/
opt
/
imh-python
/
lib
/
python3.9
/
site-packages
/
libcloud
/
compute
/
drivers
/
/opt/imh-python/lib/python3.9/site-packages/libcloud/compute/drivers
mkdir
upload
Name
Size
Mode
Actions
__pycache__/
-
0755
rm
abiquo.py
31529
0644
edit
dl
rm
auroracompute.py
2040
0644
edit
dl
rm
azure.py
113227
0644
edit
dl
rm
azure_arm.py
83132
0644
edit
dl
rm
bluebox.py
7426
0644
edit
dl
rm
brightbox.py
10859
0644
edit
dl
rm
bsnl.py
1958
0644
edit
dl
rm
cloudscale.py
8844
0644
edit
dl
rm
cloudsigma.py
68769
0644
edit
dl
rm
cloudstack.py
163834
0644
edit
dl
rm
cloudwatt.py
5094
0644
edit
dl
rm
digitalocean.py
27064
0644
edit
dl
rm
dimensiondata.py
189557
0644
edit
dl
rm
dummy.py
11074
0644
edit
dl
rm
ec2.py
219386
0644
edit
dl
rm
ecp.py
11723
0644
edit
dl
rm
ecs.py
63818
0644
edit
dl
rm
elastichosts.py
7441
0644
edit
dl
rm
elasticstack.py
16348
0644
edit
dl
rm
exoscale.py
1159
0644
edit
dl
rm
gandi.py
26305
0644
edit
dl
rm
gce.py
389086
0644
edit
dl
rm
gig_g8.py
22013
0644
edit
dl
rm
gogrid.py
15250
0644
edit
dl
rm
gridscale.py
35381
0644
edit
dl
rm
gridspot.py
4243
0644
edit
dl
rm
hostvirtual.py
14427
0644
edit
dl
rm
ikoula.py
1172
0644
edit
dl
rm
indosat.py
1997
0644
edit
dl
rm
internetsolutions.py
2050
0644
edit
dl
rm
joyent.py
8213
0644
edit
dl
rm
kamatera.py
23481
0644
edit
dl
rm
kili.py
3199
0644
edit
dl
rm
ktucloud.py
3595
0644
edit
dl
rm
kubevirt.py
40678
0644
edit
dl
rm
libvirt_driver.py
14671
0644
edit
dl
rm
linode.py
26646
0644
edit
dl
rm
maxihost.py
8419
0644
edit
dl
rm
medone.py
1984
0644
edit
dl
rm
nephoscale.py
17690
0644
edit
dl
rm
ntta.py
2011
0644
edit
dl
rm
nttcis.py
222933
0644
edit
dl
rm
onapp.py
16503
0644
edit
dl
rm
oneandone.py
57758
0644
edit
dl
rm
opennebula.py
43343
0644
edit
dl
rm
openstack.py
144008
0644
edit
dl
rm
ovh.py
18845
0644
edit
dl
rm
packet.py
33684
0644
edit
dl
rm
profitbricks.py
120806
0644
edit
dl
rm
rackspace.py
9442
0644
edit
dl
rm
rimuhosting.py
12292
0644
edit
dl
rm
scaleway.py
24231
0644
edit
dl
rm
serverlove.py
2934
0644
edit
dl
rm
skalicloud.py
2917
0644
edit
dl
rm
softlayer.py
17921
0644
edit
dl
rm
upcloud.py
11156
0644
edit
dl
rm
vcl.py
8843
0644
edit
dl
rm
vcloud.py
94722
0644
edit
dl
rm
voxel.py
10927
0644
edit
dl
rm
vpsnet.py
6721
0644
edit
dl
rm
vsphere.py
18407
0644
edit
dl
rm
vultr.py
13328
0644
edit
dl
rm
__init__.py
1207
0644
edit
dl
rm
Edit:
/opt/imh-python/lib/python3.9/site-packages/libcloud/compute/drivers/linode.py
(26646B)
# Licensed to the Apache Software Foundation (ASF) under one or more # contributor license agreements. See the NOTICE file distributed with # this work for additional information regarding copyright ownership. # The ASF licenses this file to You under the Apache License, Version 2.0 # (the "License"); you may not use this file except in compliance with # the License. You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """libcloud driver for the Linode(R) API This driver implements all libcloud functionality for the Linode API. Since the API is a bit more fine-grained, create_node abstracts a significant amount of work (and may take a while to run). Linode home page http://www.linode.com/ Linode API documentation http://www.linode.com/api/ Alternate bindings for reference http://github.com/tjfontaine/linode-python Linode(R) is a registered trademark of Linode, LLC. """ import os try: import simplejson as json except ImportError: import json import itertools import binascii from copy import copy from libcloud.utils.py3 import PY3 from libcloud.common.linode import (API_ROOT, LinodeException, LinodeConnection, LINODE_PLAN_IDS, LINODE_DISK_FILESYSTEMS) from libcloud.compute.types import Provider, NodeState from libcloud.compute.base import NodeDriver, NodeSize, Node, NodeLocation from libcloud.compute.base import NodeAuthPassword, NodeAuthSSHKey from libcloud.compute.base import NodeImage, StorageVolume class LinodeNodeDriver(NodeDriver): """libcloud driver for the Linode API Rough mapping of which is which: - list_nodes linode.list - reboot_node linode.reboot - destroy_node linode.delete - create_node linode.create, linode.update, linode.disk.createfromdistribution, linode.disk.create, linode.config.create, linode.ip.addprivate, linode.boot - list_sizes avail.linodeplans - list_images avail.distributions - list_locations avail.datacenters - list_volumes linode.disk.list - destroy_volume linode.disk.delete For more information on the Linode API, be sure to read the reference: http://www.linode.com/api/ """ type = Provider.LINODE name = "Linode" website = 'http://www.linode.com/' connectionCls = LinodeConnection _linode_plan_ids = LINODE_PLAN_IDS _linode_disk_filesystems = LINODE_DISK_FILESYSTEMS features = {'create_node': ['ssh_key', 'password']} def __init__(self, key): """Instantiate the driver with the given API key :param key: the API key to use (required) :type key: ``str`` :rtype: ``None`` """ self.datacenter = None NodeDriver.__init__(self, key) # Converts Linode's state from DB to a NodeState constant. LINODE_STATES = { (-2): NodeState.UNKNOWN, # Boot Failed (-1): NodeState.PENDING, # Being Created 0: NodeState.PENDING, # Brand New 1: NodeState.RUNNING, # Running 2: NodeState.STOPPED, # Powered Off 3: NodeState.REBOOTING, # Shutting Down 4: NodeState.UNKNOWN # Reserved } def list_nodes(self): """ List all Linodes that the API key can access This call will return all Linodes that the API key in use has access to. If a node is in this list, rebooting will work; however, creation and destruction are a separate grant. :return: List of node objects that the API key can access :rtype: ``list`` of :class:`Node` """ params = {"api_action": "linode.list"} data = self.connection.request(API_ROOT, params=params).objects[0] return self._to_nodes(data) def start_node(self, node): """ Boot the given Linode """ params = {"api_action": "linode.boot", "LinodeID": node.id} self.connection.request(API_ROOT, params=params) return True def stop_node(self, node): """ Shutdown the given Linode """ params = {"api_action": "linode.shutdown", "LinodeID": node.id} self.connection.request(API_ROOT, params=params) return True def reboot_node(self, node): """ Reboot the given Linode Will issue a shutdown job followed by a boot job, using the last booted configuration. In most cases, this will be the only configuration. :param node: the Linode to reboot :type node: :class:`Node` :rtype: ``bool`` """ params = {"api_action": "linode.reboot", "LinodeID": node.id} self.connection.request(API_ROOT, params=params) return True def destroy_node(self, node): """Destroy the given Linode Will remove the Linode from the account and issue a prorated credit. A grant for removing Linodes from the account is required, otherwise this method will fail. In most cases, all disk images must be removed from a Linode before the Linode can be removed; however, this call explicitly skips those safeguards. There is no going back from this method. :param node: the Linode to destroy :type node: :class:`Node` :rtype: ``bool`` """ params = {"api_action": "linode.delete", "LinodeID": node.id, "skipChecks": True} self.connection.request(API_ROOT, params=params) return True def create_node(self, name, image, size, auth, location=None, ex_swap=None, ex_rsize=None, ex_kernel=None, ex_payment=None, ex_comment=None, ex_private=False, lconfig=None, lroot=None, lswap=None): """Create a new Linode, deploy a Linux distribution, and boot This call abstracts much of the functionality of provisioning a Linode and getting it booted. A global grant to add Linodes to the account is required, as this call will result in a billing charge. Note that there is a safety valve of 5 Linodes per hour, in order to prevent a runaway script from ruining your day. :keyword name: the name to assign the Linode (mandatory) :type name: ``str`` :keyword image: which distribution to deploy on the Linode (mandatory) :type image: :class:`NodeImage` :keyword size: the plan size to create (mandatory) :type size: :class:`NodeSize` :keyword auth: an SSH key or root password (mandatory) :type auth: :class:`NodeAuthSSHKey` or :class:`NodeAuthPassword` :keyword location: which datacenter to create the Linode in :type location: :class:`NodeLocation` :keyword ex_swap: size of the swap partition in MB (128) :type ex_swap: ``int`` :keyword ex_rsize: size of the root partition in MB (plan size - swap). :type ex_rsize: ``int`` :keyword ex_kernel: a kernel ID from avail.kernels (Latest 2.6 Stable). :type ex_kernel: ``str`` :keyword ex_payment: one of 1, 12, or 24; subscription length (1) :type ex_payment: ``int`` :keyword ex_comment: a small comment for the configuration (libcloud) :type ex_comment: ``str`` :keyword ex_private: whether or not to request a private IP (False) :type ex_private: ``bool`` :keyword lconfig: what to call the configuration (generated) :type lconfig: ``str`` :keyword lroot: what to call the root image (generated) :type lroot: ``str`` :keyword lswap: what to call the swap space (generated) :type lswap: ``str`` :return: Node representing the newly-created Linode :rtype: :class:`Node` """ auth = self._get_and_check_auth(auth) # Pick a location (resolves LIBCLOUD-41 in JIRA) if location: chosen = location.id elif self.datacenter: chosen = self.datacenter else: raise LinodeException(0xFB, "Need to select a datacenter first") # Step 0: Parameter validation before we purchase # We're especially careful here so we don't fail after purchase, rather # than getting halfway through the process and having the API fail. # Plan ID plans = self.list_sizes() if size.id not in [p.id for p in plans]: raise LinodeException(0xFB, "Invalid plan ID -- avail.plans") # Payment schedule payment = "1" if not ex_payment else str(ex_payment) if payment not in ["1", "12", "24"]: raise LinodeException(0xFB, "Invalid subscription (1, 12, 24)") ssh = None root = None # SSH key and/or root password if isinstance(auth, NodeAuthSSHKey): ssh = auth.pubkey # pylint: disable=no-member elif isinstance(auth, NodeAuthPassword): root = auth.password if not ssh and not root: raise LinodeException(0xFB, "Need SSH key or root password") if root is not None and len(root) < 6: raise LinodeException(0xFB, "Root password is too short") # Swap size try: swap = 128 if not ex_swap else int(ex_swap) except Exception: raise LinodeException(0xFB, "Need an integer swap size") # Root partition size imagesize = (size.disk - swap) if not ex_rsize else\ int(ex_rsize) if (imagesize + swap) > size.disk: raise LinodeException(0xFB, "Total disk images are too big") # Distribution ID distros = self.list_images() if image.id not in [d.id for d in distros]: raise LinodeException(0xFB, "Invalid distro -- avail.distributions") # Kernel if ex_kernel: kernel = ex_kernel else: if image.extra['64bit']: # For a list of available kernel ids, see # https://www.linode.com/kernels/ kernel = 138 else: kernel = 137 params = {"api_action": "avail.kernels"} kernels = self.connection.request(API_ROOT, params=params).objects[0] if kernel not in [z["KERNELID"] for z in kernels]: raise LinodeException(0xFB, "Invalid kernel -- avail.kernels") # Comments comments = "Created by Apache libcloud <https://www.libcloud.org>" if\ not ex_comment else ex_comment # Step 1: linode.create params = { "api_action": "linode.create", "DatacenterID": chosen, "PlanID": size.id, "PaymentTerm": payment } data = self.connection.request(API_ROOT, params=params).objects[0] linode = {"id": data["LinodeID"]} # Step 1b. linode.update to rename the Linode params = { "api_action": "linode.update", "LinodeID": linode["id"], "Label": name } self.connection.request(API_ROOT, params=params) # Step 1c. linode.ip.addprivate if it was requested if ex_private: params = { "api_action": "linode.ip.addprivate", "LinodeID": linode["id"] } self.connection.request(API_ROOT, params=params) # Step 1d. Labels # use the linode id as the name can be up to 63 chars and the labels # are limited to 48 chars label = { "lconfig": "[%s] Configuration Profile" % linode["id"], "lroot": "[%s] %s Disk Image" % (linode["id"], image.name), "lswap": "[%s] Swap Space" % linode["id"] } if lconfig: label['lconfig'] = lconfig if lroot: label['lroot'] = lroot if lswap: label['lswap'] = lswap # Step 2: linode.disk.createfromdistribution if not root: root = binascii.b2a_base64(os.urandom(8)).decode('ascii').strip() params = { "api_action": "linode.disk.createfromdistribution", "LinodeID": linode["id"], "DistributionID": image.id, "Label": label["lroot"], "Size": imagesize, "rootPass": root, } if ssh: params["rootSSHKey"] = ssh data = self.connection.request(API_ROOT, params=params).objects[0] linode["rootimage"] = data["DiskID"] # Step 3: linode.disk.create for swap params = { "api_action": "linode.disk.create", "LinodeID": linode["id"], "Label": label["lswap"], "Type": "swap", "Size": swap } data = self.connection.request(API_ROOT, params=params).objects[0] linode["swapimage"] = data["DiskID"] # Step 4: linode.config.create for main profile disks = "%s,%s,,,,,,," % (linode["rootimage"], linode["swapimage"]) params = { "api_action": "linode.config.create", "LinodeID": linode["id"], "KernelID": kernel, "Label": label["lconfig"], "Comments": comments, "DiskList": disks } if ex_private: params['helper_network'] = True params['helper_distro'] = True data = self.connection.request(API_ROOT, params=params).objects[0] linode["config"] = data["ConfigID"] # Step 5: linode.boot params = { "api_action": "linode.boot", "LinodeID": linode["id"], "ConfigID": linode["config"] } self.connection.request(API_ROOT, params=params) # Make a node out of it and hand it back params = {"api_action": "linode.list", "LinodeID": linode["id"]} data = self.connection.request(API_ROOT, params=params).objects[0] nodes = self._to_nodes(data) if len(nodes) == 1: node = nodes[0] if getattr(auth, "generated", False): node.extra['password'] = auth.password return node return None def ex_resize_node(self, node, size): """Resizes a Linode from one plan to another Immediately shuts the Linode down, charges/credits the account, and issue a migration to another host server. Requires a size (numeric), which is the desired PlanID available from avail.LinodePlans() After resize is complete the node needs to be booted """ params = {"api_action": "linode.resize", "LinodeID": node.id, "PlanID": size} self.connection.request(API_ROOT, params=params) return True def ex_start_node(self, node): # NOTE: This method is here for backward compatibility reasons after # this method was promoted to be part of the standard compute API in # Libcloud v2.7.0 return self.start_node(node=node) def ex_stop_node(self, node): # NOTE: This method is here for backward compatibility reasons after # this method was promoted to be part of the standard compute API in # Libcloud v2.7.0 return self.stop_node(node=node) def ex_rename_node(self, node, name): """Renames a node""" params = { "api_action": "linode.update", "LinodeID": node.id, "Label": name } self.connection.request(API_ROOT, params=params) return True def list_sizes(self, location=None): """ List available Linode plans Gets the sizes that can be used for creating a Linode. Since available Linode plans vary per-location, this method can also be passed a location to filter the availability. :keyword location: the facility to retrieve plans in :type location: :class:`NodeLocation` :rtype: ``list`` of :class:`NodeSize` """ params = {"api_action": "avail.linodeplans"} data = self.connection.request(API_ROOT, params=params).objects[0] sizes = [] for obj in data: n = NodeSize(id=obj["PLANID"], name=obj["LABEL"], ram=obj["RAM"], disk=(obj["DISK"] * 1024), bandwidth=obj["XFER"], price=obj["PRICE"], driver=self.connection.driver) sizes.append(n) return sizes def list_images(self): """ List available Linux distributions Retrieve all Linux distributions that can be deployed to a Linode. :rtype: ``list`` of :class:`NodeImage` """ params = {"api_action": "avail.distributions"} data = self.connection.request(API_ROOT, params=params).objects[0] distros = [] for obj in data: i = NodeImage(id=obj["DISTRIBUTIONID"], name=obj["LABEL"], driver=self.connection.driver, extra={'pvops': obj['REQUIRESPVOPSKERNEL'], '64bit': obj['IS64BIT']}) distros.append(i) return distros def list_locations(self): """ List available facilities for deployment Retrieve all facilities that a Linode can be deployed in. :rtype: ``list`` of :class:`NodeLocation` """ params = {"api_action": "avail.datacenters"} data = self.connection.request(API_ROOT, params=params).objects[0] nl = [] for dc in data: country = None if "USA" in dc["LOCATION"]: country = "US" elif "UK" in dc["LOCATION"]: country = "GB" elif "JP" in dc["LOCATION"]: country = "JP" else: country = "??" nl.append(NodeLocation(dc["DATACENTERID"], dc["LOCATION"], country, self)) return nl def linode_set_datacenter(self, dc): """ Set the default datacenter for Linode creation Since Linodes must be created in a facility, this function sets the default that :class:`create_node` will use. If a location keyword is not passed to :class:`create_node`, this method must have already been used. :keyword dc: the datacenter to create Linodes in unless specified :type dc: :class:`NodeLocation` :rtype: ``bool`` """ did = dc.id params = {"api_action": "avail.datacenters"} data = self.connection.request(API_ROOT, params=params).objects[0] for datacenter in data: if did == dc["DATACENTERID"]: self.datacenter = did return dcs = ", ".join([d["DATACENTERID"] for d in data]) self.datacenter = None raise LinodeException(0xFD, "Invalid datacenter (use one of %s)" % dcs) def destroy_volume(self, volume): """ Destroys disk volume for the Linode. Linode id is to be provided as extra["LinodeId"] whithin :class:`StorageVolume`. It can be retrieved by :meth:`libcloud.compute.drivers.linode.LinodeNodeDriver\ .ex_list_volumes`. :param volume: Volume to be destroyed :type volume: :class:`StorageVolume` :rtype: ``bool`` """ if not isinstance(volume, StorageVolume): raise LinodeException(0xFD, "Invalid volume instance") if volume.extra["LINODEID"] is None: raise LinodeException(0xFD, "Missing LinodeID") params = { "api_action": "linode.disk.delete", "LinodeID": volume.extra["LINODEID"], "DiskID": volume.id, } self.connection.request(API_ROOT, params=params) return True def ex_create_volume(self, size, name, node, fs_type): """ Create disk for the Linode. :keyword size: Size of volume in megabytes (required) :type size: ``int`` :keyword name: Name of the volume to be created :type name: ``str`` :keyword node: Node to attach volume to. :type node: :class:`Node` :keyword fs_type: The formatted type of this disk. Valid types are: ext3, ext4, swap, raw :type fs_type: ``str`` :return: StorageVolume representing the newly-created volume :rtype: :class:`StorageVolume` """ # check node if not isinstance(node, Node): raise LinodeException(0xFD, "Invalid node instance") # check space available total_space = node.extra['TOTALHD'] existing_volumes = self.ex_list_volumes(node) used_space = 0 for volume in existing_volumes: used_space = used_space + volume.size available_space = total_space - used_space if available_space < size: raise LinodeException(0xFD, "Volume size too big. Available space\ %d" % available_space) # check filesystem type if fs_type not in self._linode_disk_filesystems: raise LinodeException(0xFD, "Not valid filesystem type") params = { "api_action": "linode.disk.create", "LinodeID": node.id, "Label": name, "Type": fs_type, "Size": size } data = self.connection.request(API_ROOT, params=params).objects[0] volume = data["DiskID"] # Make a volume out of it and hand it back params = { "api_action": "linode.disk.list", "LinodeID": node.id, "DiskID": volume } data = self.connection.request(API_ROOT, params=params).objects[0] return self._to_volumes(data)[0] def ex_list_volumes(self, node, disk_id=None): """ List existing disk volumes for for given Linode. :keyword node: Node to list disk volumes for. (required) :type node: :class:`Node` :keyword disk_id: Id for specific disk volume. (optional) :type disk_id: ``int`` :rtype: ``list`` of :class:`StorageVolume` """ if not isinstance(node, Node): raise LinodeException(0xFD, "Invalid node instance") params = { "api_action": "linode.disk.list", "LinodeID": node.id } # Add param if disk_id was specified if disk_id is not None: params["DiskID"] = disk_id data = self.connection.request(API_ROOT, params=params).objects[0] return self._to_volumes(data) def _to_volumes(self, objs): """ Covert returned JSON volumes into StorageVolume instances :keyword objs: ``list`` of JSON dictionaries representing the StorageVolumes :type objs: ``list`` :return: ``list`` of :class:`StorageVolume`s """ volumes = {} for o in objs: vid = o["DISKID"] volumes[vid] = vol = StorageVolume(id=vid, name=o["LABEL"], size=int(o["SIZE"]), driver=self.connection.driver) vol.extra = copy(o) return list(volumes.values()) def _to_nodes(self, objs): """Convert returned JSON Linodes into Node instances :keyword objs: ``list`` of JSON dictionaries representing the Linodes :type objs: ``list`` :return: ``list`` of :class:`Node`s""" # Get the IP addresses for the Linodes nodes = {} batch = [] for o in objs: lid = o["LINODEID"] nodes[lid] = n = Node(id=lid, name=o["LABEL"], public_ips=[], private_ips=[], state=self.LINODE_STATES[o["STATUS"]], driver=self.connection.driver) n.extra = copy(o) n.extra["PLANID"] = self._linode_plan_ids.get(o.get("TOTALRAM")) batch.append({"api_action": "linode.ip.list", "LinodeID": lid}) # Avoid batch limitation ip_answers = [] args = [iter(batch)] * 25 if PY3: izip_longest = itertools.zip_longest # pylint: disable=no-member else: izip_longest = getattr(itertools, 'izip_longest', _izip_longest) for twenty_five in izip_longest(*args): twenty_five = [q for q in twenty_five if q] params = {"api_action": "batch", "api_requestArray": json.dumps(twenty_five)} req = self.connection.request(API_ROOT, params=params) if not req.success() or len(req.objects) == 0: return None ip_answers.extend(req.objects) # Add the returned IPs to the nodes and return them for ip_list in ip_answers: for ip in ip_list: lid = ip["LINODEID"] which = nodes[lid].public_ips if ip["ISPUBLIC"] == 1 else\ nodes[lid].private_ips which.append(ip["IPADDRESS"]) return list(nodes.values()) def _izip_longest(*args, **kwds): """Taken from Python docs http://docs.python.org/library/itertools.html#itertools.izip """ fillvalue = kwds.get('fillvalue') def sentinel(counter=([fillvalue] * (len(args) - 1)).pop): yield counter() # yields the fillvalue, or raises IndexError fillers = itertools.repeat(fillvalue) iters = [itertools.chain(it, sentinel(), fillers) for it in args] try: for tup in itertools.izip(*iters): # pylint: disable=no-member yield tup except IndexError: pass
Save
cmd:
run