Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 40 additions & 2 deletions docs/compute/drivers/upcloud.rst
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,53 @@ UpCloud currently operates globally from eight (8) data centers:
* San Jose, USA
* Singapore, Singapore

This driver uses the UpCloud API 1.3 endpoints.

Firewall rules
--------------

UpCloud manages network access through per-server firewall rules instead of
reusable security groups. The driver exposes those rules through extension
methods:

* ``ex_list_firewall_rules(node)``
* ``ex_get_firewall_rule(node, position)``
* ``ex_create_firewall_rule(node, rule)``
* ``ex_create_firewall_rules(node, rules)``
* ``ex_delete_firewall_rule(node, position)``

Instantiating a driver
----------------------

When you instantiate a driver you need to pass the following arguments to the
driver constructor:
When you instantiate a driver you can authenticate with an API bearer token:

* ``token`` - Your UpCloud API bearer token

For example:

.. code-block:: python

from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

cls = get_driver(Provider.UPCLOUD)
driver = cls(token="ucat_...")

You can also use basic authentication with an API enabled user:

* ``username`` - Your API access enabled users username
* ``password`` - Your API access enabled users password

For example:

.. code-block:: python

from libcloud.compute.types import Provider
from libcloud.compute.providers import get_driver

cls = get_driver(Provider.UPCLOUD)
driver = cls("username", "password")

Enabling API access
-------------------

Expand Down
34 changes: 30 additions & 4 deletions libcloud/common/upcloud.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,15 @@ class UpcloudCreateNodeRequestBody:
:param ex_username: User's username, which is created.
Default is 'root'. (optional)
:type ex_username: ``str``

:param ex_storage_devices: Additional UpCloud storage_device dictionaries.
(optional)
:type ex_storage_devices: ``list`` of ``dict``

:param ex_metadata: Whether to enable the UpCloud metadata service,
``"yes"`` or ``"no"``. Cloud-init templates require
this to be enabled. (optional)
:type ex_metadata: ``str``
"""

def __init__(
Expand All @@ -63,17 +72,25 @@ def __init__(
auth=None,
ex_hostname="localhost",
ex_username="root",
ex_storage_devices=None,
ex_metadata=None,
):
storage_devices = _StorageDevice(image, size).to_dict()
if ex_storage_devices:
storage_devices["storage_device"].extend(ex_storage_devices)

self.body = {
"server": {
"title": name,
"hostname": ex_hostname,
"plan": size.id,
"zone": location.id,
"login_user": _LoginUser(ex_username, auth).to_dict(),
"storage_devices": _StorageDevice(image, size).to_dict(),
"storage_devices": storage_devices,
}
}
if ex_metadata is not None:
self.body["server"]["metadata"] = ex_metadata

def to_json(self):
"""
Expand Down Expand Up @@ -169,9 +186,18 @@ def stop_node(self, node_id):
"""
body = {"stop_server": {"stop_type": "hard"}}
self.connection.request(
"1.2/server/{}/stop".format(node_id), method="POST", data=json.dumps(body)
"1.3/server/{}/stop".format(node_id), method="POST", data=json.dumps(body)
)

def start_node(self, node_id):
"""
Starts the node

:param node_id: Id of the Node
:type node_id: ``int``
"""
self.connection.request("1.3/server/{}/start".format(node_id), method="POST")

def get_node_state(self, node_id):
"""
Get the state of the node.
Expand All @@ -182,7 +208,7 @@ def get_node_state(self, node_id):
:rtype: ``str``
"""

action = "1.2/server/{}".format(node_id)
action = "1.3/server/{}".format(node_id)
try:
response = self.connection.request(action)
return response.object["server"]["state"]
Expand All @@ -198,7 +224,7 @@ def destroy_node(self, node_id):
:param node_id: Id of the Node
:type node_id: ``int``
"""
self.connection.request("1.2/server/{}".format(node_id), method="DELETE")
self.connection.request("1.3/server/{}".format(node_id), method="DELETE")


class PlanPrice:
Expand Down
Loading
Loading