Skip to content
Merged
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
8 changes: 7 additions & 1 deletion CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ Compute
(#2135)
[Steve Kowalik - @s-t-e-v-e-n-k]

- [Azure ARM] Fix ``create_node`` failing with a JSON serialization error when
``ex_customdata`` is provided. The base64 encoded custom data is now decoded
to a ``str`` and both ``str`` and ``bytes`` inputs are accepted.
(GITHUB-1893)
[Sanjay Santhanam - @Sanjays2402]

- [UpCloud]

Add new functions to complete the Upcloud driver and move it to the
last API version 1.3
(#2152)
(#2147)
[Miguel Caballer - @micafer]

Changes in Apache Libcloud 3.9.1
Expand Down
8 changes: 6 additions & 2 deletions libcloud/compute/drivers/azure_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -609,7 +609,7 @@ def create_node(
be placed in the file /var/lib/waagent/CustomData
https://azure.microsoft.com/en-us/documentation/ \
articles/virtual-machines-how-to-inject-custom-data/
:type ex_customdata: ``str``
:type ex_customdata: ``str`` or ``bytes``

:param ex_use_managed_disks: Enable this feature to have Azure
automatically manage the availability of disks to provide data
Expand Down Expand Up @@ -741,7 +741,11 @@ def create_node(
data["properties"]["storageProfile"]["osDisk"].update({"diskSizeGB": ex_disk_size})

if ex_customdata:
data["properties"]["osProfile"]["customData"] = base64.b64encode(ex_customdata)
if isinstance(ex_customdata, str):
ex_customdata = ex_customdata.encode("utf-8")
data["properties"]["osProfile"]["customData"] = base64.b64encode(ex_customdata).decode(
"utf-8"
)

data["properties"]["osProfile"]["adminUsername"] = ex_user_name

Expand Down
51 changes: 51 additions & 0 deletions libcloud/test/compute/test_azure_arm.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import sys
import json
import base64
import functools
from datetime import datetime
from unittest import mock
Expand Down Expand Up @@ -232,6 +233,56 @@ def test_create_node_ex_disk_size(self):
},
)

def test_create_node_ex_customdata(self):
location = NodeLocation("any_location", "", "", self.driver)
size = NodeSize("any_size", "", 0, 0, 0, 0, driver=self.driver)
image = AzureImage("1", "1", "ubuntu", "pub", location.id, self.driver)
auth = NodeAuthPassword("any_password")

customdata = "#!/bin/bash\necho hello"
expected = base64.b64encode(customdata.encode("utf-8")).decode("utf-8")

# ex_customdata provided as a str
node = self.driver.create_node(
"test-node-1",
size,
image,
auth,
location=location,
ex_resource_group="000000",
ex_storage_account="000000",
ex_user_name="any_user",
ex_network="000000",
ex_subnet="000000",
ex_use_managed_disks=True,
ex_customdata=customdata,
)
os_profile = node.extra["properties"]["osProfile"]
self.assertEqual(os_profile["customData"], expected)
# customData must be a JSON-serializable str, not bytes
self.assertIsInstance(os_profile["customData"], str)
json.dumps(node.extra["properties"])

# ex_customdata provided as bytes (regression for GH #1893)
node = self.driver.create_node(
"test-node-1",
size,
image,
auth,
location=location,
ex_resource_group="000000",
ex_storage_account="000000",
ex_user_name="any_user",
ex_network="000000",
ex_subnet="000000",
ex_use_managed_disks=True,
ex_customdata=customdata.encode("utf-8"),
)
os_profile = node.extra["properties"]["osProfile"]
self.assertEqual(os_profile["customData"], expected)
self.assertIsInstance(os_profile["customData"], str)
json.dumps(node.extra["properties"])

def test_create_node_ex_os_disk_delete(self):
location = NodeLocation("any_location", "", "", self.driver)
size = NodeSize("any_size", "", 0, 0, 0, 0, driver=self.driver)
Expand Down