libcloud-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From anthonys...@apache.org
Subject [04/11] libcloud git commit: 1&1 Compute Driver
Date Tue, 11 Apr 2017 00:23:58 GMT
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 <jasmin@stackpointcloud.com>
Authored: Tue Apr 11 00:19:46 2017 +0200
Committer: jasminSPC <jasmin@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'


Mime
View raw message