0

I want to order an hourly Bare Metal, using Softlayer java API. I took the idea from https://gist.github.com/bmpotter/fe2de7f8028d73ada4e5. Here are my steps:

    Hardware hardware = new Hardware();
    Order orderTemplate = new Order();

    // 1. Set hostname, domain to hardware
    // 2. set Preset 
    Preset preset = new Preset();
    preset.setKeyName("S1270_8GB_2X1TBSATA_NORAID");
    hardware.setFixedConfigurationPreset(preset);
    // 3. Component setMaxSpeed, and added to hardware
    hardware.setPrimaryNetworkComponent()
    // 4. "UBUNTU_14_64"
    hardware.setOperatingSystemReferenceCode()

    // 1. Added Quantity to orderTemplate
    // 2. Added location to orderTemplate
    // 3. Added Hardware to orderTemplate
    // 4. Added Container, since I am see the exception
    orderTemplate.setContainerIdentifier("SoftLayer_Product_Package_Preset");

    Finally tried to verify the Order.

I keep getting a generic error message:

Invalid container specified: SoftLayer_Container_Product_Order. Ordering a server or service requires a specific container type, not the generic base order container.

What am I doing wrong? Do I need to send priceIds, similar to non hourly Bare Metal Order? Is there a troubleshooting guide to know what is missing in my order?

Pedro David Fuentes Can you please help? I tried this, after figuring out the prices:

https://[username]:[apikey]@api.softlayer.com/rest/v3/SoftLayer_Product_Order/verifyOrder

{
   "parameters": [
   {
     "complexType": "SoftLayer_Container_Product_Order_Hardware_Server",
     "quantity": 1,
     "location": "DALLAS",
     "packageId": 200,
     "useHourlyPricing": 1,
     "presetId": 66,
     "prices": [
     {
        "id": 37318
     }, 
     {
        "id": 34183
     }, 
     {
        "id": 26737
     }, 
     {
        "id": 34807
     }, 
     {
        "id": 25014
     }
  ],
  "hardware": [
    {
      "hostname": "myhostname",
      "domain": "mydomain.com"
    }
   ]
  }
 ]
}
{ 
    "error": "Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).", 
    "code": "SoftLayer_Exception_Public" 
}

Also reproducible via JAVA code, hence tried via REST too.

Modified code with extra logging:

String username = "xxxxx";
String apiKey = "xxxxx";

Location datacenter = new Location();
datacenter.setName("seo01");

Preset preset = new Preset();
preset.setKeyName("S1270_8GB_2X1TBSATA_NORAID");

Component networkComponent = new Component();
networkComponent.setMaxSpeed(100L);

Hardware hardware = new Hardware();
hardware.setDatacenter(datacenter);
hardware.setHostname("xxxxx_xxxxx_BM_HOURLY");
hardware.setDomain("xxxx.xxx");
hardware.setHourlyBillingFlag(true);
hardware.setFixedConfigurationPreset(preset);
List<Component> networkComponents = hardware.getNetworkComponents();
networkComponents.add(networkComponent);
hardware.setOperatingSystemReferenceCode("CENTOS_LATEST");

ApiClient client = new RestApiClient().withCredentials(username, apiKey).withLoggingEnabled();
Hardware.Service hardwareService = Hardware.service(client); 
try
{  
  Gson gson = new Gson();
  Hardware hardwarePlaced = hardwareService.createObject(hardware);
  System.out.println("createObject: " + gson.toJson(hardwarePlaced));
}
catch(Exception e)
{
    System.out.println("Error: " + e);  
}

I get an error: Running POST on link with body: {"parameters":[{"complexType":"SoftLayer_Hardware","hostname":"xxxxx_xxxxx_BM_HOURLY","domain":"xxxx.xxx","fixedConfigurationPreset":{"complexType":"SoftLayer_Product_Package_Preset","keyName":"S1270_8GB_2X1TBSATA_NORAID"},"datacenter":{"complexType":"SoftLayer_Location","name":"seo01"},"hourlyBillingFlag":true,"networkComponents":[{"complexType":"SoftLayer_Network_Component","maxSpeed":100}],"operatingSystemReferenceCode":"CENTOS_LATEST"}]} Got 500 on link with body: {"error":"Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).","code":"SoftLayer_Exception_Public"} Error: com.softlayer.api.ApiException$Internal: Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).(code: SoftLayer_Exception_Public, status: 500)

CSN
  • 9
  • 3

2 Answers2

0

you could try this script.

package SoftLayer_Java_Scripts.Examples;
import java.util.ArrayList;
import java.util.List;
import com.softlayer.api.*;
import com.softlayer.api.service.container.product.order.hardware.Server;
import com.softlayer.api.service.Hardware;
import com.softlayer.api.service.product.Order;
import com.softlayer.api.service.product.item.Price;
import com.google.gson.Gson;

/**
* Order a new server with preset configuration.
* 
 * The presets used to simplify ordering by eliminating the need
* for price ids when submitting orders.
* Also when the order contains a preset id, it is not possible
* to configure VLANs in the order.
* 
 * Important manual pages:
* http://sldn.softlayer.com/reference/services/SoftLayer_Product_Order/verifyOrder
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Container_Product_Order_Network_Message_Queue
* http://sldn.softlayer.com/reference/datatypes/SoftLayer_Virtual_Guest
* 
 * @license <http://sldn.softlayer.com/article/License>
* @author SoftLayer Technologies, Inc. <sldn@softlayer.com>
* @version 1.0
*/
public class OrderPreSetBMS
{
  public static void main( String[] args )
  {
    // Your SoftLayer API username and key.
       String user = "set me";
       String apiKey = "set me";

       long quantity = 1;
       String location = "AMSTERDAM";
       long packageId = 200;
       long presetId = 64;
       String hostname = "test";
       String domain = "example.org";

       // Building a skeleton SoftLayer_Hardware_Server object to model the hostname and
       // domain we want for our server. If you set quantity greater then 1 then you
       // need to define one hostname/domain pair per server you wish to order.
       Hardware hardware = new Hardware();
       hardware.setHostname(hostname);
       hardware.setDomain(domain);

    // Building a skeleton SoftLayer_Product_Item_Price objects. These objects contain
    // much more than ids, but SoftLayer's ordering system only needs the price's id
    // to know what you want to order.
    // Every item in SoftLayer's product catalog is assigned an id. Use these ids
    // to tell the SoftLayer API which options you want in your new server. Use
    // the getActivePackages() method in the SoftLayer_Account API service to get
       // a list of available item and price options per available package.
       // Note: The presets already have some preconfigured items, such as
       // the server or the disks you do not need to configure the prices for those
       // items.
       //
       // Id: 44988 -> CentOS 7.x (64 bit)
    // Id: 1800  -> 0 GB Bandwidth
    // Id: 273   -> 100 Mbps Public & Private Network Uplinks
    // Id: 420   -> Unlimited SSL VPN Users & 1 PPTP VPN User per account
    // Id: 21    -> 1 IP Address
    // Id: 906   -> Reboot / KVM over IP        
    long[] priceIds = {44988, 1800, 273, 420, 21, 906};
    List<Price> prices = new ArrayList<Price>();
    for (int i = 0; i < priceIds.length; i++) {
      Price p = new Price();
      p.setId(priceIds[i]);
      prices.add(p);
    }

    // Building a skeleton SoftLayer_Container_Product_Order_Hardware_Server object
    // containing the order you wish to place.
       Server server = new Server();
       server.setQuantity(quantity);
       server.setLocation(location);
       server.setPackageId(packageId);

    List<Price> priceList = server.getPrices();
    priceList.addAll(prices);

       List<Hardware> hardwareList = server.getHardware();
       hardwareList.add(hardware);
       server.setPresetId(presetId);

       // Creating a SoftLayer API client and service objects. 
       ApiClient client = new RestApiClient().withCredentials(user, apiKey);
       Order.Service service = Order.service(client);

       try
       {
      // verifyOrder() will check your order for errors. Replace this with a call
      // to placeOrder() when you're ready to order. Both calls return a receipt
       // object that you can use for your records.
       // Once your order is placed it'll go through SoftLayer's approval and
       // provisioning process. When it's done you'll have a new
       // SoftLayer_Hardware_Server object and server ready to use.
       com.softlayer.api.service.container.product.Order verifiedOrder = service.verifyOrder(server);
         Gson gson = new Gson();
         System.out.println(gson.toJson(verifiedOrder));
       }
       catch(Exception e)
       {
              System.out.println("Error: " + e); 
       }
  }
}

The next REST request retrieves the Product Item Prices for a package Id. Is important to notice how these prices are organized and what information they contain. For example, these product item prices might have the same item id, this is because the prices are separated by location.

 https://$username:$apiKey@api.softlayer.com/rest/v3/SoftLayer_Product_Package/200/getItemPrices.json?objectMask=mask[id,pricingLocationGroup[locations[name]],item[id,description],categories[categoryCode]]

The next Request uses an object filter and Host Ping and TCP Service Monitoring as the search criteria. With this example, one can realize that Product Item Prices can have the same Item Id meaning that they are the same, but should be used according to the specific location where the order is being verified.

 https://$username:$apiKey@api.softlayer.com/rest/v3/SoftLayer_Product_Package/200/getItemPrices.json?objectMask=mask[id,pricingLocationGroup[locations[name]],item[id,description],categories[categoryCode]]&objectFilter={"itemPrices":{"item":{"description":{"operation":"Host Ping and TCP Service Monitoring"}}}} 

For further reading:

https://sldn.softlayer.com/article/object-masks

https://sldn.softlayer.com/article/object-filters

  • Thanks for your sample code. When I set packageId as 200 and list out the prices for Bandwidth, I get the following: 1)1000 GB Bandwidth, priceId : 50233 2)Unlimited Bandwidth (100 Mbps Uplink), priceId : 24745 3)5000 GB Bandwidth, priceId : 50243 4)500 GB Bandwidth, priceId : 50359 5)0 GB Bandwidth, priceId : 35963 6)20000 GB Bandwidth, priceId : 50263 7)10000 GB Bandwidth, priceId : 50253 8)0 GB Bandwidth, priceId : 34183 None of the above lists 1800 bandwidth. Is it expected to use hardcoded values, for ex for 0GB BW? Hardcoded values can change from time to time, hence asking. – CSN Sep 08 '16 at 19:14
  • Similarly, there is no priceId 420 for PackageId: 200 1)Desc :100 Mbps Private Network Uplink, priceId: 23787 2)Desc :10 Mbps Public & Private Network Uplinks, priceId: 22829 3)Desc :1 Gbps Private Network Uplink, priceId: 23777 4)Desc :1 Gbps Public & Private Network Uplinks, priceId: 24713 5)Desc :100 Mbps Public & Private Network Uplinks, matches(): true priceId: 26737 6)Desc :10 Mbps Private Network Uplink, priceId: 27052 7)Desc :1 Gbps Public & Private Network Uplinks (Unbonded), priceId: 37220 8)Desc :10 Gbps Dual Public & Private Network Uplinks (Unbonded), priceId: 40200 – CSN Sep 08 '16 at 19:24
  • David Do you support Redhat linux for hourly BM? I get the following exception when I am using the above code: com.softlayer.api.ApiException$Internal: Price # 44988 does not exist.(code: SoftLayer_Exception_Public, status: 500) – CSN Sep 08 '16 at 22:19
  • This link might help you to understand how and why some item prices have different ids. https://sldn.softlayer.com/blog/cmporter/location-based-pricing-and-you – Pedro David Fuentes Antezana Sep 09 '16 at 17:03
  • Can you check out my updated question? I still can't make it work. – CSN Sep 09 '16 at 23:58
  • I will look at the docs. What I was asking was I am getting this error "error": "Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).", http://stackoverflow.com/questions/39003084/gpu-related-api-errors-for-softlayer-hourly-bare-metal-server-creation, you mentioned it is resolved. I see this error again. – CSN Sep 12 '16 at 16:04
  • The reason why you are seeing differents prices than the example is because Pedro and you have different accounts, softlayer has diferents types of accounts and each one of them have diferent prices, so do not expect that the same prices ID will work for you, you need to call the getItems method to get the prices which will work for you, and of course you do not have to use hardcode prices because they can change (your code always must query the prices prior to make the order). – Nelson Raul Cabero Mendoza Sep 13 '16 at 01:10
  • Now keep in mind that not all prices (or configurations) will work for presets (the best way to verify this is seeing if you can order it via the Portal) for example you cannot set VLANs for presets, I am not sure about "Unable to add a Graphics Processing Unit" but please verify it using the portal. – Nelson Raul Cabero Mendoza Sep 13 '16 at 01:13
  • That is the drawback to use preset, basically you only can configure the basic stuff such as OS or Bandwidth (like in Pedro´s example) if you need to configure more stuff the best option for you is not to use preset. – Nelson Raul Cabero Mendoza Sep 13 '16 at 01:26
  • The presets were desing to fast provisioning, and it is better to use the http://sldn.softlayer.com/reference/services/SoftLayer_Hardware_Server/createObject method to order them, and you can see the valid options using the http://sldn.softlayer.com/reference/services/SoftLayer_Hardware_Server/getCreateObjectOptions method, I will try to send you an examle using java – Nelson Raul Cabero Mendoza Sep 13 '16 at 01:56
  • Even if we use Bare Metals for a couple of days and delete them, we are charged monthly. So, we were recommended by SL team to use hourly BMs. Any example in java is greatly appreciated. I am getting "Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200)." when I try to verify an order using https://[username]:[apikey]@api.softlayer.com/rest/v3/SoftLayer_Product_Order/verifyOrder too. – CSN Sep 13 '16 at 16:11
0

This documentation about order BM servers can help you http://sldn.softlayer.com/blog/bpotter/ordering-bare-metal-servers-using-softlayer-api

Here an exmaple to order presets:

import java.util.List;
import com.softlayer.api.*;
import com.softlayer.api.service.Hardware;
import com.softlayer.api.service.Location;
import com.softlayer.api.service.network.Component;
import com.softlayer.api.service.product.Order;
import com.softlayer.api.service.product.pkg.Preset;
import com.google.gson.Gson;

public class OrderPreSetBMS2
{
  public static void main( String[] args )
  {
    String user = "set me";
    String apiKey = "set me";

    Location datacenter = new Location();
    datacenter.setName("seo01");

    Preset preset = new Preset();
    preset.setKeyName("S1270_8GB_2X1TBSATA_NORAID");

    Component networkComponent = new Component();
    networkComponent.setMaxSpeed(100L);


    Hardware hardware = new Hardware();
    hardware.setDatacenter(datacenter);
    hardware.setHostname("simplebmi");
    hardware.setDomain("test.com");
    hardware.setHourlyBillingFlag(true);
    hardware.setFixedConfigurationPreset(preset);
    List<Component> networkComponents = hardware.getNetworkComponents();
    networkComponents.add(networkComponent);
    hardware.setOperatingSystemReferenceCode("UBUNTU_14_64");

    ApiClient client = new RestApiClient().withCredentials(user, apiKey);
    Hardware.Service hardwareService = Hardware.service(client); 
    Order.Service orderService = Order.service(client); 

    try
    {
      //Change generateOrderTemplate method by createObject when you are ready to order the server. 
      com.softlayer.api.service.container.product.Order productOrder = hardwareService.generateOrderTemplate(hardware);
      Gson gson = new Gson();
      System.out.println(gson.toJson(productOrder));
    }
    catch(Exception e)
    {
        System.out.println("Error: " + e);  
    }
  }
}
  • Thanks so much @Nelson Raul Cabero Mendoza. I exactly ran your program and tried to verify the order, using productOrder: com.softlayer.api.service.container.product.Order verifyOrder = com.softlayer.api.service.product.Order.service(client).verifyOrder(productOrder); I get the same exception: Error: com.softlayer.api.ApiException$Internal: Unable to add a Graphics Processing Unit price (178119) because it is not valid for the package (200).(code: SoftLayer_Exception_Public, status: 500). What does this exception mean? – CSN Sep 13 '16 at 19:02
  • that is the easy way to order BM servers, but you only can configure some stuff. If you wish to configure more stuff you need to use placeOrder method and not to use presets – Nelson Raul Cabero Mendoza Sep 13 '16 at 19:05
  • Nelson - @Nelson Raul Cabero Mendoza I see the same exception again, I was editing while you commented. – CSN Sep 13 '16 at 19:07
  • Do not verify the order, It seems that generateOrderTemplate method is not creating the right order template, if you want to order the server use the createObject method. – Nelson Raul Cabero Mendoza Sep 13 '16 at 19:17
  • please if you are using the java client, enable it to log the request like this "ApiClient client = new RestApiClient().withCredentials(user, apiKey).withLoggingEnabled();" it will log the restful request that it is doing please post that. – Nelson Raul Cabero Mendoza Sep 13 '16 at 20:06
  • I can order succefully the preset 66 and it verifies properly the order. – Nelson Raul Cabero Mendoza Sep 13 '16 at 20:08
  • also verify that you can order the preset via portal https://manage.softlayer.com/Store/orderHourlyBareMetalInstance/37278/66 – Nelson Raul Cabero Mendoza Sep 13 '16 at 20:09
  • I could not add the link: link = https://api.softlayer.com/rest/v3.1/SoftLayer_Hardware.json. @Nelson Raul Cabero Mendoza, can we chat somewhere? On Softlayer Portal or email? I modified the question with the code and error message. I could not add the link in the question. – CSN Sep 13 '16 at 20:41
  • I will review it and let you know as soon as I can, but it seems an issue with your account and in that case the best option is to submit a ticket. – Nelson Raul Cabero Mendoza Sep 13 '16 at 20:57
  • Yep it is an issue with your account, someone of softlayer sales must review your account, submit a ticket in the softlayer control portal for further help. – Nelson Raul Cabero Mendoza Sep 13 '16 at 22:13
  • Yes, I have already opened a Softlayer ticket. Error has been misleading. Thanks for all your help. – CSN Sep 13 '16 at 22:16