-
Notifications
You must be signed in to change notification settings - Fork 924
Updated Linode (Akamai Connected Cloud) support (including cloud-init) #1946
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -37,6 +37,7 @@ | |
from libcloud.utils.py3 import httplib | ||
from libcloud.compute.base import ( | ||
Node, | ||
KeyPair, | ||
NodeSize, | ||
NodeImage, | ||
NodeDriver, | ||
|
@@ -861,6 +862,33 @@ def list_images(self): | |
data = self._paginated_request("/v4/images", "data") | ||
return [self._to_image(obj) for obj in data] | ||
|
||
def create_key_pair(self, name, public_key=""): | ||
""" | ||
Creates an SSH keypair | ||
|
||
:param name: The name to be given to the keypair (required).\ | ||
:type name: `str` | ||
|
||
:keyword public_key: Contents of the public key the the SSH key pair | ||
:type public_key: `str` | ||
|
||
:rtype: :class: `KeyPair` | ||
""" | ||
attr = {"label": name, "ssh_key": public_key} | ||
response = self.connection.request( | ||
"/v4/profile/sshkeys", data=json.dumps(attr), method="POST" | ||
).object | ||
return self._to_key_pair(response) | ||
|
||
def list_key_pairs(self): | ||
""" | ||
Provide a list of all the SSH keypairs in your account. | ||
|
||
:rtype: ``list`` of :class: `KeyPair` | ||
""" | ||
data = self._paginated_request("/v4/profile/sshkeys", "data") | ||
return [self._to_key_pair(obj) for obj in data] | ||
|
||
def list_locations(self): | ||
""" | ||
Lists the Regions available for Linode services | ||
|
@@ -945,15 +973,28 @@ def reboot_node(self, node): | |
def create_node( | ||
self, | ||
location, | ||
size, | ||
image=None, | ||
name=None, | ||
# Previously, the following 3 parameters did not match the rest of the libcloud | ||
# codebase drivers. They should be in the same order as other compute drivers. | ||
# Previously, it looked like this: | ||
# size, | ||
# image=None, | ||
# name=None, | ||
# | ||
# Comments welcome on how backwards compatibility (if any) should work here. | ||
# Since it was not compatible with other drivers, it is not clear to me if this | ||
# would break anyone's codebase if they were not using any other libcloud drivers | ||
# to other cloud providers in the first place. If they were not, that seems to | ||
# kind of defeat the purpose of using libcloud. | ||
name, # Can be None | ||
size, # Can be None | ||
image, # Can be None | ||
root_pass=None, | ||
ex_authorized_keys=None, | ||
ex_authorized_users=None, | ||
ex_tags=None, | ||
ex_backups_enabled=False, | ||
ex_private_ip=False, | ||
ex_userdata=False, | ||
): | ||
"""Creates a Linode Instance. | ||
In order for this request to complete successfully, | ||
|
@@ -997,6 +1038,12 @@ def create_node( | |
:keyword ex_private_ip: whether or not to request a private IP | ||
:type ex_private_ip: ``bool`` | ||
|
||
:keyword ex_userdata: add cloud-config compatible userdata to be | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it would actually be better to let user pass in a raw string and then we can take care of base64 encoding the string inside the method ourselves. This way the method abstracts away this implementation detail from the end user (we already do a similar thing in a bunch of places). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @Dorthu Would you like me to make that change? ^^^ There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I agree that it would be more convenient for the library to handle the encoding, especially if there's precedent elsewhere in libcloud, as long as that behavior is featured prominently in the documentation. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Will do! Thanks guys. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
processed by cloud-init inside the Linode instance. NOTE: the | ||
contents of this string must be base64 encoded before passing | ||
it to this function. | ||
:type ex_userdata: ``str`` | ||
|
||
:return: Node representing the newly-created node | ||
:rtype: :class:`Node` | ||
""" | ||
|
@@ -1014,6 +1061,9 @@ def create_node( | |
"backups_enabled": ex_backups_enabled, | ||
} | ||
|
||
if ex_userdata: | ||
attr["metadata"] = {"user_data": binascii.b2a_base64(bytes(ex_userdata.encode("utf-8"))).decode("ascii").strip()} | ||
|
||
if image is not None: | ||
if root_pass is None: | ||
raise LinodeExceptionV4("root password required " "when providing an image") | ||
|
@@ -1369,6 +1419,18 @@ def ex_get_volume(self, volume_id): | |
response = self.connection.request("/v4/volumes/%s" % volume_id).object | ||
return self._to_volume(response) | ||
|
||
def get_image(self, image): | ||
""" | ||
Lookup a Linode image | ||
|
||
:param image: The name to image to be looked up (required).\ | ||
:type name: `str` | ||
|
||
:rtype: :class: `NodeImage` | ||
""" | ||
response = self.connection.request("/v4/images/%s" % image, method="GET") | ||
return self._to_image(response.object) | ||
|
||
def create_image(self, disk, name=None, description=None): | ||
"""Creates a private image from a LinodeDisk. | ||
Images are limited to three per account. | ||
|
@@ -1554,6 +1616,18 @@ def ex_rename_node(self, node, name): | |
|
||
return self._to_node(response) | ||
|
||
def _to_key_pair(self, data): | ||
extra = {"id": data["id"]} | ||
|
||
return KeyPair( | ||
name=data["label"], | ||
fingerprint=None, | ||
public_key=data["ssh_key"], | ||
private_key=None, | ||
driver=self, | ||
extra=extra, | ||
) | ||
|
||
def _to_node(self, data): | ||
extra = { | ||
"tags": data["tags"], | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
{ | ||
"created": "2018-01-01T00:01:01", | ||
"id": 42, | ||
"label": "My SSH Key", | ||
"ssh_key": "ssh-rsa AAAA_valid_public_ssh_key_123456785== user@their-computer" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
{ | ||
"data": [ | ||
{ | ||
"created": "2018-01-01T00:01:01", | ||
"id": 42, | ||
"label": "My SSH Key", | ||
"ssh_key": "ssh-rsa AAAA_valid_public_ssh_key_123456785== user@their-computer" | ||
} | ||
], | ||
"page": 1, | ||
"pages": 1, | ||
"results": 1 | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's fine to leave it as-in and document this backward incompatible / breaking change in the upgrade notes file (https://github.com/apache/libcloud/blob/trunk/docs/upgrade_notes.rst), ideally with some concrete before / after code examples.