| # 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. |
| """ |
| 1&1 Cloud Server Compute driver |
| """ |
| import json |
| from time import sleep |
| |
| from libcloud.utils.py3 import httplib |
| from libcloud.common.base import JsonResponse, ConnectionKey |
| from libcloud.common.types import InvalidCredsError |
| from libcloud.compute.base import ( |
| Node, |
| NodeSize, |
| NodeImage, |
| NodeDriver, |
| NodeLocation, |
| NodeAuthSSHKey, |
| NodeAuthPassword, |
| ) |
| from libcloud.compute.types import NodeState |
| from libcloud.compute.providers import Provider |
| |
| API_HOST = "cloudpanel-api.1and1.com" |
| API_VERSION = "/v1/" |
| |
| __all__ = [ |
| "API_HOST", |
| "API_VERSION", |
| "OneAndOneResponse", |
| "OneAndOneConnection", |
| "OneAndOneNodeDriver", |
| ] |
| |
| |
| class OneAndOneResponse(JsonResponse): |
| """ |
| OneAndOne response parsing. |
| """ |
| |
| valid_response_codes = [httplib.OK, httplib.CREATED, httplib.ACCEPTED] |
| |
| def parse_error(self): |
| |
| if self.status == httplib.UNAUTHORIZED: |
| body = self.parse_body() |
| raise InvalidCredsError(body["message"]) |
| else: |
| body = self.parse_body() |
| if "message" in body: |
| error = "{} (code: {})".format(body["message"], self.status) |
| else: |
| error = body |
| return error |
| |
| def success(self): |
| return self.status in self.valid_response_codes |
| |
| |
| class OneAndOneConnection(ConnectionKey): |
| """ |
| Connection class for the 1&1 driver |
| """ |
| |
| host = API_HOST |
| api_prefix = API_VERSION |
| responseCls = OneAndOneResponse |
| |
| def encode_data(self, data): |
| return json.dumps(data) |
| |
| def add_default_headers(self, headers): |
| """ |
| Add headers that are necessary for every request |
| |
| This method adds ``token`` and ``Content-Type`` to the request. |
| """ |
| headers["X-Token"] = self.key |
| headers["Content-Type"] = "application/json" |
| return headers |
| |
| def request(self, action, params=None, data=None, headers=None, method="GET", raw=False): |
| """ |
| Some requests will use the href attribute directly. |
| If this is not the case, then we should formulate the |
| url based on the action specified. |
| If we are using a full url, we need to remove the |
| host and protocol components. |
| """ |
| action = self.api_prefix + action.lstrip("/") |
| |
| return super().request( |
| action=action, |
| params=params, |
| data=data, |
| headers=headers, |
| method=method, |
| raw=raw, |
| ) |
| |
| |
| class OneAndOneNodeDriver(NodeDriver): |
| """ |
| Base OneAndOne node driver. |
| """ |
| |
| connectionCls = OneAndOneConnection |
| name = "1and1" |
| website = "http://www.1and1.com" |
| type = Provider.ONEANDONE |
| |
| NODE_STATE_MAP = { |
| "POWERING_ON": NodeState.STARTING, |
| "POWERING_OFF": NodeState.PENDING, |
| "POWERED_OFF": NodeState.STOPPING, |
| "POWERED_ON": NodeState.RUNNING, |
| "REBOOTING": NodeState.REBOOTING, |
| "CONFIGURING": NodeState.RECONFIGURING, |
| "REMOVING": NodeState.UNKNOWN, |
| "DEPLOYING": NodeState.STARTING, |
| } |
| |
| """ |
| Core Functions |
| """ |
| |
| def list_sizes(self): |
| """ |
| Lists all sizes |
| |
| :return: A list of all configurable node sizes. |
| :rtype: ``list`` of :class:`NodeSize` |
| """ |
| sizes = [] |
| |
| fixed_instances = self._list_fixed_instances() |
| for value in fixed_instances: |
| node_size = self._to_node_size(value) |
| sizes.append(node_size) |
| |
| return sizes |
| |
| def list_locations(self): |
| """ |
| Lists all locations |
| |
| :return: ``list`` of :class:`NodeLocation` |
| :rtype: ``list`` |
| """ |
| datacenters = self.ex_list_datacenters() |
| locations = [] |
| for values in datacenters: |
| node_size = self._to_location(values) |
| locations.append(node_size) |
| |
| return locations |
| |
| def list_images(self, image_type=None): |
| """ |
| :return: ``list`` of :class: `NodeImage` |
| :rtype: ``list`` |
| """ |
| response = self.connection.request(action="server_appliances", method="GET") |
| |
| return self._to_images(response.object, image_type) |
| |
| def get_image(self, image_id): |
| response = self.connection.request(action="server_appliances/%s" % image_id, method="GET") |
| return self._to_image(response.object) |
| |
| """ |
| Node functions |
| """ |
| |
| def create_node( |
| self, |
| name, |
| image, |
| ex_fixed_instance_size_id, |
| location=None, |
| auth=None, |
| ex_ip=None, |
| ex_monitoring_policy_id=None, |
| ex_firewall_policy_id=None, |
| ex_loadbalancer_id=None, |
| ex_description=None, |
| ex_power_on=None, |
| ): |
| """ |
| Creates a node. |
| |
| :param name: The name of the new node |
| :type name: `str` |
| |
| :param ex_fixed_instance_size_id: |
| Fixed instance size ID from list_sizes |
| :type ex_fixed_instance_size_id: ``str`` |
| |
| :param location: 1&1 Data center Location |
| :type location: `NodeLocation` |
| |
| :param ex_ip: IP address |
| :type ex_ip: `str` |
| |
| :param ex_ssh_key: SSH Key |
| :type ex_ssh_key: `str` |
| |
| :param password: Password |
| :type password: `str` |
| |
| :param ex_monitoring_policy_id: |
| :type ex_firewall_policy_id: `str` |
| |
| :param ex_firewall_policy_id: |
| :type ex_firewall_policy_id: `str` |
| |
| :param ex_loadbalancer_id: |
| :type ex_loadbalancer_id: `str` |
| |
| :param ex_description: |
| :type ex_description: `str` |
| |
| :param ex_power_on: |
| :type ex_power_on: `bool` |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class:`Node` |
| """ |
| |
| body = { |
| "name": name, |
| "appliance_id": image.id, |
| "hardware": {"fixed_instance_size_id": ex_fixed_instance_size_id}, |
| } |
| |
| if location is not None: |
| body["datacenter_id"] = location.id |
| if ex_power_on is not None: |
| body["power_on"] = ex_power_on |
| |
| if ex_description is not None: |
| body["description"] = ex_description |
| |
| if ex_firewall_policy_id is not None: |
| body["firewall_policy_id"] = ex_firewall_policy_id |
| |
| if ex_monitoring_policy_id is not None: |
| body["monitoring_policy_id"] = ex_monitoring_policy_id |
| |
| if ex_loadbalancer_id is not None: |
| body["loadbalancer_id"] = ex_loadbalancer_id |
| |
| if auth is not None: |
| if isinstance(auth, NodeAuthPassword): |
| body["password"] = auth.password |
| elif isinstance(auth, NodeAuthSSHKey): |
| body["rsa_key"] = auth.pubkey |
| if ex_ip is not None: |
| body["ip_id"] = ex_ip |
| |
| response = self.connection.request( |
| action="servers", |
| data=body, |
| method="POST", |
| ) |
| |
| return self._to_node(response.object) |
| |
| def list_nodes(self): |
| """ |
| List all nodes. |
| |
| :return: ``list`` of :class:`Node` |
| :rtype: ``list`` |
| """ |
| response = self.connection.request(action="servers", method="GET") |
| |
| return self._to_nodes(response.object) |
| |
| def destroy_node(self, node, ex_keep_ips=False): |
| """ |
| Destroys a node. |
| |
| :param node: The node you wish to destroy. |
| :type volume: :class:`Node` |
| |
| :param ex_keep_ips: True to keep all IP addresses assigned to the node |
| :type ex_keep_ips: : ``bool`` |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| self.ex_shutdown_server(node.id) |
| |
| self._wait_for_state(node.id, "POWERED_OFF") |
| |
| response = self.connection.request( |
| action="servers/%s" % node.id, |
| params={"keep_ips": ex_keep_ips}, |
| method="DELETE", |
| ) |
| |
| return self._to_node(response.object) |
| |
| def reboot_node(self, node): |
| """ |
| Reboots the node. |
| |
| :param node: The node you wish to destroy. |
| :type volume: :class:`Node` |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| shutdown_body = {"action": "REBOOT", "method": "HARDWARE"} |
| response = self.connection.request( |
| action="servers/%s/status/action" % node.id, |
| data=shutdown_body, |
| method="PUT", |
| ) |
| return self._to_node(response.object) |
| |
| """ |
| Extension functions |
| """ |
| |
| def ex_rename_server(self, server_id, name=None, description=None): |
| """ |
| Renames the server |
| :param server_id: ID of the server you want to rename |
| |
| :param name: New name of the server |
| :type: ``str`` |
| |
| :param description: New description of the server |
| :type: ``str`` |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| |
| body = {} |
| if name is not None: |
| body["name"] = name |
| if description is not None: |
| body["description"] = description |
| |
| response = self.connection.request(action="servers/%s" % server_id, data=body, method="PUT") |
| |
| return self._to_node(response.object) |
| |
| def ex_get_server_hardware(self, server_id): |
| """ |
| Gets all server hardware |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :return: Server's hardware |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="servers/%s/hardware" % server_id, method="GET") |
| return response.object |
| |
| """ |
| Hardware operations |
| """ |
| |
| def ex_modify_server_hardware( |
| self, |
| server_id, |
| fixed_instance_size_id=None, |
| vcore=None, |
| cores_per_processor=None, |
| ram=None, |
| ): |
| """ |
| Modifies server's hardware |
| |
| :param server_id: |
| :type: ``str`` |
| |
| :param fixed_instance_size_id: Id of the fixed instance size |
| :type: ``str`` |
| |
| :param vcore: Virtual cores count |
| :type: ``int`` |
| |
| :param cores_per_processor: Count of cores per procesor |
| :type: ``int`` |
| |
| :param ram: Amount of ram for the server |
| :type: ``int`` |
| |
| :return: Instance of class ``Node`` |
| :type: :class: `Node` |
| """ |
| |
| body = {} |
| |
| if fixed_instance_size_id is not None: |
| body["fixed_instance_size_id"] = fixed_instance_size_id |
| if vcore is not None: |
| body["vcore"] = vcore |
| if cores_per_processor is not None: |
| body["cores_per_processor"] = cores_per_processor |
| if ram is not None: |
| body["ram"] = ram |
| |
| response = self.connection.request( |
| action="servers/%s/hardware" % server_id, data=body, method="PUT" |
| ) |
| |
| return self._to_node(response.object) |
| |
| """ |
| HDD operations |
| """ |
| |
| def ex_modify_server_hdd(self, server_id, hdd_id=None, size=None): |
| """ |
| Modifies server hard disk drives |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param hdd_id: Id of the hard disk |
| :type: ``str`` |
| |
| :param size: Size of the hard disk |
| :type: ``str`` |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| |
| body = {} |
| |
| if size is not None: |
| body["size"] = size |
| |
| response = self.connection.request( |
| action="servers/{}/hardware/hdds/{}".format(server_id, hdd_id), |
| data=body, |
| method="PUT", |
| ) |
| |
| return self._to_node(response.object) |
| |
| def ex_add_hdd(self, server_id, size, is_main): |
| """ |
| Add a hard disk to the server |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param size: Size of the new disk |
| :type: ``str`` |
| |
| :param is_main: Indicates if the disk is going to be the boot disk |
| :type: ``boolean`` |
| |
| :return: Instance of class ``Node`` |
| :type: :class: `Node` |
| """ |
| body = {"size": size, "is_main": is_main} |
| |
| response = self.connection.request( |
| action="servers/%s/hardware/hdds" % server_id, data=body, method="POST" |
| ) |
| |
| return self._to_node(response.object) |
| |
| def ex_remove_hdd(self, server_id, hdd_id): |
| """ |
| Removes existing hard disk |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param hdd_id: Id of the hard disk |
| :type: ``str`` |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| |
| response = self.connection.request( |
| action="servers/{}/hardware/hdds/{}".format(server_id, hdd_id), method="DELETE" |
| ) |
| |
| return self._to_node(response.object) |
| |
| """ |
| Data center operations |
| """ |
| |
| def ex_list_datacenters(self): |
| """ |
| Lists all data centers |
| |
| :return: List of data centers |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="datacenters", method="GET") |
| |
| return response.object |
| |
| def ex_get_server(self, server_id): |
| """ |
| Gets a server |
| |
| :param server_id: Id of the server to be retrieved |
| :type: ``str`` |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| |
| response = self.connection.request(action="servers/%s" % (server_id), method="GET") |
| |
| return self._to_node(response.object) |
| |
| def ex_shutdown_server(self, server_id, method="SOFTWARE"): |
| """ |
| Shuts down the server |
| |
| :param server_id: Id of the server to be shut down |
| :type: ``str`` |
| |
| :param method: Method of shutting down "SOFTWARE" or "HARDWARE" |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| |
| shutdown_body = {"action": "POWER_OFF", "method": method} |
| response = self.connection.request( |
| action="servers/%s/status/action" % (server_id), |
| data=shutdown_body, |
| method="PUT", |
| ) |
| return self._to_node(response.object) |
| |
| """ |
| Image operations |
| """ |
| |
| def ex_get_server_image(self, server_id): |
| """ |
| Gets server image |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :return: Server image |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request(action="servers/%s/image" % server_id, method="GET") |
| return response.object |
| |
| def ex_reinstall_server_image(self, server_id, image_id, password=None): |
| """ |
| Installs a new image on the server |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param image_id: Id of the image (Server Appliance) |
| :type: ``str`` |
| |
| :param password: New password for the server |
| |
| :return: Instance of class ``Node`` |
| :rtype: :class: `Node` |
| """ |
| |
| body = { |
| "id": image_id, |
| } |
| |
| if password is not None: |
| body["password"] = password |
| |
| response = self.connection.request( |
| action="servers/%s/image" % server_id, data=body, method="PUT" |
| ) |
| return self._to_node(response.object) |
| |
| """ |
| Server IP operations |
| """ |
| |
| def ex_list_server_ips(self, server_id): |
| """ |
| Gets all server IP objects |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :return: List of server IP objects |
| :rtype: ``list`` of ``dict`` |
| """ |
| response = self.connection.request(action="servers/%s/ips" % server_id, method="GET") |
| |
| return response.object |
| |
| def ex_get_server_ip(self, server_id, ip_id): |
| """ |
| Get a single server IP object |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param ip_id: ID of the IP address |
| :type: ``str`` |
| |
| :return: IP address object |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="servers/{}/ips/{}".format(server_id, ip_id), method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_assign_server_ip(self, server_id, ip_type): |
| """ |
| Assigns a new IP address to the server |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param ip_type: Type of the IP address [IPV4,IPV6] |
| :type: ``str`` |
| |
| :return: ``Node`` instance |
| :rtype: ``Node`` |
| """ |
| |
| body = {"type": ip_type} |
| |
| response = self.connection.request( |
| action="servers/%s/ips" % server_id, data=body, method="POST" |
| ) |
| |
| return self._to_node(response.object) |
| |
| def ex_remove_server_ip(self, server_id, ip_id, keep_ip=None): |
| """ |
| Removes an IP address from the server |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param ip_id: ID of the IP address |
| :type: ``str`` |
| |
| :param keep_ip: Indicates whether IP address will be removed from |
| the Cloud Panel |
| :type: ``boolean`` |
| |
| :return: ``Node`` instance |
| :rtype: ``Node`` |
| """ |
| |
| body = {} |
| if keep_ip is not None: |
| body["keep_ip"] = keep_ip |
| |
| response = self.connection.request( |
| action="servers/{}/ips/{}".format(server_id, ip_id), data=body, method="DELETE" |
| ) |
| |
| return self._to_node(response.object) |
| |
| def ex_get_server_firewall_policies(self, server_id, ip_id): |
| """ |
| Gets a firewall policy of attached to the server's IP |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param ip_id: ID of the IP address |
| :type: ``str`` |
| |
| :return: IP address object |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="/servers/{}/ips/{}/firewall_policy".format(server_id, ip_id), |
| method="GET", |
| ) |
| |
| return response.object |
| |
| def ex_add_server_firewall_policy(self, server_id, ip_id, firewall_id): |
| """ |
| Adds a firewall policy to the server's IP address |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :param ip_id: ID of the IP address |
| :type: ``str`` |
| |
| :param firewall_id: ID of the firewall policy |
| :type: ``str`` |
| |
| :return: ``Node`` instance |
| :rtype: ``Node`` |
| """ |
| body = {"id": firewall_id} |
| response = self.connection.request( |
| action="/servers/{}/ips/{}/firewall_policy".format(server_id, ip_id), |
| data=body, |
| method="POST", |
| ) |
| |
| return self._to_node(response.object) |
| |
| """ |
| Firewall Policy operations |
| """ |
| |
| def ex_create_firewall_policy(self, name, rules, description=None): |
| """ |
| Creates a firewall Policy. |
| |
| :param name: |
| :param description: |
| :param rules: |
| |
| :rtype: `dict` |
| :return: `dict` firewall policy |
| |
| """ |
| body = {"name": name} |
| |
| if description is not None: |
| body["description"] = description |
| |
| if len(rules) == 0: |
| raise ValueError("At least one firewall rule is required.") |
| else: |
| body["rules"] = rules |
| |
| response = self.connection.request( |
| action="firewall_policies", |
| data=body, |
| method="POST", |
| ) |
| |
| return response.object |
| |
| def ex_list_firewall_policies(self): |
| """ " |
| List firewall policies |
| |
| :return: 'dict' |
| """ |
| |
| response = self.connection.request(action="firewall_policies", method="GET") |
| |
| return response.object |
| |
| def ex_get_firewall_policy(self, fw_id): |
| """ |
| Gets firewall policy |
| |
| :param fw_id: ID of the firewall policy |
| :return: 'dict' |
| """ |
| |
| response = self.connection.request(action="firewall_policy/%s" % fw_id, method="GET") |
| |
| return response.object |
| |
| def ex_delete_firewall_policy(self, fw_id): |
| """ |
| Deletes firewall policy |
| |
| :param fw_id: ID of the Firewall |
| :return: 'dict' |
| """ |
| response = self.connection.request(action="firewall_policy/%s" % fw_id, method="DELETE") |
| |
| return response.object |
| |
| """ |
| Shared storage operations |
| """ |
| |
| def ex_list_shared_storages(self): |
| """ |
| List of shared storages |
| :return: 'dict' |
| """ |
| response = self.connection.request(action="shared_storages", method="GET") |
| |
| return response.object |
| |
| def ex_get_shared_storage(self, storage_id): |
| """ |
| Gets a shared storage |
| :return: 'dict' |
| """ |
| response = self.connection.request(action="shared_storages/%s" % (storage_id), method="GET") |
| |
| return response.object |
| |
| def ex_create_shared_storage(self, name, size, datacenter_id=None, description=None): |
| """ |
| Creates a shared storage |
| :param name: Name of the storage |
| :param size: Size of the storage |
| :param datacenter_id: datacenter where storage should be created |
| :param description: description ot the storage |
| :return: 'dict' |
| """ |
| |
| body = {"name": name, "size": size, "datacenter_id": datacenter_id} |
| |
| if description is not None: |
| body["description"] = description |
| |
| response = self.connection.request(action="shared_storages", data=body, method="POST") |
| |
| return response.object |
| |
| def ex_delete_shared_storage(self, storage_id): |
| """ |
| Removes a shared storage |
| |
| :param storage_id: Id of the shared storage |
| :type: ``str`` |
| |
| :return: Instnace of shared storage |
| :rtype: ``list`` of ``dict`` |
| """ |
| response = self.connection.request( |
| action="shared_storages/%s" % storage_id, method="DELETE" |
| ) |
| |
| return response.object |
| |
| def ex_attach_server_to_shared_storage(self, storage_id, server_id, rights): |
| """ |
| Attaches a single server to a shared storage |
| |
| :param storage_id: Id of the shared storage |
| :param server_id: Id of the server to be attached to the shared storage |
| :param rights: |
| :return: |
| :rtype: 'dict' |
| """ |
| body = {"severs": [{"id": server_id, "rights": rights}]} |
| |
| response = self.connection.request( |
| action="shared_storages/%s/servers" % storage_id, data=body, method="POST" |
| ) |
| |
| return response.object |
| |
| def ex_get_shared_storage_server(self, storage_id, server_id): |
| """ |
| Gets a shared storage's server |
| :param storage_id: |
| :param server_id: |
| :return: |
| """ |
| response = self.connection.request( |
| action="shared_storages/{}/servers/{}".format(storage_id, server_id), |
| ) |
| |
| return response.object |
| |
| def ex_detach_server_from_shared_storage(self, storage_id, server_id): |
| """ |
| Detaches a server from shared storage |
| |
| :param storage_id: Id of the shared storage |
| :type: ``str`` |
| |
| :param server_id: Id of the server |
| :type: ``str`` |
| |
| :return: Instance of shared storage |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="shared_storages/{}/servers/{}".format(storage_id, server_id), |
| method="DELETE", |
| ) |
| |
| return response.object |
| |
| """ |
| Load Balancers operations |
| """ |
| |
| def ex_create_load_balancer( |
| self, |
| name, |
| method, |
| rules, |
| persistence=None, |
| persistence_time=None, |
| health_check_test=None, |
| health_check_interval=None, |
| health_check_path=None, |
| health_check_parser=None, |
| datacenter_id=None, |
| description=None, |
| ): |
| """ |
| |
| :param name: Name of the load balancer |
| |
| :param method: Load balancer method |
| |
| :param rules: Load balancer rules |
| :type rules: ``list`` of ``dict`` |
| |
| :param persistence: Indictes if persistance is set |
| :type persistence: ``boolean`` |
| |
| :param persistence_time: Persistance time |
| :type persistence_time: ``int`` |
| |
| :param health_check_test: Type of test |
| :type health_check_test:``str`` |
| |
| :param health_check_interval: Interval of the check |
| |
| :param health_check_path: Path |
| :type health_check_path: ``str`` |
| |
| :param health_check_parser: Parser |
| :type health_check_parser:``str`` |
| |
| :param datacenter_id: Data center id |
| :type datacenter_id:``str`` |
| |
| :param description: Description of load balancer |
| :type description:``str`` |
| |
| :return: ``dict`` |
| """ |
| |
| body = { |
| "name": name, |
| "method": method, |
| } |
| |
| body["rules"] = [] |
| body["rules"] = rules |
| |
| if persistence is not None: |
| body["persistence"] = persistence |
| if persistence_time is not None: |
| body["persistence_time"] = persistence_time |
| if health_check_test is not None: |
| body["health_check_test"] = health_check_test |
| if health_check_interval is not None: |
| body["health_check_interval"] = health_check_interval |
| if health_check_path is not None: |
| body["health_check_path"] = health_check_path |
| if health_check_parser is not None: |
| body["health_check_parser"] = health_check_parser |
| if datacenter_id is not None: |
| body["datacenter_id"] = datacenter_id |
| if description is not None: |
| body["description"] = description |
| |
| response = self.connection.request(action="load_balancers", data=body, method="POST") |
| |
| return response.object |
| |
| def ex_update_load_balancer( |
| self, |
| lb_id, |
| name=None, |
| description=None, |
| health_check_test=None, |
| health_check_interval=None, |
| persistence=None, |
| persistence_time=None, |
| method=None, |
| ): |
| body = {} |
| |
| if name is not None: |
| body["name"] = name |
| if description is not None: |
| body["description"] = description |
| if health_check_test is not None: |
| body["health_check_test"] = health_check_test |
| if health_check_interval is not None: |
| body["health_check_interval"] = health_check_interval |
| if persistence is not None: |
| body["persistence"] = persistence |
| if persistence_time is not None: |
| body["persistence_time"] = persistence_time |
| if method is not None: |
| body["method"] = method |
| |
| response = self.connection.request( |
| action="load_balancers/%s" % lb_id, data=body, method="PUT" |
| ) |
| |
| return response.object |
| |
| def ex_add_servers_to_load_balancer(self, lb_id, server_ips=[]): |
| """ |
| Adds server's IP address to load balancer |
| |
| :param lb_id: Load balancer ID |
| :type: ``str`` |
| |
| :param server_ips: Array of server IP IDs |
| :type: ``list`` of ``str`` |
| |
| :return: Instance of load balancer |
| :rtype: ``dict`` |
| """ |
| body = { |
| "server_ips": server_ips, |
| } |
| |
| response = self.connection.request( |
| action="load_balancers/%s/server_ips" % lb_id, data=body, method="POST" |
| ) |
| |
| return response.object |
| |
| def ex_remove_server_from_load_balancer(self, lb_id, server_ip): |
| """ |
| Removes server's IP from load balancer |
| |
| :param lb_id: Load balancer ID |
| :type: ``str`` |
| |
| :param server_ip: ID of the server IP |
| :type: ``str`` |
| |
| :return: Instance of load balancer |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="/load_balancers/{}/server_ips/{}".format(lb_id, server_ip), |
| method="DELETE", |
| ) |
| |
| return response.object |
| |
| def ex_add_load_balancer_rule(self, lb_id, protocol, port_balancer, port_server, source=None): |
| """ |
| Adds a rule to load balancer |
| |
| :param lb_id: Load balancer ID |
| :rtype: ``str`` |
| |
| :param protocol: Load balancer protocol |
| :rtype: ``str`` |
| |
| :param port_balancer: Port to be balananced |
| :rtype: ``int`` |
| |
| :param port_server: Server port |
| :rtype: ``int`` |
| |
| :param source: Source IP address |
| :rtype: ``str`` |
| |
| :return: Instance of load balancer |
| :rtype: ``dict`` |
| """ |
| |
| body = { |
| "rules": [ |
| { |
| "protocol": protocol, |
| "port_balancer": port_balancer, |
| "port_server": port_server, |
| } |
| ] |
| } |
| |
| if source is not None: |
| body["rules"][0]["source"] = source |
| |
| response = self.connection.request( |
| action="/load_balancers/%s/rules" % lb_id, data=body, method="POST" |
| ) |
| |
| return response.object |
| |
| def ex_remove_load_balancer_rule(self, lb_id, rule_id): |
| """ |
| Removes load balancer rule |
| |
| :param lb_id: Load balancer ID |
| :rtype: ``str`` |
| |
| :param rule_id: Rule ID |
| :rtype: ``str`` |
| |
| :return: Instance of load balancer |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="/load_balancers/{}/rules/{}".format(lb_id, rule_id), method="DELETE" |
| ) |
| |
| return response.object |
| |
| def ex_list_load_balancers(self): |
| """ |
| Lists all load balancers |
| |
| :return: List of load balancers |
| :rtype: ``list`` of ``dict`` |
| """ |
| response = self.connection.request(action="load_balancers", method="GET") |
| return response.object |
| |
| def ex_get_load_balancer(self, lb_id): |
| """ |
| Gets a single load balancer |
| |
| :param lb_id: ID of the load balancer |
| :type lb_id: ``str`` |
| |
| :return: Instance of load balancer |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="load_balancers/%s" % lb_id, method="GET") |
| |
| return response.object |
| |
| def ex_list_load_balancer_server_ips(self, lb_id): |
| """ |
| List balanced server IP addresses |
| |
| :param lb_id: ID of the load balancer |
| :type lb_id: ``str`` |
| |
| :return: Array of IP address IDs |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="load_balancers/%s/server_ips" % lb_id, method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_get_load_balancer_server_ip(self, lb_id, server_ip): |
| """ |
| Gets load balanced server id |
| |
| :param lb_id: ID of the load balancer |
| :type lb_id: ``str`` |
| |
| :param server_ip: ID of the server IP |
| :type server_ip: ``str`` |
| |
| :return: Server IP |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="load_balancers/{}/server_ips/{}".format(lb_id, server_ip), method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_list_load_balancer_rules(self, lb_id): |
| """ |
| Lists loadbalancer rules |
| |
| :param lb_id: ID of the load balancer |
| :type lb_id: ``str`` |
| |
| :return: Lists of rules |
| :rtype: ``list`` of ``dict`` |
| """ |
| response = self.connection.request(action="load_balancers/%s/rules" % lb_id, method="GET") |
| |
| return response.object |
| |
| def ex_get_load_balancer_rule(self, lb_id, rule_id): |
| """ |
| Get a load balancer rule |
| |
| :param lb_id: ID of the load balancer |
| :type lb_id: ``str`` |
| |
| :param rule_id: Rule ID |
| :type rule_id: ``str`` |
| |
| :return: A load balancer rule |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="load_balancers/{}/rules/{}".format(lb_id, rule_id), method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_delete_load_balancer(self, lb_id): |
| """ |
| Deletes a load balancer rule |
| |
| :param lb_id: ID of the load balancer |
| :type lb_id: ``str`` |
| |
| :param rule_id: Rule ID |
| :type rule_id: ``str`` |
| |
| :return: Instance of load balancer |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="load_balancers/%s" % lb_id, method="DELETE") |
| |
| return response.object |
| |
| """ |
| Public IP operations |
| """ |
| |
| def ex_list_public_ips(self): |
| """ |
| Lists all public IP addresses |
| |
| :return: Array of public addresses |
| :rtype: ``list`` of ``dict`` |
| """ |
| response = self.connection.request(action="public_ips", method="GET") |
| |
| return response.object |
| |
| def ex_create_public_ip(self, type, reverse_dns=None, datacenter_id=None): |
| """ |
| Creates a public IP |
| |
| :param type: Type of IP (IPV4 or IPV6) |
| :type type: ``str`` |
| |
| :param reverse_dns: Reverse DNS |
| :type reverse_dns: ``str`` |
| |
| :param datacenter_id: Datacenter ID where IP address will be crated |
| :type datacenter_id: ``str`` |
| |
| :return: Instance of Public IP |
| :rtype: ``dict`` |
| """ |
| body = {"type": type} |
| |
| if reverse_dns is not None: |
| body["reverse_dns"] = reverse_dns |
| if datacenter_id is not None: |
| body["datacenter_id"] = datacenter_id |
| |
| response = self.connection.request(action="public_ips", data=body, method="POST") |
| |
| return response.object |
| |
| def ex_get_public_ip(self, ip_id): |
| """ |
| Gets a Public IP |
| |
| :param ip_id: ID of the IP |
| :type ip_id: ``str`` |
| |
| :return: Instance of Public IP |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="public_ips/%s" % ip_id, method="GET") |
| |
| return response.object |
| |
| def ex_delete_public_ip(self, ip_id): |
| """ |
| Deletes a public IP |
| |
| :param ip_id: ID of public IP |
| :type ip_id: ``str`` |
| |
| :return: Instance of IP Address |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="public_ips/%s" % ip_id, method="DELETE") |
| |
| return response |
| |
| def ex_update_public_ip(self, ip_id, reverse_dns): |
| """ |
| Updates a Public IP |
| |
| :param ip_id: ID of public IP |
| :type ip_id: ``str`` |
| |
| :param reverse_dns: Reverse DNS |
| :type reverse_dns: ``str`` |
| |
| :return: Instance of Public IP |
| :rtype: ``dict`` |
| """ |
| |
| body = {"reverse_dns": reverse_dns} |
| response = self.connection.request( |
| action="public_ips/%s" % ip_id, data=body, method="DELETE" |
| ) |
| |
| return response.object |
| |
| """ |
| Private Network Operations |
| """ |
| |
| def ex_list_private_networks(self): |
| """ |
| Lists all private networks |
| |
| :return: List of private networks |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="private_networks", method="GET") |
| |
| return response.object |
| |
| def ex_create_private_network( |
| self, |
| name, |
| description=None, |
| datacenter_id=None, |
| network_address=None, |
| subnet_mask=None, |
| ): |
| """ |
| Creates a private network |
| |
| :param name: Name of the private network |
| :type name: ``str`` |
| |
| :param description: Description of the private network |
| :type description: ``str`` |
| |
| :param datacenter_id: ID of the data center for the private network |
| :type datacenter_id: ``str`` |
| |
| :param network_address: Network address of the private network |
| :type network_address: ``str`` |
| |
| :param subnet_mask: Subnet mask of the private network |
| :type subnet_mask: ``str`` |
| |
| :return: Newly created private network |
| :rtype: ``dict`` |
| """ |
| |
| body = {"name": name} |
| |
| if description is not None: |
| body["description"] = description |
| if datacenter_id is not None: |
| body["datacenter_id"] = datacenter_id |
| if network_address is not None: |
| body["network_address"] = network_address |
| if subnet_mask is not None: |
| body["subnet_maks"] = subnet_mask |
| |
| response = self.connection.request(action="private_networks", data=body, method="POST") |
| return response.object |
| |
| def ex_delete_private_network(self, network_id): |
| """ |
| Deletes a private network |
| |
| :param network_id: Id of the private network |
| :type network_id: ``str`` |
| |
| :return: Instance of the private network being deleted |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="private_networks" % network_id, method="DELETE") |
| |
| return response.object |
| |
| def ex_update_private_network( |
| self, |
| network_id, |
| name=None, |
| description=None, |
| datacenter_id=None, |
| network_address=None, |
| subnet_mask=None, |
| ): |
| """ |
| Updates a private network |
| |
| :param name: Name of the private network |
| :type name: ``str`` |
| |
| :param description: Description of the private network |
| :type description: ``str`` |
| |
| :param datacenter_id: ID of the data center for the private network |
| :type datacenter_id: ``str`` |
| |
| :param network_address: Network address of the private network |
| :type network_address: ``str`` |
| |
| :param subnet_mask: Subnet mask of the private network |
| :type subnet_mask: ``str`` |
| |
| :return: Instance of private network |
| :rtype: ``dict`` |
| """ |
| body = {} |
| |
| if name is not None: |
| body["name"] = name |
| if description is not None: |
| body["description"] = description |
| if datacenter_id is not None: |
| body["datacenter_id"] = datacenter_id |
| if network_address is not None: |
| body["network_address"] = network_address |
| if subnet_mask is not None: |
| body["subnet_maks"] = subnet_mask |
| |
| response = self.connection.request(action="private_networks/%s", data=body, method="PUT") |
| |
| return response.object |
| |
| def ex_list_private_network_servers(self, network_id): |
| """ |
| Lists all private network servers |
| |
| :param network_id: Private network ID |
| :type network_id: ``str`` |
| |
| :return: List of private network servers |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="/private_networks/%s/servers" % network_id, method="GET" |
| ) |
| return response.object |
| |
| def ex_add_private_network_server(self, network_id, server_ids): |
| """ |
| Add servers to private network |
| |
| :param network_id: Private Network ID |
| :type network_id: ``str`` |
| |
| :param server_ids: List of server IDs |
| :type server_ids: ``list`` of ``str`` |
| |
| :return: List of attached servers |
| :rtype: ``dict`` |
| |
| """ |
| body = {"servers": server_ids} |
| |
| response = self.connection.request( |
| action="/private_networks/%s/servers" % network_id, data=body, method="POST" |
| ) |
| |
| return response.object |
| |
| def ex_remove_server_from_private_network(self, network_id, server_id): |
| """ |
| Removes a server from the private network |
| |
| :param network_id: Private Network ID |
| :type network_id: ``str`` |
| |
| :param server_id: Id of the server |
| :type server_id: ``str`` |
| |
| :return: Instance of the private network |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="/private_networks/{}/servers/{}".format(network_id, server_id), |
| method="POST", |
| ) |
| return response.object |
| |
| """ |
| Monitoring policy operations |
| """ |
| |
| def ex_list_monitoring_policies(self): |
| """ |
| Lists all monitoring policies |
| |
| :return: List of monitoring policies |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request(action="monitoring_policies", method="GET") |
| |
| return response.object |
| |
| def ex_create_monitoring_policy( |
| self, |
| name, |
| thresholds, |
| ports, |
| processes, |
| description=None, |
| email=None, |
| agent=None, |
| ): |
| """ |
| Creates a monitoring policy |
| |
| :param name: Name for the monitoring policy |
| :type name: ``str`` |
| |
| :param thresholds: Thresholds for the monitoring policy |
| :type thresholds: ``dict`` |
| |
| :param ports: Monitoring policies for ports |
| :type ports: ``list`` of ``dict`` |
| |
| :param processes: Processes to be monitored |
| :type processes: ``list`` of ``dict`` |
| |
| :param description: Description for the monitoring policy |
| :type description: ``str`` |
| |
| :param email: Email for notifications |
| :type email: ``str`` |
| |
| :param agent: Indicates if agent application will be installed |
| :type agent: ``boolean`` |
| |
| :return: Newly created instance of monitofing policy |
| :rtype: ``dict`` |
| """ |
| body = { |
| "name": name, |
| "thresholds": thresholds, |
| "ports": ports, |
| "processes": processes, |
| } |
| |
| if description is not None: |
| body["description"] = description |
| if email is not None: |
| body["email"] = email |
| if agent is not None: |
| body["agent"] = agent |
| |
| response = self.connection.request(action="monitoring_policies", data=body, method="POST") |
| return response.object |
| |
| def ex_delete_monitoring_policy(self, policy_id): |
| """ |
| Deletes a monitoring policy |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :return: Instance of the monitoring policy being deleted |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="monitoring_policies" % policy_id, method="DELETE" |
| ) |
| |
| return response.object |
| |
| def ex_update_monitoring_policy( |
| self, policy_id, email, thresholds, name=None, description=None |
| ): |
| """ |
| Updates monitoring policy |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param email: Email to send notifications to |
| :type email: ``str`` |
| |
| :param thresholds: Thresholds for the monitoring policy |
| :type thresholds: ``dict`` |
| |
| :param name: Name of the monitoring policy |
| :type name: ``str`` |
| |
| :param description: Description of the monitoring policy |
| :type description: ``str`` |
| |
| :return: Instance of the monitoring policy being deleted |
| :rtype: ``dict`` |
| """ |
| |
| body = {} |
| |
| if name is not None: |
| body["name"] = name |
| if description is not None: |
| body["description"] = description |
| if thresholds is not None: |
| body["thresholds"] = thresholds |
| if email is not None: |
| body["email"] = email |
| |
| response = self.connection.request( |
| action="monitoring_policies/%s" % policy_id, data=body, method="PUT" |
| ) |
| |
| return response.object |
| |
| def ex_get_monitoring_policy(self, policy_id): |
| """ |
| Fetches a monitoring policy |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="monitoring_policies/%s" % policy_id, method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_get_monitoring_policy_ports(self, policy_id): |
| """ |
| Fetches monitoring policy ports |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="monitoring_policies/%s/ports" % policy_id, method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_get_monitoring_policy_port(self, policy_id, port_id): |
| """ |
| Fetches monitoring policy port |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param port_id: Id of the port |
| :type port_id: ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="monitoring_policies/{}/ports/{}".format(policy_id, port_id), |
| method="GET", |
| ) |
| |
| return response.object |
| |
| def ex_remove_monitoring_policy_port(self, policy_id, port_id): |
| """ |
| Removes monitoring policy port |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param port_id: Id of the port |
| :type port_id: ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="monitoring_policies/{}/ports/{}".format(policy_id, port_id), |
| method="DELETE", |
| ) |
| |
| return response.object |
| |
| def ex_add_monitoring_policy_ports(self, policy_id, ports): |
| """ |
| Add monitoring policy ports |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param ports: List of ports |
| :type ports: ``dict`` |
| [ |
| { |
| 'protocol':'TCP', |
| 'port':'80', |
| 'alert_if':'RESPONDING', |
| 'email_notification':true |
| } |
| ] |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| body = {"ports": ports} |
| |
| response = self.connection.request( |
| action="monitoring_policies/%s/ports" % policy_id, data=body, method="POST" |
| ) |
| |
| return response.object |
| |
| def ex_get_monitoring_policy_processes(self, policy_id): |
| """ |
| Fetches monitoring policy processes |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="monitoring_policies/%s/processes" % policy_id, method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_get_monitoring_policy_process(self, policy_id, process_id): |
| """ |
| Fetches monitoring policy process |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param process_id: Id of the process |
| :type process_id: ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="monitoring_policies/{}/processes/{}".format(policy_id, process_id), |
| method="GET", |
| ) |
| |
| return response.object |
| |
| def ex_remove_monitoring_policy_process(self, policy_id, process_id): |
| """ |
| Removes monitoring policy process |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param process_id: Id of the process |
| :type process_id: ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="monitoring_policies/{}/processes/{}".format(policy_id, process_id), |
| method="DELETE", |
| ) |
| |
| return response.object |
| |
| def ex_add_monitoring_policy_processes(self, policy_id, processes): |
| """ |
| Add monitoring policy processes |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param processes: List of processes |
| :type processes: ``list`` of ``dict`` |
| [ |
| { |
| 'process': 'taskmmgr', |
| 'alert_if': 'RUNNING', |
| 'email_notification': true |
| } |
| ] |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| |
| body = {"processes": processes} |
| |
| response = self.connection.request( |
| action="monitoring_policies/%s/processes" % policy_id, |
| data=body, |
| method="POST", |
| ) |
| |
| return response.object |
| |
| def ex_list_monitoring_policy_servers(self, policy_id): |
| """ |
| List all servers that are being monitoried by the policy |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :return: List of servers being monitored |
| :rtype: ``list`` of ``dict`` |
| """ |
| |
| response = self.connection.request( |
| action="monitoring_policies/%s/servers" % policy_id, method="GET" |
| ) |
| |
| return response.object |
| |
| def ex_add_servers_to_monitoring_policy(self, policy_id, servers): |
| """ |
| Adds servers to monitoring policy |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param servers: List of server ID |
| :type servers: ``list`` of ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| body = {"servers": servers} |
| response = self.connection.request( |
| action="monitoring_policies/%s/servers" % policy_id, |
| data=body, |
| method="POST", |
| ) |
| |
| return response.object |
| |
| def ex_remove_server_from_monitoring_policy(self, policy_id, server_id): |
| """ |
| Removes a server from monitoring policy |
| |
| :param policy_id: Id of the monitoring policy |
| :type policy_id: ``str`` |
| |
| :param server_id: Id of the server |
| :type server_id: ``str`` |
| |
| :return: Instance of a monitoring policy |
| :rtype: ``dict`` |
| """ |
| response = self.connection.request( |
| action="monitoring_policies/{}/servers/{}".format(policy_id, server_id), |
| method="DELETE", |
| ) |
| |
| return response.object |
| |
| """ |
| Private Functions |
| """ |
| |
| def _to_images(self, object, image_type=None): |
| if image_type is not None: |
| images = [image for image in object if image["type"] == image_type] |
| else: |
| images = [image for image in object] |
| |
| return [self._to_image(image) for image in images] |
| |
| def _to_image(self, data): |
| extra = { |
| "os_family": data["os_family"], |
| "os": data["os"], |
| "os_version": data["os_version"], |
| "os_architecture": data["os_architecture"], |
| "os_image_type": data["os_image_type"], |
| "min_hdd_size": data["min_hdd_size"], |
| "available_datacenters": data["available_datacenters"], |
| "licenses": data["licenses"], |
| "version": data["version"], |
| "categories": data["categories"], |
| } |
| return NodeImage(id=data["id"], name=data["name"], driver=self, extra=extra) |
| |
| def _to_node_size(self, data): |
| return NodeSize( |
| id=data["id"], |
| name=data["name"], |
| ram=data["hardware"]["ram"], |
| disk=data["hardware"]["hdds"][0]["size"], |
| bandwidth=None, |
| price=None, |
| driver=self.connection.driver, |
| extra={ |
| "vcores": data["hardware"]["vcore"], |
| "cores_per_processor": data["hardware"]["cores_per_processor"], |
| }, |
| ) |
| |
| def _to_location(self, location): |
| return NodeLocation( |
| id=location["id"], |
| name=location["country_code"], |
| country=location["location"], |
| driver=self.connection.driver, |
| ) |
| |
| def _to_nodes(self, servers): |
| return [self._to_node(server) for server in servers] |
| |
| def _to_node(self, server): |
| extra = {} |
| extra["datacenter"] = server["datacenter"] |
| |
| if "description" in server: |
| extra["description"] = server["description"] |
| if "status" in server: |
| extra["status"] = server["status"] |
| if "image" in server: |
| extra["image"] = server["image"] |
| if "hardware" in server: |
| extra["hardware"] = server["hardware"] |
| if "dvd" in server: |
| extra["dvd"] = server["dvd"] |
| if "snapshot" in server: |
| extra["snapshot"] = server["snapshot"] |
| if "ips" in server: |
| extra["ips"] = server["ips"] |
| if "alerts" in server: |
| extra["alerts"] = server["alerts"] |
| if "monitoring_policy" in server: |
| extra["monitoring_policy"] = server["monitoring_policy"] |
| if "private_networks" in server: |
| extra["private_networks"] = server["private_networks"] |
| |
| ips = [] |
| |
| if server["ips"] is not None: |
| for ip in server["ips"]: |
| ips.append(ip["ip"]) |
| state = self.NODE_STATE_MAP.get(server["status"]["state"]) |
| |
| return Node( |
| id=server["id"], |
| state=state, |
| name=server["name"], |
| driver=self.connection.driver, |
| public_ips=ips, |
| private_ips=None, |
| extra=extra, |
| ) |
| |
| def _wait_for_state(self, server_id, state, retries=50): |
| for i in (0, retries): |
| server = self.ex_get_server(server_id) |
| |
| if server.extra["status"]["state"] == state: |
| return |
| sleep(5) |
| |
| if i == retries: |
| raise Exception("Retries count reached") |
| |
| def _list_fixed_instances(self): |
| response = self.connection.request(action="/servers/fixed_instance_sizes", method="GET") |
| |
| return response.object |