softlayer / softlayer-go

SoftLayer API Client for the Go Language
Apache License 2.0
53 stars 46 forks source link

Unable to reload the OS with new hard drive partition #45

Open acamacho82 opened 7 years ago

acamacho82 commented 7 years ago

Hi, I'm creating some examples in order to pass them to customers when they required, and I'm trying to reload the OS of bare metal servers with a new disk partition but I'm unable to add the partitions to the Container_Hardware_Server_Configuration object.

configuration := datatypes.Container_Hardware_Server_Configuration{
        ItemPrices : prices,
        HardDrives : hardDrives ,    // Cannot use []Hardware_Component_HardDrive type as []Hardware_Component
}

Below is the hard drive partition that I'd like to add it to the configuration above, the problem is that HardDrives is an array of Hardware_Component objects and I couldn't find a way to add Hardware_Component_HardDrive objects like in Python or REST. I tried by adding a complexType parameter or convert it to Hardware_Component but only errors are raised.

hardDrives := []datatypes.Hardware_Component_HardDrive{
        {
            Partitions: []datatypes.Hardware_Component_Partition{
                {
                    Name        : sl.String("/swap0"),
                MinimumSize : sl.Float(1),
            },              
            {
                Name        : sl.String("/"),
                MinimumSize : sl.Float(1),
                Grow        : sl.Int(1),
            },
        },
    },
}

I realize that most of supported languages for Softlayer API are based on sldn documentation, but I noticed that sldn have some issues since there are missing parameters like 'complexType' which is used in Hardware_Component (like python example below) or deprecated parameters like snapshotSpaceAvailable in Network_Storage (comment here). And due to that, this may be an issue in softlayer-go.

Please, let me know if there is something wrong with my implementation.

Examples in other languages: Following is part of a SOAP structure to reload the OS


<ns1:reloadOperatingSystem>
      <token xsi:type="xsd:string">FORCE</token>
      <config xsi:type="ns1:SoftLayer_Container_Hardware_Server_Configuration">
        <hardDrives SOAP-ENC:arrayType="ns1:SoftLayer_Hardware_Component[1]" xsi:type="ns1:SoftLayer_Hardware_ComponentArray">
          <item xsi:type="ns1:SoftLayer_Hardware_Component_HardDrive">
            <partitions SOAP-ENC:arrayType="ns1:SoftLayer_Hardware_Component_Partition[2]" xsi:type="ns1:SoftLayer_Hardware_Component_PartitionArray">              
              <item xsi:type="ns1:SoftLayer_Hardware_Component_Partition">
                <name xsi:type="xsd:string">/swap0</name>
                <minimumSize xsi:type="xsd:decimal">0.75</minimumSize>                
              </item>
              <item xsi:type="ns1:SoftLayer_Hardware_Component_Partition">                
                <name xsi:type="xsd:string">/</name>
                <minimumSize xsi:type="xsd:decimal">10</minimumSize>
                <grow xsi:type="xsd:int">1</grow>                
              </item>              
            </partitions>
          </item>
        </hardDrives>
      </config>
    </ns1:reloadOperatingSystem>

On Python and REST, the 'complexType' parameter is used to specify the Hardware_Component_HardDrive


hardDrives = [
    {
        'complexType': 'SoftLayer_Hardware_Component_HardDrive',
        'partitions': [
            {    'name': '/swap0',  'minimumSize': '1',   },                 
            {    'name': '/',       'minimumSize': '1',   'grow': '1', },
        ]
    }
]

config = {
        'itemPrices': itemPrices,
        'hardDrives': hardDrives
    }

reload = client['Hardware_Server'].reloadOperatingSystem('FORCE', config, id=serverId)

Thanks for your help.

renier commented 7 years ago

@acamacho82 This is a prickly problem. Since Go is a statically typed language where there is no inheritance, it of course doesn't have the same type flexibility like Python. At the same time, it needs to follow the specified api schema.

The fix would be tricky. We would have to throw away the HardDrives []Hardware_Component type and replace it with HardDrives []interface{}, to allow you to pass any type there. Then in any API that would get a structure containing this, we'd have to check the base type being passed in that field so that the appropriate complexType field could be added before the request is sent (it needs to be added if passing a [Hardware_Component_HardDrive type). Requires more thought.

In the mean time, you can use the session's DoRequest method which lets you pass in your payload in the raw.