You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by an...@apache.org on 2017/04/11 00:23:58 UTC
[04/11] libcloud git commit: 1&1 Compute Driver
1&1 Compute Driver
Project: http://git-wip-us.apache.org/repos/asf/libcloud/repo
Commit: http://git-wip-us.apache.org/repos/asf/libcloud/commit/ff028ae2
Tree: http://git-wip-us.apache.org/repos/asf/libcloud/tree/ff028ae2
Diff: http://git-wip-us.apache.org/repos/asf/libcloud/diff/ff028ae2
Branch: refs/heads/trunk
Commit: ff028ae26b232e808f303e680aa0d6737224f605
Parents: 419c694
Author: jasminSPC <ja...@stackpointcloud.com>
Authored: Tue Apr 11 00:19:46 2017 +0200
Committer: jasminSPC <ja...@stackpointcloud.com>
Committed: Tue Apr 11 00:19:46 2017 +0200
----------------------------------------------------------------------
docs/compute/drivers/oneandone.rst | 295 +
.../compute/oneandone/create_firewall_policy.py | 33 +
.../compute/oneandone/create_load_balancer.py | 36 +
.../oneandone/create_monitoring_policy.py | 90 +
docs/examples/compute/oneandone/create_node.py | 36 +
.../compute/oneandone/create_private_network.py | 14 +
.../compute/oneandone/create_public_ip.py | 14 +
.../compute/oneandone/create_shared_storage.py | 21 +
.../compute/oneandone/instantiate_driver.py | 9 +
libcloud/common/base.py | 1 +
libcloud/compute/drivers/oneandone.py | 2263 +++
libcloud/compute/providers.py | 2 +
libcloud/compute/types.py | 1 +
.../compute/fixtures/oneandone/auth_error.json | 5 +
.../compute/fixtures/oneandone/create_node.json | 43 +
.../oneandone/describe_firewall_policy.json | 26 +
.../oneandone/describe_id_firewall_policy.json | 4 +
.../fixtures/oneandone/describe_server.json | 49 +
.../oneandone/describe_shared_stoage.json | 29 +
.../fixtures/oneandone/ex_list_datacenters.json | 26 +
.../oneandone/fixed_instance_sizes.json | 70 +
.../compute/fixtures/oneandone/get_image.json | 24 +
.../fixtures/oneandone/get_server_image.json | 4 +
.../oneandone/list_firewall_policies.json | 54 +
.../compute/fixtures/oneandone/list_images.json | 17941 +++++++++++++++++
.../fixtures/oneandone/list_load_balancer.json | 78 +
.../oneandone/list_monitoring_policies.json | 152 +
.../fixtures/oneandone/list_public_ips.json | 59 +
.../fixtures/oneandone/list_servers.json | 197 +
.../oneandone/list_shared_storages.json | 64 +
.../fixtures/oneandone/load_balancer.json | 38 +
.../fixtures/oneandone/load_balancer_rule.json | 7 +
.../fixtures/oneandone/load_balancer_rules.json | 16 +
.../oneandone/load_balancer_server_ip.json | 5 +
.../oneandone/load_balancer_server_ips.json | 6 +
.../fixtures/oneandone/monitoring_policy.json | 73 +
.../oneandone/monitoring_policy_port.json | 7 +
.../oneandone/monitoring_policy_ports.json | 16 +
.../oneandone/monitoring_policy_process.json | 6 +
.../oneandone/monitoring_policy_processes.json | 14 +
.../oneandone/monitoring_policy_servers.json | 10 +
.../compute/fixtures/oneandone/public_ip.json | 15 +
.../fixtures/oneandone/server_hardware.json | 13 +
.../compute/fixtures/oneandone/server_ip.json | 8 +
.../compute/fixtures/oneandone/server_ips.json | 10 +
.../fixtures/oneandone/shared_storage.json | 24 +
.../test/compute/fixtures/oneandone/ttt.json | 73 +
libcloud/test/compute/test_oneandone.py | 1281 ++
libcloud/test/secrets.py-dist | 1 +
49 files changed, 23263 insertions(+)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/compute/drivers/oneandone.rst
----------------------------------------------------------------------
diff --git a/docs/compute/drivers/oneandone.rst b/docs/compute/drivers/oneandone.rst
new file mode 100644
index 0000000..9145124
--- /dev/null
+++ b/docs/compute/drivers/oneandone.rst
@@ -0,0 +1,295 @@
+1&1 Compute Driver Documentation
+================================
+
+`1&1` is one of the world's largest hosting providers. We offer a range of services, including hosting solutions, domains, and websites.
+
+The data centers/availability zones are located in:
+
+- United States of America (US)
+- Germany (DE)
+- United Kingdom or Great Britain and Northern Ireland (GB)
+- Spain (ES)
+
+Instantiating a Driver
+----------------------
+
+To instantiate a driver you will need to pass the API key using the following constructor parameter:
+
+* ``key`` - Your 1&1 API Key
+
+You can obtain your API key in the `1&1 Cloud Panel` under Management ->
+Users where an API key will be generated.
+
+With a newly-generated API token you can instantiate a driver using:
+
+.. literalinclude:: /examples/compute/oneandone/instantiate_driver.py
+ :language: python
+
+
+1&1 Implementation of Libcloud
+------------------------------
+
+The 1&1 driver implements the following ``NodeDriver`` functions:
+
+* ``list_sizes`` - Returns a list of ``NodeSize``
+* ``list_locations`` - Returns a list of ``NodeLocation``
+* ``list_images`` - Returns a list of ``NodeImage``
+* ``get_image`` - Returns a ``NodeImage``
+* ``create_node`` - Creates a ``Node``
+* ``list_nodes`` - Returns a list of ``Node``
+* ``destroy_node`` - Destroys an existing ``Node``
+* ``reboot_node`` - Reboots a ``Node``
+
+1&1 Extension Functions
+-----------------------
+
+Server Functions
+-----------------
+* ``ex_rename_server`` - Allows you to change server name and description
+* ``ex_get_server_hardware`` - Returns server's hardware specification
+* ``ex_modify_server_hardware`` - Updates server hardware
+* ``ex_modify_server_hdd`` - Updates a single server HDD
+* ``ex_add_hdd`` - Adds a new HDD to server
+* ``ex_remove_hdd`` - Removes a HDD from server
+* ``ex_list_datacenters`` - Returns a list of available 1&1 data centers
+* ``ex_get_server`` - Gets a server
+* ``ex_shutdown_server`` - Shuts down a server
+* ``ex_get_server_image`` - Gets server image
+* ``ex_reinstall_server_image`` - Installs a new image on the server
+* ``ex_list_server_ips`` - Gets all server IP objects
+* ``ex_assign_server_ip`` - Assigns a new IP address to the server
+* ``ex_remove_server_ip`` - Removes an IP address from the server
+* ``ex_get_server_firewall_policies`` - Gets a firewall policy attached to the server's IP address
+* ``ex_remove_server_firewall_policy`` - Removes a firewall policy from the server's IP address
+* ``ex_add_server_firewall_policy`` - Adds a firewall policy to the server's IP address
+
+Monitoring Policy Functions
+---------------------------
+* ``ex_list_monitoring_policies`` - Lists all monitoring policies
+* ``ex_create_monitoring_policy`` - Creates a monitoring policy
+* ``ex_delete_monitoring_policy`` - Deletes a monitoring policy
+* ``ex_update_monitoring_policy`` - Updates monitoring policy
+* ``ex_get_monitoring_policy`` - Fetches a monitoring policy
+* ``ex_get_monitoring_policy_ports`` - Fetches monitoring policy ports
+* ``ex_get_monitoring_policy_port`` - Fetches monitoring policy port
+* ``ex_remove_monitoring_policy_port`` - Removes monitoring policy port
+* ``ex_add_monitoring_policy_ports`` - Adds monitoring policy ports
+* ``ex_get_monitoring_policy_processes`` - Fetches monitoring policy processes
+* ``ex_get_monitoring_policy_process`` - Fetches monitoring policy process
+* ``ex_remove_monitoring_policy_process`` - Removes monitoring policy process
+* ``ex_add_monitoring_policy_processes`` - Adds monitoring policy processes
+* ``ex_list_monitoring_policy_servers`` - List all servers that are being monitored by the policy
+* ``ex_add_servers_to_monitoring_policy`` - Adds servers to monitoring policy
+* ``ex_remove_server_from_monitoring_policy`` - Removes a server from monitoring policy
+
+Shared Storage Functions
+------------------------
+* ``ex_list_shared_storages`` - Lists shared storages
+* ``ex_get_shared_storage`` - Gets a shared storage
+* ``ex_create_shared_storage`` - Creates a shared storage
+* ``ex_delete_shared_storage`` - Removes a shared storage
+* ``ex_attach_server_to_shared_storage`` - Attaches a single server to a shared storage
+* ``ex_get_shared_storage_server`` - Gets a shared storage's server
+* ``ex_detach_server_from_shared_storage`` - Detaches a server from shared storage
+
+Public IP Functions
+-------------------
+* ``ex_list_public_ips`` - Lists all public IP addresses
+* ``ex_create_public_ip`` - Creates a public IP
+* ``ex_get_public_ip`` - Gets a public IP
+* ``ex_delete_public_ip`` - Deletes a public IP
+* ``ex_update_public_ip`` - Updates a Public IP
+
+Private Network Functions
+-------------------------
+* ``ex_list_private_networks`` - Lists all private networks
+* ``ex_create_private_network`` - Creates a private network
+* ``ex_delete_private_network`` - Deletes a private network
+* ``ex_update_private_network`` - Updates a private network
+* ``ex_list_private_network_servers`` - Lists all private network servers
+* ``ex_add_private_network_server`` - Adds servers to private network
+* ``ex_remove_server_from_private_network`` - Removes a server from the private network
+
+Load Balancer Functions
+-----------------------
+* ``ex_create_load_balancer`` - Creates a load balancer
+* ``ex_update_load_balancer`` - Updates a load balancer
+* ``ex_add_servers_to_load_balancer`` - Adds servers to a load balancers
+* ``ex_remove_server_from_load_balancer`` - Removes a server from a load balancer
+* ``ex_add_load_balancer_rule`` - Adds a rule to a load balancer
+* ``ex_remove_load_balancer_rule`` - Removes a rule from a load balancer
+* ``ex_list_load_balancers`` - Lists all load balancers
+* ``ex_get_load_balancer`` - Gets a load balancer
+* ``ex_list_load_balancer_server_ips`` - Lists load balanced server IP addresses
+* ``ex_get_load_balancer_server_ip`` - Gets a balanced server IP address
+* ``ex_list_load_balancer_rules`` - Lists load balancer rules
+* ``ex_get_load_balancer_rule`` - Gets a load balancer rule
+* ``ex_delete_load_balancer`` - Deletes a load balancer
+
+Firewall Policy Functions
+-------------------------
+* ``ex_create_firewall_policy`` - Creates a firewall policy
+* ``ex_list_firewall_policies`` - Lists firewall policies
+* ``ex_get_firewall_policy`` - Gets a firewall policy
+* ``ex_delete_firewall_policy`` - Deletes a firewall policy
+
+Create a Node
+-------------
+
+To create a node on 1&1 using Libcloud, follow this example:
+
+.. literalinclude:: /examples/compute/oneandone/create_node.py
+ :language: python
+
+This example will create a 1&1 server using 'S' as a small instance in the 'ES' (spain) data center.
+
+`create_node` has the following parameters:
+
+Required parameters:
+
+* ``name`` - Desired node name. Must be unique.
+* ``image`` - Image ID retrieved from `list_images`.
+* ``ex_fixed_instance_size_id`` - This is an ID of a flavor.
+
+Optional parameters:
+
+* ``auth`` - Password for the server. If none is provided, 1&1 will generate one for you, and return it in the response.
+* ``location`` - Desired `NodeLocation`
+* ``ex_ip`` - ID of a public IP address which can be created using `ex_create_public_ip`.
+* ``ex_monitoring_policy_id`` - Id of a monitoring policy which can be created using `ex_create_monitoring_policy`.
+* ``ex_firewall_policy_id`` - Id of a firewall policy which can be create using `ex_create_firewall_policy`.
+* ``ex_loadbalancer_id`` - Id of a load balancer which can be create using `ex_create_load_balancer`.
+* ``ex_description`` - Description for the server.
+* ``ex_power_on`` - A boolean indicating whether a server will be `POWERED_ON` or `POWERED_OFF` when provisioned.
+
+
+Create a Firewall Policy
+------------------------
+
+To create a firewall policy, follow this example:
+
+.. literalinclude:: /examples/compute/oneandone/create_firewall_policy.py
+ :language: python
+
+This example will create a firewall policy with a TCP rule allowing access on port 80.
+
+`ex_create_firewall_policy` has the following parameters:
+
+Required parameters:
+
+* ``name`` - Desired name for the firewall policy. Must be unique.
+* ``rules`` - ``list`` of ``dict``:
+ * ``protocol`` - One of the follwing protocols can be set TCP, UDP, TCP/UDP, ICMP, IPSEC.
+ * ``port_from`` - Port range start. Must be between 1 and 65535.
+ * ``port_to`` - Port range end. Must be between 1 and 65535.
+ * ``source`` - Source IP address.
+
+
+Optional parameters:
+
+* ``description`` - Description of the firewall policy.
+
+
+Create a Monitoring Policy
+--------------------------
+
+To create a monitoring policy, follow this example:
+
+.. literalinclude:: /examples/compute/oneandone/create_monitoring_policy.py
+ :language: python
+
+`ex_create_monitoring_policy` has the following parameters:
+
+Required parameters:
+
+* ``name`` - Desired name for the monitoring policy. Must be unique.
+* ``thresholds`` - ``dict`` of thresholds to be monitored. See the example
+* ``ports`` - ``list`` of ``dict`` defining which ports are to be monitored. See the example.
+* ``processes`` - ``list`` of ``dict`` defining which processes are to be monitored. See the example.
+
+Optional parameters:
+
+* ``description`` - Description of the monitoring policy.
+* ``email`` - Email address where notifications will be sent.
+* ``agent`` - Indicating whether an agent application should be installed on the host.
+
+Create a Shared Storage
+-----------------------
+
+To create a shared storage, follow this example:
+
+.. literalinclude:: /examples/compute/oneandone/create_shared_storage.py
+ :language: python
+
+Required parameters:
+
+* ``name`` - ``str`` Desired name for the shared storage. Must be unique.
+* ``size`` - ``int`` Size of the shared storage.
+* ``datacenter_id`` - ``str`` 1&1 data center.
+
+Optional parameters:
+
+* ``description`` - Description of the shared storage.
+
+Create a Load Balancer
+----------------------
+
+
+To create a load balancer, follow this example:
+
+ .. literalinclude:: /examples/compute/oneandone/create_load_balancer.py
+ :language: python
+
+Required parameters:
+
+* ``name`` - ``str`` Desired name for the shared storage. Must be unique.
+* ``method`` - ``str``
+* ``rules`` - ``list`` of ``dict``
+
+Optional parameters:
+
+* ``persistence``
+* ``persistence_time``
+* ``health_check_test``
+* ``health_check_interval``
+* ``health_check_path``
+* ``health_check_parser``
+* ``datacenter_id``
+* ``description``
+
+
+Create a Public IP
+------------------
+
+To create a public IP address, follow this example:
+
+ .. literalinclude:: /examples/compute/oneandone/create_public_ip.py
+ :language: python
+
+Required parameters:
+
+* ``type`` - ``str`` IPV4 or IPV6
+
+Optional parameters:
+
+* ``reverse_dns`` - ``str``
+* ``datacenter_id`` - ``str`` 1&1 Datacenter
+
+
+Create a Private Network
+------------------------
+
+To create a private network, follow this example:
+
+ .. literalinclude:: /examples/compute/oneandone/create_private_network.py
+ :language: python
+
+Required parameters:
+
+* ``name`` - ``str`` name of the public network.
+
+Optional parameters:
+
+* ``datacenter_id`` - ``str``
+* ``network_address``
+* ``subnet_mask``
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/create_firewall_policy.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/create_firewall_policy.py b/docs/examples/compute/oneandone/create_firewall_policy.py
new file mode 100644
index 0000000..74db619
--- /dev/null
+++ b/docs/examples/compute/oneandone/create_firewall_policy.py
@@ -0,0 +1,33 @@
+import os
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.ONEANDONE)
+drv = cls(key=os.environ.get('ONEANDONE_TOKEN'))
+
+my_rules = [
+ {
+ "protocol": "TCP",
+ "port_from": 80,
+ "port_to": 80,
+ "source": "0.0.0.0"
+ },
+ {
+ "protocol": "TCP",
+ "port_from": 443,
+ "port_to": 443,
+ "source": "0.0.0.0"
+ }
+]
+
+print(type(my_rules))
+
+try:
+ fw_policy = drv.ex_create_firewall_policy(
+ name='Firewall Policy',
+ rules=my_rules,
+ description='FW Policy Description')
+ print(fw_policy)
+except Exception as e:
+ print(e)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/create_load_balancer.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/create_load_balancer.py b/docs/examples/compute/oneandone/create_load_balancer.py
new file mode 100644
index 0000000..5e08ed9
--- /dev/null
+++ b/docs/examples/compute/oneandone/create_load_balancer.py
@@ -0,0 +1,36 @@
+import os
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.ONEANDONE)
+drv = cls(key=os.environ.get('ONEANDONE_TOKEN'))
+
+rules = [
+ {
+ "protocol": "TCP",
+ "port_balancer": 80,
+ "port_server": 80,
+ "source": "0.0.0.0"
+ },
+ {
+ "protocol": "TCP",
+ "port_balancer": 9999,
+ "port_server": 8888,
+ "source": "0.0.0.0"
+ }
+]
+
+try:
+ shared_storage = drv.ex_create_load_balancer(
+ name="Test Load Balancer",
+ method='ROUND_ROBIN',
+ rules=rules,
+ persistence=False,
+ persistence_time=1200,
+ health_check_test='TCP',
+ health_check_interval=40)
+
+ print(shared_storage)
+except Exception as e:
+ print(e)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/create_monitoring_policy.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/create_monitoring_policy.py b/docs/examples/compute/oneandone/create_monitoring_policy.py
new file mode 100644
index 0000000..d84b80d
--- /dev/null
+++ b/docs/examples/compute/oneandone/create_monitoring_policy.py
@@ -0,0 +1,90 @@
+import os
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.ONEANDONE)
+drv = cls(key=os.environ.get('ONEANDONE_TOKEN'))
+
+ports = [
+ {
+ "protocol": "TCP",
+ "port": 443,
+ "alert_if": "NOT_RESPONDING",
+ "email_notification": True
+ }
+]
+
+processes = [
+ {
+ "process": "httpdeamon",
+ "alert_if": "NOT_RUNNING",
+ "email_notification": False
+ }
+]
+thresholds = {
+ "cpu": {
+ "warning": {
+ "value": 90,
+ "alert": False
+ },
+ "critical": {
+ "value": 95,
+ "alert": False
+ }
+ },
+ "ram": {
+ "warning": {
+ "value": 90,
+ "alert": False
+ },
+ "critical": {
+ "value": 95,
+ "alert": False
+ }
+ },
+ "disk": {
+ "warning": {
+ "value": 80,
+ "alert": False
+ },
+ "critical": {
+ "value": 90,
+ "alert": False
+ }
+ },
+ "transfer": {
+ "warning": {
+ "value": 1000,
+ "alert": False
+ },
+ "critical": {
+ "value": 2000,
+ "alert": False
+ }
+ },
+ "internal_ping": {
+ "warning": {
+ "value": 50,
+ "alert": False
+ },
+ "critical": {
+ "value": 100,
+ "alert": True
+ }
+ }
+}
+
+try:
+ monitoring_policy = drv.ex_create_monitoring_policy(
+ name='Monitoring Policy',
+ ports=ports,
+ thresholds=thresholds,
+ processes=processes,
+ description='Monitoring Policy Description',
+ email="test@test.com",
+ agent=True
+ )
+ print(monitoring_policy)
+except Exception as e:
+ print(e)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/create_node.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/create_node.py b/docs/examples/compute/oneandone/create_node.py
new file mode 100644
index 0000000..444de7d
--- /dev/null
+++ b/docs/examples/compute/oneandone/create_node.py
@@ -0,0 +1,36 @@
+import os
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.ONEANDONE)
+drv = cls(key=os.environ.get('ONEANDONE_TOKEN'))
+
+# First we need to get all avaliable sizes
+sizes = drv.list_sizes()
+
+# Then we select one we want to use to create a node. We pick 'S' as small.
+desired_size = [size for size in sizes if size.name == 'S']
+
+# Let's get all available images
+images = drv.list_images('IMAGE')
+
+# Now we select an image we want to install on to the node.
+# We pick Ubuntu 14.04
+desired_image = \
+ [img for img in images if 'ubuntu1404-64min' in img.name.lower()]
+
+# This step is optional.
+# Then we get the list of available datacenters (locations)
+locations = drv.list_locations()
+
+# And we pick one in this case Spain (ES)
+desired_location = [loc for loc in locations if loc.name == 'ES']
+
+# Now let's create that node:
+node = drv.create_node(name="Libcloud Test Node2",
+ image=desired_image[0],
+ ex_fixed_instance_size_id=desired_size[0].id,
+ location=desired_location[0])
+
+print(node)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/create_private_network.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/create_private_network.py b/docs/examples/compute/oneandone/create_private_network.py
new file mode 100644
index 0000000..c6adb70
--- /dev/null
+++ b/docs/examples/compute/oneandone/create_private_network.py
@@ -0,0 +1,14 @@
+import os
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.ONEANDONE)
+drv = cls(key=os.environ.get('ONEANDONE_TOKEN'))
+
+try:
+ public_network = drv.ex_create_private_network(
+ name='TestPN')
+ print(public_network)
+except Exception as e:
+ print(e)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/create_public_ip.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/create_public_ip.py b/docs/examples/compute/oneandone/create_public_ip.py
new file mode 100644
index 0000000..ec76e05
--- /dev/null
+++ b/docs/examples/compute/oneandone/create_public_ip.py
@@ -0,0 +1,14 @@
+import os
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.ONEANDONE)
+drv = cls(key=os.environ.get('ONEANDONE_TOKEN'))
+
+try:
+ public_ip = drv.ex_create_public_ip(
+ type='IPV4')
+ print(public_ip)
+except Exception as e:
+ print(e)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/create_shared_storage.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/create_shared_storage.py b/docs/examples/compute/oneandone/create_shared_storage.py
new file mode 100644
index 0000000..dbec592
--- /dev/null
+++ b/docs/examples/compute/oneandone/create_shared_storage.py
@@ -0,0 +1,21 @@
+import os
+
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+cls = get_driver(Provider.ONEANDONE)
+drv = cls(key=os.environ.get('ONEANDONE_TOKEN'))
+
+locations = drv.list_locations()
+
+desired_location = [loc for loc in locations if loc.name == 'ES']
+
+try:
+ shared_storage = drv.ex_create_shared_storage(
+ name="Test Shared Storage", size=50,
+ datacenter_id=desired_location[0].id,
+ description=None
+ )
+ print(shared_storage)
+except Exception as e:
+ print(e)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/docs/examples/compute/oneandone/instantiate_driver.py
----------------------------------------------------------------------
diff --git a/docs/examples/compute/oneandone/instantiate_driver.py b/docs/examples/compute/oneandone/instantiate_driver.py
new file mode 100644
index 0000000..9111925
--- /dev/null
+++ b/docs/examples/compute/oneandone/instantiate_driver.py
@@ -0,0 +1,9 @@
+from libcloud.compute.types import Provider
+from libcloud.compute.providers import get_driver
+
+# First we need to instantiate desired libcoud driver.
+cls = get_driver(Provider.ONEANDONE)
+
+token = 'your_token'
+# Then pass in your security token
+drv = cls(key=token)
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/libcloud/common/base.py
----------------------------------------------------------------------
diff --git a/libcloud/common/base.py b/libcloud/common/base.py
index c5759f3..f6826d2 100644
--- a/libcloud/common/base.py
+++ b/libcloud/common/base.py
@@ -514,6 +514,7 @@ class Connection(object):
def request(self, action, params=None, data=None, headers=None,
method='GET', raw=False, stream=False):
+
"""
Request a given `action`.
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/libcloud/compute/drivers/oneandone.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/drivers/oneandone.py b/libcloud/compute/drivers/oneandone.py
new file mode 100644
index 0000000..a33fe3d
--- /dev/null
+++ b/libcloud/compute/drivers/oneandone.py
@@ -0,0 +1,2263 @@
+# 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 libcloud.compute.providers import Provider
+from libcloud.common.base import JsonResponse, ConnectionKey
+from libcloud.compute.base import NodeSize, NodeImage, NodeLocation, \
+ Node, NodeAuthPassword, NodeAuthSSHKey
+from libcloud.common.types import InvalidCredsError
+from libcloud.compute.types import NodeState
+from libcloud.utils.py3 import httplib
+from libcloud.compute.base import NodeDriver
+
+from time import sleep
+
+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 = '%s (code: %s)' % (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(OneAndOneConnection, self). \
+ 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 ```str```
+
+ :param image: Image from list_images
+ :rtype: ``NodeImage``
+
+ :param ex_fixed_instance_size_id:
+ Fixed instance size ID from list_sizes
+ :rtype: ``str``
+
+ :param location: 1&1 Data center Location
+ :type ```NodeLocation```
+
+ :param auth: SSH key or root password
+ :type: :class:`NodeAuthSSHKey` or :class:`NodeAuthPassword`
+
+ :param ex_ip: IP address
+ :type ```str```
+
+ :param ex_ssh_key: SSH Key
+ :type ```str```
+
+ :param password: Password
+ :type ```str```
+
+ :param ex_monitoring_policy_id:
+ :type ```str```
+
+ :param ex_firewall_policy_id:
+ :type ```str```
+
+ :param ex_loadbalancer_id:
+ :type ```str```
+
+ :param ex_description:
+ :type ```str```
+
+ :param ex_power_on:
+ :type ```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
+ :rtype: ``str``
+
+ :param description: New description of the server
+ :rtype: ``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
+ :rtype: ``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:
+ :rtype: ``str``
+
+ :param fixed_instance_size_id: Id of the fixed instance size
+ :rtype: ``str``
+
+ :param vcore: Virtual cores count
+ :rtype: ``int``
+
+ :param cores_per_processor: Count of cores per procesor
+ :rtype: ``int``
+
+ :param ram: Amount of ram for the server
+ :rtype: ``int```
+
+ :return: Instance of class ``Node``
+ :rtype: :class: `Node`
+ """
+
+ body = {}
+
+ if fixed_instance_size_id is not None:
+ body["firewall_policy_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
+ :rtype: ``str``
+
+ :param hdd_id: Id of the hard disk
+ :rtype: ``str``
+
+ :param size: Size of the hard disk
+ :rtype: ``str``
+
+
+ :return: Instance of class ``Node``
+ :rtype: :class: `Node`
+ """
+
+ body = {}
+
+ if size is not None:
+ body[size] = size
+
+ response = self.connection.request(
+ action='servers/%s/hardware/hdds/%s' % (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
+ :rtype: ``str``
+
+ :param size: Size of the new disk
+ :rtype: ``str``
+
+ :param is_main: Indicates if the disk is going to be the boot disk
+ :rtype: ``boolean``
+
+ :return: Instance of class ``Node``
+ :rtype: :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
+ :rtype: ``str``
+
+ :param hdd_id: Id of the hard disk
+ :rtype: ``str``
+
+ :return: Instance of class ``Node``
+ :rtype: :class: `Node`
+ """
+
+ response = self.connection.request(
+ action='servers/%s/hardware/hdds/%s' % (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
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param image_id: Id of the image (Server Appliance)
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param ip_id: ID of the IP address
+ :rtype: ``str``
+
+ :return: IP address object
+ :rtype: ``dict``
+ """
+ response = self.connection.request(
+ action='servers/%s/ips/%s' % (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
+ :rtype: ``str``
+
+ :param ip_type: Type of the IP address [IPV4,IPV6]
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param ip_id: ID of the IP address
+ :rtype: ``str``
+
+ :param keep_ip: Indicates whether IP address will be removed from
+ the Cloud Panel
+ :rtype: ``boolean``
+
+ :return: ``Node`` instance
+ :rtype: ``Node``
+ """
+
+ body = {}
+ if keep_ip is not None:
+ body['keep_ip'] = keep_ip
+
+ response = self.connection.request(
+ action='servers/%s/ips/%s' % (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
+ :rtype: ``str``
+
+ :param ip_id: ID of the IP address
+ :rtype: ``str``
+
+ :return: IP address object
+ :rtype: ``dict``
+ """
+
+ response = self.connection.request(
+ action='/servers/%s/ips/%s/firewall_policy' % (server_id, ip_id),
+ method='GET'
+ )
+
+ return response.object
+
+ def ex_remove_server_firewall_policy(self, server_id, ip_id):
+ """
+ Removes a firewall policy from server's IP
+
+ :param server_id: Id of the server
+ :rtype: ``str``
+
+ :param ip_id: ID of the IP address
+ :rtype: ``str``
+
+ :return: ``Node`` instance
+ :rtype: ``Node``
+ """
+ response = self.connection.request(
+ action='/servers/%s/ips/%s/firewall_policy' % (server_id, ip_id),
+ method='DELETE'
+ )
+
+ return self._to_node(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
+ :rtype: ``str``
+
+ :param ip_id: ID of the IP address
+ :rtype: ``str``
+
+ :param firewall_id: ID of the firewall policy
+ :rtype: ``str``
+
+ :return: ``Node`` instance
+ :rtype: ``Node``
+ """
+ body = {
+ "id": firewall_id
+ }
+ response = self.connection.request(
+ action='/servers/%s/ips/%s/firewall_policy' % (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': [
+ {
+ "protocol": "TCP",
+ "port_from": 80,
+ "port_to": 80,
+ "source": "0.0.0.0"
+ }
+ ]
+
+ :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
+ :rtype: ``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/%s/servers/%s' % (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
+ :rtype: ``str``
+
+ :param server_id: Id of the server
+ :rtype: ``str``
+
+ :return: Instance of shared storage
+ :rtype: ``dict``
+ """
+ response = self.connection.request(
+ action='shared_storages/%s/servers/%s' % (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
+ :rtype:``str``
+
+ :param method: Load balancer method
+ :rtype:``str``
+
+ :param rules: Load balancer rules
+ :rtype: ``list`` of ``dict``
+ "rules": [
+ {
+ "protocol": "TCP",
+ "port_balancer": 80,
+ "port_server": 80,
+ "source": "0.0.0.0"
+ },
+ {
+ "protocol": "TCP",
+ "port_balancer": 9999,
+ "port_server": 8888,
+ "source": "0.0.0.0"
+ }
+ ]
+ :param persistence: Indictes if persistance is set
+ :rtype: ``boolean``
+
+ :param persistence_time: Persistance time
+ :rtype: ``int``
+
+ :param health_check_test: Type of test
+ :rtype:``str``
+
+ :param health_check_interval: Interval of the check
+
+ :param health_check_path: Path
+ :rtype:``str``
+ :param health_check_parser: Parser
+ :rtype:``str``
+
+ :param datacenter_id: Data center id
+ :rtype:``str``
+
+ :param description: Description of load balancer
+ :rtype:``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
+ :rtype: ``str``
+
+ :param server_ips: Array of server IP IDs
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param server_ip: ID of the server IP
+ :rtype: ``str``
+
+ :return: Instance of load balancer
+ :rtype: ``dict``
+ """
+
+ response = self.connection.request(
+ action='/load_balancers/%s/server_ips/%s' % (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/%s/rules/%s' % (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
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param server_ip: ID of the server IP
+ :rtype: ``str``
+
+ :return: Server IP
+ :rtype: ``dict``
+ """
+ response = self.connection.request(
+ action='load_balancers/%s/server_ips/%s' % (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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param rule_id: Rule ID
+ :rtype: ``str``
+
+ :return: A load balancer rule
+ :rtype: ``dict``
+ """
+ response = self.connection.request(
+ action='load_balancers/%s/rules/%s' % (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
+ :rtype: ``str``
+
+ :param rule_id: Rule ID
+ :rtype: ``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]
+ :rtype: ``str``
+
+ :param reverse_dns: Reverse DNS
+ :rtype: ``str``
+
+ :param datacenter_id: Datacenter ID where IP address will be crated
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param reverse_dns: Reverse DNS
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param description: Description of the private network
+ :rtype: ``str``
+
+ :param datacenter_id: ID of the data center for the private network
+ :rtype: ``str``
+
+ :param network_address: Network address of the private network
+ :rtype: ``str``
+
+ :param subnet_mask: Subnet mask of the private network
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param description: Description of the private network
+ :rtype: ``str``
+
+ :param datacenter_id: ID of the data center for the private network
+ :rtype: ``str``
+
+ :param network_address: Network address of the private network
+ :rtype: ``str``
+
+ :param subnet_mask: Subnet mask of the private network
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param server_ids: List of server IDs
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param server_id: Id of the server
+ :rtype: ``str``
+
+ :return: Instance of the private network
+ :rtype: ``dict``
+ """
+
+ response = self.connection.request(
+ action='/private_networks/%s/servers/%s' % (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
+ :rtype: ``str``
+
+ :param thresholds: Thresholds for the monitoring policy
+ :rtype: ``dict``
+ {
+ "cpu":{
+ "warning":{
+ "value":90,
+ "alert":false
+ },
+ "critical":{
+ "value":95,
+ "alert":false
+ }
+ },
+ "ram":{
+ "warning":{
+ "value":90,
+ "alert":false
+ },
+ "critical":{
+ "value":95,
+ "alert":false
+ }
+ },
+ "disk":{
+ "warning":{
+ "value":80,
+ "alert":false
+ },
+ "critical":{
+ "value":90,
+ "alert":false
+ }
+ },
+ "transfer":{
+ "warning":{
+ "value":1000,
+ "alert":false
+ },
+ "critical":{
+ "value":2000,
+ "alert":false
+ }
+ },
+ "internal_ping":{
+ "warning":{
+ "value":50,
+ "alert":false
+ },
+ "critical":{
+ "value":100,
+ "alert":false
+ }
+ }
+ }
+ :param ports: Monitoring policies for ports
+ :rtype: ``dict``
+ [
+ {
+ "protocol":"TCP",
+ "port":"22",
+ "alert_if":"RESPONDING",
+ "email_notification":true
+ }
+ ]
+
+
+ :param processes: Processes to be monitored
+ :rtype: ``dict``
+ [
+ {
+ "process":"test",
+ "alert_if":"NOT_RUNNING",
+ "email_notification":true
+ }
+ ]
+
+ :param description: Description for the monitoring policy
+ :rtype: ``str``
+
+ :param email: Email for notifications
+ :rtype: ``str``
+
+ :param agent: Indicates if agent application will be installed
+ :rtype: ``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
+ :rtype: ``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
+ :param email: Email to send notifications to
+ :rtype: ``str``
+
+ :param thresholds: Thresholds for the monitoring policy
+ :rtype: ``dict``
+
+ :param name: Name of the monitoring policy
+ :rtype: ``str``
+
+ :param description: Description of the monitoring policy
+ :rtype: ``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
+ :rtype: ``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
+
+ :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
+ :rtype: ``str``
+
+ :param port_id: Id of the port
+ :rtype: ``str``
+
+ :return: Instance of a monitoring policy
+ :rtype: ``dict``
+ """
+
+ response = self.connection.request(
+ action='monitoring_policies/%s/ports/%s' % (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
+ :rtype: ``str``
+
+ :param port_id: Id of the port
+ :rtype: ``str``
+
+ :return: Instance of a monitoring policy
+ :rtype: ``dict``
+ """
+
+ response = self.connection.request(
+ action='monitoring_policies/%s/ports/%s' % (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
+ :rtype: ``str``
+
+ :param ports: List of ports
+ :rtype: ``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
+
+ :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
+ :rtype: ``str``
+
+ :param process_id: Id of the process
+ :rtype: ``str``
+
+ :return: Instance of a monitoring policy
+ :rtype: ``dict``
+ """
+
+ response = self.connection.request(
+ action='monitoring_policies/%s/processes/%s'
+ % (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
+ :rtype: ``str``
+
+ :param process_id: Id of the process
+ :rtype: ``str``
+
+ :return: Instance of a monitoring policy
+ :rtype: ``dict``
+ """
+
+ response = self.connection.request(
+ action='monitoring_policies/%s/processes/%s'
+ % (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
+ :rtype: ``str``
+
+ :param processes: List of processes
+ :rtype: ``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
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param servers: List of server ID
+ :rtype: ``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
+ :rtype: ``str``
+
+ :param server_id: Id of the server
+ :rtype: ``str``
+
+ :return: Instance of a monitoring policy
+ :rtype: ``dict``
+ """
+ response = self.connection.request(
+ action='monitoring_policies/%s/servers/%s'
+ % (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):
+ """
+ Convert into NodeSize
+ """
+ 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')
+
+ pass
+
+ def _list_fixed_instances(self):
+ response = self.connection.request(
+ action='/servers/fixed_instance_sizes',
+ method='GET'
+ )
+
+ return response.object
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/libcloud/compute/providers.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/providers.py b/libcloud/compute/providers.py
index 2d5127e..df983e9 100644
--- a/libcloud/compute/providers.py
+++ b/libcloud/compute/providers.py
@@ -143,6 +143,8 @@ DRIVERS = {
('libcloud.compute.drivers.ecs', 'ECSDriver'),
Provider.CLOUDSCALE:
('libcloud.compute.drivers.cloudscale', 'CloudscaleNodeDriver'),
+ Provider.ONEANDONE:
+ ('libcloud.compute.drivers.oneandone', 'OneAndOneNodeDriver'),
}
http://git-wip-us.apache.org/repos/asf/libcloud/blob/ff028ae2/libcloud/compute/types.py
----------------------------------------------------------------------
diff --git a/libcloud/compute/types.py b/libcloud/compute/types.py
index 646725d..d57cc91 100644
--- a/libcloud/compute/types.py
+++ b/libcloud/compute/types.py
@@ -144,6 +144,7 @@ class Provider(Type):
NIMBUS = 'nimbus'
NINEFOLD = 'ninefold'
NTTA = 'ntta'
+ ONEANDONE = 'oneandone'
OPENNEBULA = 'opennebula'
OPENSTACK = 'openstack'
OPSOURCE = 'opsource'