softlayer / softlayer-ruby

http://softlayer.github.io/softlayer-ruby/
MIT License
54 stars 35 forks source link

The "SoftLayer_Billing_Order_Quote::verifyOrder" method fails when try to order a VSI with ruby client #74

Closed MiguelHigorre closed 7 years ago

MiguelHigorre commented 9 years ago

When trying to order a virtual server instance using the ruby client the "SoftLayer_Billing_Order_Quote::verifyOrder" method fails and raises the following exception:

"An invalid price was submitted with this order"

The exception is raised despite valid parameters are set and it is possible order using the same quote from UI and also using the php client.

To reproduce the problem use below code

require 'rubygems'

require 'softlayer_api'

require 'pp'

SL_API_USERNAME = "set-me"

SL_API_KEY = "set-me"

client = SoftLayer::Client.new( :username => "#{SL_API_USERNAME}", :api_key => "#{SL_API_KEY}")

quoteId = 1242802

order_templates = client['SoftLayer_Billing_Order_Quote'].object_with_id(quoteId).getRecalculatedOrderContainer()

order = order_templates['orderContainers'][0]

order['complexType'] = 'SoftLayer_Container_Product_Order_Virtual_Server' order['quantity'] = 1 order['location'] = '154820' order['hardware'] = [{'hostname'=> 'server01', 'domain'=> 'example.com'}]

begin receipt = client['SoftLayer_Billing_Order_Quote'].object_with_id(quoteId).verifyOrder(order) pprint.pprint(receipt) rescue => error_reason puts "The order could not be verified #{error_reason}" end

SLsthompson commented 9 years ago

OK. Let me get with the ordering guys and see if we can figure out why this might fail.

SLsthompson commented 9 years ago

Are you placing the order through Ruby using the same User account that created the quote?

MiguelHigorre commented 9 years ago

Yes, I used same account to create the quote and try to perform the order... please note that this problem happens when try to order virtual servers.. It works when bare metal server are ordered from quotes

SLsthompson commented 9 years ago

This may seem silly... but where you have:

order['hardware'] = [{'hostname'=> 'server01', 'domain'=> 'example.com'}]

Have you tried using virtualGuests in the place of hardware?

From the documentation it doesn't seem that it should matter... but I'm curious to know if it does.

MiguelHigorre commented 9 years ago

Yep, I tried with "virtualGuests" instead "hardware"... got same results.

SLsthompson commented 9 years ago

I have a strong suspicion that this may be related to Issue #49

It appears that when you get back the order template from the system, the hash contains a lot of key/value pairs which have the empty string ("") as the value. I suspect that in other contexts (like the PHP example you mentioned) those nil values are handled better.

A hardware order might not have a key that is rejected when it comes back with "" instead of nil.

I had some success with running through the order template and simply removing any key value pairs where the value was "". Unfortunately, since that is a nested structure, a more thorough "sanitizing" mechanism might be necessary in the general case.

Alternatively you might be able to get away with creating an all new order template and only filling out the fields that "make sense", copying over values from the order obtained from the quote as needed.

None of these is a satisfying solution, however. Internally will have to pursue the resolution to Issue #49

(on an unrelated note your SoftLayer_Container_Product_Order_Virtual_Server constant should probably be SoftLayer_Container_Product_Order_Virtual_Guest)

MiguelHigorre commented 9 years ago

After updating the 'SoftLayer_Container_Product_Order_Virtual_Guest' value that you mentioned.. I did not get the previous message I reported. However the order cannot be verified and the "Invalid data on the order for property: presetId. Invalid preset id: 0" exception is raised, and probably this problem is related to the issue you commented.

Anyway I think in the case to order a Virtual guest the "preset id" parameter should not be mandatory, please let me know your comments

renier commented 7 years ago

This also fails from Python and PHP. It's a problem in the SoftLayer_Billing_Order_Quote api.

You have to do it like this:

require 'softlayer_api'

# Credentials to the SoftLayer API are grabbed from the config file by default.
# See https://github.com/softlayer/softlayer-ruby/blob/master/lib/softlayer/Config.rb#L11-L44
client = SoftLayer::Client.new

QUOTE_ID = 1234

quote = client['Billing_Order_Quote'].object_with_id(QUOTE_ID)
order = quote.getRecalculatedOrderContainer['orderContainers'][0]

order['quantity'] = 1
order['virtualGuests'] = [{ 'hostname' => 'quotetest', 'domain' => 'example.com' }]
order.delete('hardware')

pp client['Product_Order'].placeOrder(order) # or verifyOrder()

The problem with not be