由于 500 服务器错误,无法使用 SoftLayer API 和 Ansible 提供 VM

Unable to provision VMs using SoftLayer API and Ansible due to 500 Server Errors

我们正在使用 Ansible 来配置一组虚拟机。为此,我们使用此处的 softlayer.py 脚本作为 ansible 的一部分:https://github.com/ansible/ansible/blob/devel/contrib/inventory/softlayer.py

我们 运行: ansible-playbook manifest.yml -s -i softlayer.py

manifest.yml 包含一堆应该配置我们的 VM 的可靠任务。这是一个删除了所有敏感信息的示例:

- gather_facts: false
hosts: localhost
name: Build Servers
sudo: false
tasks:
- local_action: 
cpus: 4
datacenter: sjc03
dedicated: false
disks:
- 25
domain: test.example.sample.net
hostname: machine-one
hourly: false
memory: 8192
module: sl_vm
nic_speed: 1000
os_code: UBUNTU_14_64
private: true
private_vlan: 1234567
ssh_keys: []
tags:
- tagone
- tagtwo
- tagthree
- tagfour
- test.example.sample.net
name: Build machine-one server

下面是完整的错误输出,如果有用的话:

Inventory script (softlayer.py) had an execution error: Traceback (most recent call last):
File "/opt/test/job/softlayer.py", line 207, in <module>
SoftLayerInventory()
File "/opt/test/job/softlayer.py", line 84, in __init__
self.get_all_servers()
File "/opt/test/job/softlayer.py", line 204, in get_all_servers
self.get_virtual_servers()
File "/opt/test/job/softlayer.py", line 188, in get_virtual_servers
instances = vs.list_instances(mask=mask)
File "/usr/local/lib/python2.7/dist-packages/SoftLayer-4.0.3-py2.7.egg/SoftLayer/managers/vs.py", line 141, in list_instances
return func(**kwargs)
File "/usr/local/lib/python2.7/dist-packages/SoftLayer-4.0.3-py2.7.egg/SoftLayer/API.py", line 362, in call_handler
return self(name, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/SoftLayer-4.0.3-py2.7.egg/SoftLayer/API.py", line 330, in call
return self.client.call(self.name, name, *args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/SoftLayer-4.0.3-py2.7.egg/SoftLayer/API.py", line 226, in call
return self.transport(request)
File "/usr/local/lib/python2.7/dist-packages/SoftLayer-4.0.3-py2.7.egg/SoftLayer/transports.py", line 162, in __call__
raise exceptions.TransportError(ex.response.status_code, str(ex))
SoftLayer.exceptions.TransportError: TransportError(500): 500 Server Error: Internal Server Error for url: https://api.softlayer.com/xmlrpc/v3.1/SoftLayer_Account

可能是什么原因造成的?

根据异常,存在很多500错误,原因有很多:

  • 超时
  • 内存不足
  • 无效请求
  • 错误

我不确定 Ansible 如何处理和发送参数到 SoftLayer API Python Client, but a quick view, Ansible is using SoftLayer-4.0.3 and SoftLayer API Python Client 已经发布了 v5.2.0,我们建议使用它,以获得最新更新并避免可能出现的问题。

我使用 SoftLayer Python Command-line Interface 发送了您尝试过的相同参数并进行了一些测试,并且运行良好:

slcli vs create --hostname=machine-one --domain=stest.example.sample.net --cpu 4 --memory 8192 -o UBUNTU_14_64 --datacenter=sjc03 --billing=monthly --tag tagone,tagtwo,tagthree,tagfour,test.example.sample.net --public --network 1000 --private

我建议在下面提交一个问题link,以便Ansible可以验证并修复它:

https://github.com/ansible/ansible/issues

这似乎特定于在 https://api.softlayer.com/xmlrpc/v3.1/SoftLayer_Account 上调用 getVirtualGuests 使用一组特定的凭据/在一个特定的帐户上并使用一个特定的掩码。

<?xml version='1.0'?>
<methodCall>
<methodName>getVirtualGuests</methodName>
<params>
<param>
<value><struct>
<member>
<name>headers</name>
<value><struct>
<member>
<name>SoftLayer_ObjectMask</name>
<value><struct>
<member>
<name>mask</name>
<value><string>mask[id,globalIdentifier,hostname,domain,fullyQualifiedDomainName,primaryBackendIpAddress,primaryIpAddress,datacenter,tagReferences.tag.name,lastKnownPowerState.name,powerState,maxCpu,maxMemory,activeTransaction.transactionStatus[friendlyName,name],status]</string></value>
</member>
</struct></value>
</member>
<member>
<name>SoftLayer_AccountObjectFilter</name>
<value><struct>
</struct></value>
</member>
<member>
<name>authenticate</name>
<value><struct>
<member>
<name>apiKey</name>
<value><string>xxxxxxx</string></value>
</member>
<member>
<name>username</name>
<value><string>example</string></value>
</member>
</struct></value>
</member>
</struct></value>
</member>
</struct></value>
</param>
</params>
</methodCall>

将 XML 发布到上面的 xmlrpc 端点,我使用原始问题中提到的特定凭据遇到了 500 错误。如果我使用一组不同的(有效)凭据,我会按预期返回我的服务器列表。如果我提供了无效的凭据,那么我会按预期收到 "Invalid API token."。

在 500 的情况下令人惊讶的是,它似乎确实有 运行 查询(因为 SoftLayer-Total-Items: 70 在 header 中返回),但是 HTTP 代码是 500 并且响应的 body 为空。

如果我检查 slcli -vvv vs list 发出的 http 请求(成功),我发现它向同一方法发送了不同的掩码,所以可能 softlayer.py 中的掩码是相关的。