PageRenderTime 43ms CodeModel.GetById 17ms RepoModel.GetById 1ms app.codeStats 0ms

/cges/pymodules/python2.7/lib/python/apache_libcloud-0.15.1-py2.7.egg/libcloud/compute/drivers/softlayer.py

https://gitlab.com/pooja043/Globus_Docker_2
Python | 474 lines | 391 code | 50 blank | 33 comment | 16 complexity | c66b58049a1717e8ef891acfafe36730 MD5 | raw file
  1. # Licensed to the Apache Software Foundation (ASF) under one or more
  2. # contributor license agreements. See the NOTICE file distributed with
  3. # this work for additional information regarding copyright ownership.
  4. # The ASF licenses this file to You under the Apache License, Version 2.0
  5. # (the "License"); you may not use this file except in compliance with
  6. # the License. You may obtain a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS,
  12. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. # See the License for the specific language governing permissions and
  14. # limitations under the License.
  15. """
  16. Softlayer driver
  17. """
  18. import time
  19. from libcloud.common.base import ConnectionUserAndKey
  20. from libcloud.common.xmlrpc import XMLRPCResponse, XMLRPCConnection
  21. from libcloud.common.types import InvalidCredsError, LibcloudError
  22. from libcloud.compute.types import Provider, NodeState
  23. from libcloud.compute.base import NodeDriver, Node, NodeLocation, NodeSize, \
  24. NodeImage
  25. DEFAULT_DOMAIN = 'example.com'
  26. DEFAULT_CPU_SIZE = 1
  27. DEFAULT_RAM_SIZE = 2048
  28. DEFAULT_DISK_SIZE = 100
  29. DATACENTERS = {
  30. 'hou02': {'country': 'US'},
  31. 'sea01': {'country': 'US', 'name': 'Seattle - West Coast U.S.'},
  32. 'wdc01': {'country': 'US', 'name': 'Washington, DC - East Coast U.S.'},
  33. 'dal01': {'country': 'US'},
  34. 'dal02': {'country': 'US'},
  35. 'dal04': {'country': 'US'},
  36. 'dal05': {'country': 'US', 'name': 'Dallas - Central U.S.'},
  37. 'dal06': {'country': 'US'},
  38. 'dal07': {'country': 'US'},
  39. 'sjc01': {'country': 'US', 'name': 'San Jose - West Coast U.S.'},
  40. 'sng01': {'country': 'SG', 'name': 'Singapore - Southeast Asia'},
  41. 'ams01': {'country': 'NL', 'name': 'Amsterdam - Western Europe'},
  42. }
  43. NODE_STATE_MAP = {
  44. 'RUNNING': NodeState.RUNNING,
  45. 'HALTED': NodeState.UNKNOWN,
  46. 'PAUSED': NodeState.UNKNOWN,
  47. 'INITIATING': NodeState.PENDING
  48. }
  49. SL_BASE_TEMPLATES = [
  50. {
  51. 'name': '1 CPU, 1GB ram, 25GB',
  52. 'ram': 1024,
  53. 'disk': 25,
  54. 'cpus': 1,
  55. }, {
  56. 'name': '1 CPU, 1GB ram, 100GB',
  57. 'ram': 1024,
  58. 'disk': 100,
  59. 'cpus': 1,
  60. }, {
  61. 'name': '1 CPU, 2GB ram, 100GB',
  62. 'ram': 2 * 1024,
  63. 'disk': 100,
  64. 'cpus': 1,
  65. }, {
  66. 'name': '1 CPU, 4GB ram, 100GB',
  67. 'ram': 4 * 1024,
  68. 'disk': 100,
  69. 'cpus': 1,
  70. }, {
  71. 'name': '2 CPU, 2GB ram, 100GB',
  72. 'ram': 2 * 1024,
  73. 'disk': 100,
  74. 'cpus': 2,
  75. }, {
  76. 'name': '2 CPU, 4GB ram, 100GB',
  77. 'ram': 4 * 1024,
  78. 'disk': 100,
  79. 'cpus': 2,
  80. }, {
  81. 'name': '2 CPU, 8GB ram, 100GB',
  82. 'ram': 8 * 1024,
  83. 'disk': 100,
  84. 'cpus': 2,
  85. }, {
  86. 'name': '4 CPU, 4GB ram, 100GB',
  87. 'ram': 4 * 1024,
  88. 'disk': 100,
  89. 'cpus': 4,
  90. }, {
  91. 'name': '4 CPU, 8GB ram, 100GB',
  92. 'ram': 8 * 1024,
  93. 'disk': 100,
  94. 'cpus': 4,
  95. }, {
  96. 'name': '6 CPU, 4GB ram, 100GB',
  97. 'ram': 4 * 1024,
  98. 'disk': 100,
  99. 'cpus': 6,
  100. }, {
  101. 'name': '6 CPU, 8GB ram, 100GB',
  102. 'ram': 8 * 1024,
  103. 'disk': 100,
  104. 'cpus': 6,
  105. }, {
  106. 'name': '8 CPU, 8GB ram, 100GB',
  107. 'ram': 8 * 1024,
  108. 'disk': 100,
  109. 'cpus': 8,
  110. }, {
  111. 'name': '8 CPU, 16GB ram, 100GB',
  112. 'ram': 16 * 1024,
  113. 'disk': 100,
  114. 'cpus': 8,
  115. }]
  116. SL_TEMPLATES = {}
  117. for i, template in enumerate(SL_BASE_TEMPLATES):
  118. # Add local disk templates
  119. local = template.copy()
  120. local['local_disk'] = True
  121. SL_TEMPLATES[i] = local
  122. class SoftLayerException(LibcloudError):
  123. """
  124. Exception class for SoftLayer driver
  125. """
  126. pass
  127. class SoftLayerResponse(XMLRPCResponse):
  128. defaultExceptionCls = SoftLayerException
  129. exceptions = {
  130. 'SoftLayer_Account': InvalidCredsError,
  131. }
  132. class SoftLayerConnection(XMLRPCConnection, ConnectionUserAndKey):
  133. responseCls = SoftLayerResponse
  134. host = 'api.softlayer.com'
  135. endpoint = '/xmlrpc/v3'
  136. def request(self, service, method, *args, **kwargs):
  137. headers = {}
  138. headers.update(self._get_auth_headers())
  139. headers.update(self._get_init_params(service, kwargs.get('id')))
  140. headers.update(
  141. self._get_object_mask(service, kwargs.get('object_mask')))
  142. headers.update(
  143. self._get_object_mask(service, kwargs.get('object_mask')))
  144. args = ({'headers': headers}, ) + args
  145. endpoint = '%s/%s' % (self.endpoint, service)
  146. return super(SoftLayerConnection, self).request(method, *args,
  147. **{'endpoint':
  148. endpoint})
  149. def _get_auth_headers(self):
  150. return {
  151. 'authenticate': {
  152. 'username': self.user_id,
  153. 'apiKey': self.key
  154. }
  155. }
  156. def _get_init_params(self, service, id):
  157. if id is not None:
  158. return {
  159. '%sInitParameters' % service: {'id': id}
  160. }
  161. else:
  162. return {}
  163. def _get_object_mask(self, service, mask):
  164. if mask is not None:
  165. return {
  166. '%sObjectMask' % service: {'mask': mask}
  167. }
  168. else:
  169. return {}
  170. class SoftLayerNodeDriver(NodeDriver):
  171. """
  172. SoftLayer node driver
  173. Extra node attributes:
  174. - password: root password
  175. - hourlyRecurringFee: hourly price (if applicable)
  176. - recurringFee : flat rate (if applicable)
  177. - recurringMonths : The number of months in which the recurringFee
  178. will be incurred.
  179. """
  180. connectionCls = SoftLayerConnection
  181. name = 'SoftLayer'
  182. website = 'http://www.softlayer.com/'
  183. type = Provider.SOFTLAYER
  184. features = {'create_node': ['generates_password']}
  185. def _to_node(self, host):
  186. try:
  187. password = \
  188. host['operatingSystem']['passwords'][0]['password']
  189. except (IndexError, KeyError):
  190. password = None
  191. hourlyRecurringFee = host.get('billingItem', {}).get(
  192. 'hourlyRecurringFee', 0)
  193. recurringFee = host.get('billingItem', {}).get('recurringFee', 0)
  194. recurringMonths = host.get('billingItem', {}).get('recurringMonths', 0)
  195. createDate = host.get('createDate', None)
  196. # When machine is launching it gets state halted
  197. # we change this to pending
  198. state = NODE_STATE_MAP.get(host['powerState']['keyName'],
  199. NodeState.UNKNOWN)
  200. if not password and state == NodeState.UNKNOWN:
  201. state = NODE_STATE_MAP['INITIATING']
  202. public_ips = []
  203. private_ips = []
  204. if 'primaryIpAddress' in host:
  205. public_ips.append(host['primaryIpAddress'])
  206. if 'primaryBackendIpAddress' in host:
  207. private_ips.append(host['primaryBackendIpAddress'])
  208. image = host.get('operatingSystem', {}).get('softwareLicense', {}) \
  209. .get('softwareDescription', {}) \
  210. .get('longDescription', None)
  211. return Node(
  212. id=host['id'],
  213. name=host['fullyQualifiedDomainName'],
  214. state=state,
  215. public_ips=public_ips,
  216. private_ips=private_ips,
  217. driver=self,
  218. extra={
  219. 'hostname': host['hostname'],
  220. 'fullyQualifiedDomainName': host['fullyQualifiedDomainName'],
  221. 'password': password,
  222. 'maxCpu': host.get('maxCpu', None),
  223. 'datacenter': host.get('datacenter', {}).get('longName', None),
  224. 'maxMemory': host.get('maxMemory', None),
  225. 'image': image,
  226. 'hourlyRecurringFee': hourlyRecurringFee,
  227. 'recurringFee': recurringFee,
  228. 'recurringMonths': recurringMonths,
  229. 'created': createDate,
  230. }
  231. )
  232. def destroy_node(self, node):
  233. self.connection.request(
  234. 'SoftLayer_Virtual_Guest', 'deleteObject', id=node.id
  235. )
  236. return True
  237. def reboot_node(self, node):
  238. self.connection.request(
  239. 'SoftLayer_Virtual_Guest', 'rebootSoft', id=node.id
  240. )
  241. return True
  242. def ex_stop_node(self, node):
  243. self.connection.request(
  244. 'SoftLayer_Virtual_Guest', 'powerOff', id=node.id
  245. )
  246. return True
  247. def ex_start_node(self, node):
  248. self.connection.request(
  249. 'SoftLayer_Virtual_Guest', 'powerOn', id=node.id
  250. )
  251. return True
  252. def _get_order_information(self, node_id, timeout=1200, check_interval=5):
  253. mask = {
  254. 'billingItem': '',
  255. 'powerState': '',
  256. 'operatingSystem': {'passwords': ''},
  257. 'provisionDate': '',
  258. }
  259. for i in range(0, timeout, check_interval):
  260. res = self.connection.request(
  261. 'SoftLayer_Virtual_Guest',
  262. 'getObject',
  263. id=node_id,
  264. object_mask=mask
  265. ).object
  266. if res.get('provisionDate', None):
  267. return res
  268. time.sleep(check_interval)
  269. raise SoftLayerException('Timeout on getting node details')
  270. def create_node(self, **kwargs):
  271. """Create a new SoftLayer node
  272. @inherits: :class:`NodeDriver.create_node`
  273. :keyword ex_domain: e.g. libcloud.org
  274. :type ex_domain: ``str``
  275. :keyword ex_cpus: e.g. 2
  276. :type ex_cpus: ``int``
  277. :keyword ex_disk: e.g. 100
  278. :type ex_disk: ``int``
  279. :keyword ex_ram: e.g. 2048
  280. :type ex_ram: ``int``
  281. :keyword ex_bandwidth: e.g. 100
  282. :type ex_bandwidth: ``int``
  283. :keyword ex_local_disk: e.g. True
  284. :type ex_local_disk: ``bool``
  285. :keyword ex_datacenter: e.g. Dal05
  286. :type ex_datacenter: ``str``
  287. :keyword ex_os: e.g. UBUNTU_LATEST
  288. :type ex_os: ``str``
  289. """
  290. name = kwargs['name']
  291. os = 'DEBIAN_LATEST'
  292. if 'ex_os' in kwargs:
  293. os = kwargs['ex_os']
  294. elif 'image' in kwargs:
  295. os = kwargs['image'].id
  296. size = kwargs.get('size', NodeSize(id=123, name='Custom', ram=None,
  297. disk=None, bandwidth=None,
  298. price=None,
  299. driver=self.connection.driver))
  300. ex_size_data = SL_TEMPLATES.get(int(size.id)) or {}
  301. # plan keys are ints
  302. cpu_count = kwargs.get('ex_cpus') or ex_size_data.get('cpus') or \
  303. DEFAULT_CPU_SIZE
  304. ram = kwargs.get('ex_ram') or ex_size_data.get('ram') or \
  305. DEFAULT_RAM_SIZE
  306. bandwidth = kwargs.get('ex_bandwidth') or size.bandwidth or 10
  307. hourly = 'true' if kwargs.get('ex_hourly', True) else 'false'
  308. local_disk = 'true'
  309. if ex_size_data.get('local_disk') is False:
  310. local_disk = 'false'
  311. if kwargs.get('ex_local_disk') is False:
  312. local_disk = 'false'
  313. disk_size = DEFAULT_DISK_SIZE
  314. if size.disk:
  315. disk_size = size.disk
  316. if kwargs.get('ex_disk'):
  317. disk_size = kwargs.get('ex_disk')
  318. datacenter = ''
  319. if 'ex_datacenter' in kwargs:
  320. datacenter = kwargs['ex_datacenter']
  321. elif 'location' in kwargs:
  322. datacenter = kwargs['location'].id
  323. domain = kwargs.get('ex_domain')
  324. if domain is None:
  325. if name.find('.') != -1:
  326. domain = name[name.find('.') + 1:]
  327. if domain is None:
  328. # TODO: domain is a required argument for the Sofylayer API, but it
  329. # it shouldn't be.
  330. domain = DEFAULT_DOMAIN
  331. newCCI = {
  332. 'hostname': name,
  333. 'domain': domain,
  334. 'startCpus': cpu_count,
  335. 'maxMemory': ram,
  336. 'networkComponents': [{'maxSpeed': bandwidth}],
  337. 'hourlyBillingFlag': hourly,
  338. 'operatingSystemReferenceCode': os,
  339. 'localDiskFlag': local_disk,
  340. 'blockDevices': [
  341. {
  342. 'device': '0',
  343. 'diskImage': {
  344. 'capacity': disk_size,
  345. }
  346. }
  347. ]
  348. }
  349. if datacenter:
  350. newCCI['datacenter'] = {'name': datacenter}
  351. res = self.connection.request(
  352. 'SoftLayer_Virtual_Guest', 'createObject', newCCI
  353. ).object
  354. node_id = res['id']
  355. raw_node = self._get_order_information(node_id)
  356. return self._to_node(raw_node)
  357. def _to_image(self, img):
  358. return NodeImage(
  359. id=img['template']['operatingSystemReferenceCode'],
  360. name=img['itemPrice']['item']['description'],
  361. driver=self.connection.driver
  362. )
  363. def list_images(self, location=None):
  364. result = self.connection.request(
  365. 'SoftLayer_Virtual_Guest', 'getCreateObjectOptions'
  366. ).object
  367. return [self._to_image(i) for i in result['operatingSystems']]
  368. def _to_size(self, id, size):
  369. return NodeSize(
  370. id=id,
  371. name=size['name'],
  372. ram=size['ram'],
  373. disk=size['disk'],
  374. bandwidth=size.get('bandwidth'),
  375. price=None,
  376. driver=self.connection.driver,
  377. )
  378. def list_sizes(self, location=None):
  379. return [self._to_size(id, s) for id, s in SL_TEMPLATES.items()]
  380. def _to_loc(self, loc):
  381. country = 'UNKNOWN'
  382. loc_id = loc['template']['datacenter']['name']
  383. name = loc_id
  384. if loc_id in DATACENTERS:
  385. country = DATACENTERS[loc_id]['country']
  386. name = DATACENTERS[loc_id].get('name', loc_id)
  387. return NodeLocation(id=loc_id, name=name,
  388. country=country, driver=self)
  389. def list_locations(self):
  390. res = self.connection.request(
  391. 'SoftLayer_Virtual_Guest', 'getCreateObjectOptions'
  392. ).object
  393. return [self._to_loc(l) for l in res['datacenters']]
  394. def list_nodes(self):
  395. mask = {
  396. 'virtualGuests': {
  397. 'powerState': '',
  398. 'hostname': '',
  399. 'maxMemory': '',
  400. 'datacenter': '',
  401. 'operatingSystem': {'passwords': ''},
  402. 'billingItem': '',
  403. },
  404. }
  405. res = self.connection.request(
  406. "SoftLayer_Account",
  407. "getVirtualGuests",
  408. object_mask=mask
  409. ).object
  410. return [self._to_node(h) for h in res]