How to use what I see in Object Walker?


#1

Hi All, still new to MIQ. Been using Objectwalker and wondering how to translate the information back to automate code? Perhaps an example is easiet to show what I mean. The below indicates that there is a hash/array with the data I am after. I tried a few things:

data_centre = @handle.options(:dialog)
data_centre = @handle.options(:dialog_data_center)
data_centre = @handle.options[0]
data_centre = @handle.get_option(:dialog_data_center)

All pretty much erroring with the following result:
NoMethodError: undefined method `options’ for #MiqAeMethodService::MiqAeService:0x00000014763798

In this case I want to modify the vmname method, I am assuming what objectwalker dumps should be available for use there?

[----] I, [2017-05-13T21:15:49.851724 #12786:b2a479c] INFO – : Q-task_id([service_template_provision_request_51000000000253]) object_walker#29CD2B2A:[3] miq_
provision_request.options[:dialog] = {“dialog_job_template”=>“Db_MY”, “dialog_data_centre”=>“IMC3”, “dialog_itsm_env”=>“Development”, “dialog_datazone”=>“No”, “dialog_dmzzone”=>“No”, “
dialog_baas”=>“No”, “dialog_monitor”=>“No”, “dialog_envname”=>“Non-Prod”, “dialog_ip_addr”=>“10.213.148.230”, “dialog_vm_pre”=>"", “dialog_size_of_disks”=>"", “dialog_vm_size”=>“Small”
, “dialog_number_of_vms”=>""} (type: Hash)

Thanks


#2

Made some progress

data_centre = provision_object.get_option(:dialog_data_centre) “works”. No value in the variable thought… how to manage a hash type?


#3

Hi

I’m not sure if you’ve tried it, but the object_walker output is much easier to view using the object_walker_reader.rb script (https://github.com/pemcg/object_walker/blob/master/object_walker_reader.rb).

In your example the value of the options hash :dialog key is itself a hash, so you need to extract the value from the options hash, and then access your key, i.e.

data_centre = provision_object.get_option(:dialog)['dialog_data_centre']

Hope this helps,
pemcg


#4

Hi Pete,

Yes I did indeed get object_walker_reader going, awesome tool. Thanks for all resources and time!

Though I would take it back a bit and just try and retrieve a simple string option (cart_order), no error but its nil/empty…

Script extract:
@handle.log(“info”, “Detected vmdb_object_type:<#{@handle.root[‘vmdb_object_type’]}>”)

data_centre = provision_object.get_option(:cart_state)
@handle.log("info", "Detected #{data_centre}")

Auto log (2’nd Detected log entry empty):
[----] I, [2017-05-14T08:54:08.295486 #28494:ac5ecc] INFO – : Q-task_id([service_template_provision_request_51000000000274]) Detected vmdb_object_type:<miq_provision>
[----] I, [2017-05-14T08:54:08.301443 #28494:ac5ecc] INFO – : Q-task_id([service_template_provision_request_51000000000274]) Detected
[----] E, [2017-05-14T08:54:08.303188 #28494:ac5ecc] ERROR – : Q-task_id([service_template_provision_request_51000000000274]) The following error occurred during met
hod evaluation:
[----] E, [2017-05-14T08:54:08.304809 #28494:ac5ecc] ERROR – : Q-task_id([service_template_provision_request_51000000000274]) NoMethodError: undefined method spli t' for nil:NilClass [----] E, [2017-05-14T08:54:08.305594 #28494:ac5ecc] ERROR -- : Q-task_id([service_template_provision_request_51000000000274]) <AEMethod vmname> <code: a = app.split('_')>:24:inmain’
[----] E, [2017-05-14T08:54:08.309457 #28494:ac5ecc] ERROR – : Q-task_id([service_template_provision_request_51000000000274]) Method STDERR: <code: a = app.split(’_’)>:24:in main': u ndefined methodsplit’ for nil:NilClass (NoMethodError)

Object reader:
| | | | — attributes follow —
| | | | miq_request_task.created_on = 2017-05-13 13:15:44 UTC (type: ActiveSupport::TimeWithZone)
| | | | miq_request_task.description = Provisioning [Redhat Services] for Service [Redhat Services] (type: String)
| | | | miq_request_task.destination_id = nil
| | | | miq_request_task.destination_type = nil
| | | | miq_request_task.id = 51000000000638 (type: Fixnum)
| | | | miq_request_task.message = Service_Template_Provisioning - Request Created (type: String)
| | | | miq_request_task.miq_request_id = 51000000000253 (type: Fixnum)
| | | | miq_request_task.miq_request_task_id = nil
| | | | miq_request_task.options[:cart_state] = ordered (type: String)
| | | | miq_request_task.options[:delivered_on] = 2017-05-13 13:15:44 UTC (type: Time)
| | | | miq_request_task.options[:dialog] = {“dialog_job_template”=>“Db_MY”, “dialog_data_centre”=>“IMC3”, “dialog_itsm_env”=>“Development”, “dialog_datazone”=>“No”, “dialog_dmzzone”=>“No”, “dialog_baas”=>“No”, “dialog_monitor”=>“No”, “dialog_envname”=>“Non-Prod”, “dialog_ip_addr”=>“10.213.148.230”, “dialog_vm_pre”=>"", “dialog_size_of_disks”=>"", “dialog_vm_size”=>“Small”, “dialog_number_of_vms”=>""} (type: Hash)
| | | | miq_request_task.options[:pass] = 0 (type: Fixnum)


#5

vmnaming_pemg.rb (1.9 KB)

Switching to the attached vmname better logs what I am seeing. vm_name comes from the predefined “VM Name”. vm_prefix is set by a custom method and displayed in the service catalog via a dynamic dialog. The model defined default vm_prefix is also there/correct.

What I was hoping is that by setting the dynamically generated service catalog element to vm_prefix, I would end up with a custom servername and n{3} appened. But the dynamically generated vm_prefix isn’t making it to the vmname method. I then checked objectwalker and saw hashes that contained the options I want to use to generate the custom servername (essentially move my custon dynamic method code to vmname method). But I am unable to access the hash(es)…

From log:
[----] I, [2017-05-14T14:51:21.104854 #2057:acfad0] INFO – : Q-task_id([service_template_provision_request_51000000000282]) vm_name from dialog:<“changeme”> vm_prefix from dialog:<""> vm_prefix from model:<“HKG_”>
[----] I, [2017-05-14T14:51:21.106743 #2057:acfad0] INFO – : Q-task_id([service_template_provision_request_51000000000282]) Provisioning Object Tags: {}
[----] I, [2017-05-14T14:51:21.107525 #2057:acfad0] INFO – : Q-task_id([service_template_provision_request_51000000000282]) VM Naming Prefix: <HKG_>
[----] I, [2017-05-14T14:51:21.109525 #2057:acfad0] INFO – : Q-task_id([service_template_provision_request_51000000000282]) VM Name: <HKG_$n{3}>

In a nutshell how do I access elements from the service catalog in the / mydomain / Infrastructure / VM / Provisioning / Naming / vmname method?

An example from the object_reader and the options I am after…

 |    |    |    |    miq_request_task.options[:dialog] = {"dialog_job_template"=>"", "dialog_data_centre"=>"IMC3", "dialog_itsm_env"=>"Development", "dialog_datazone"=>"No", "dialog_dmzzone"=>"No", "dialog_baas"=>"No", "dialog_monitor"=>"No", "dialog_envname"=>"Non-Prod", "dialog_ip_addr"=>"10.213.148.230", "dialog_vm_prefix"=>"HKG_X3L5", "dialog_size_of_disks"=>"", "dialog_vm_size"=>"Small", "dialog_number_of_vms"=>""}   (type: Hash)

Thanks


#6

Unfortunately the problem that you’re seeing frustrates many people, and is due to the fact that the VM naming method is run from the group profile, before the service provision state machine runs (which runs in task context). The upshot is that the dialog variables read by CatalogItemInitialization aren’t available for naming.

I’ve heard some talk about moving naming into the VM provision state machine, but I’m not sure whether an issue or BZ/RFE has been created yet. @gmccullough might know more?

pemcg


#7

Being one of the frustrated people, I create a state in the VMProvision_VM
state machine to set the VM name. This way, I have more information at hand.


#8

Thanks @pemcg & @fdupont . I suspected as much, as per 2.19.6. Provisioning Profiles and the VM Name Passes described here. Great to get confirmation… phew, can become a bit of a rabbit hole quickly :wink: Is Pass1 where default (vmname) method gets called and Pass2 is where the CatalogItemInitialization magic happens?

Anyway, if my understanding is correct. I need to move my custom name generation code to somewhere in/after CatalogItemInitialization? Probably /Service/Provisioning/StateMachines/Methods/CatalogItemInitialization method should work, since DialogParser and Child propagation is done here? “def set_vm_name”, “def set_all_vm_name_attrs”, “def pass_dialog_values_to_provision_task”, etc look like steps I don’t want to miss.

I have to say the experience so far has reduced my confidence in being able to work with options and elements from service catalogs. I am hoping at this stage, CatalogItemInitialization, the Request options are available and include the service catalog elements. If not, is VMProvision_VM better?

What I need to achieve is generate a custom server name prefix, based on user inputs from a service catalog. Then I want the automate engine just to add n{3} ensuring uniqueness. I had this going but it only works if provisioning one server at a time… I think the “easy” bit is the custom server name prefix code and it could go to CatalogItemInitialization or VMProvision_VM, its more about getting the automate engine to manage the n{3} in such a way that its unique/incremental per custom server name prefix.


#9

Having a code block, as per below. Will mean there is a good likelihood two users request the same server type and the second one fails, because the first hasn’t been populated to the vmdb…

for i in (1…999)
vm_name = “#{srv_prefix}#{i.to_s.rjust(3, “0”)}".upcase
break if $evm.vmdb(‘vm_or_template’).find_by_name(vm_name).blank?
end


#10

Here is the BZ opened to address this issue:

https://bugzilla.redhat.com/show_bug.cgi?id=1442225
[RFE]: Support unique vm naming from automate when provisioning service with multiple VMs


#11

Thanks @gmccullough @itewk @pemcg @fdupont


#12

@dan Let me know if you need any help implementing the work around I posted on the RFE.


#13

I ended up embedding Ian’s code (as per BZ) in CatalogInitialzationItem. Thanks All.


Request from Provisioning Dialog or Service catalog?