diff options
| author | Scott Moser <smoser@brickies.net> | 2020-06-22 14:44:37 -0400 | 
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-06-22 14:44:37 -0400 | 
| commit | 76652f3e07b6f659b2fd166a6619cb427dc6bc7e (patch) | |
| tree | 75a6d70ac0aaae5a4cc766661fca742b599ee663 /cloudinit/sources/helpers | |
| parent | 055731eade79d4121d1005469765207e425ac343 (diff) | |
| download | vyos-cloud-init-76652f3e07b6f659b2fd166a6619cb427dc6bc7e.tar.gz vyos-cloud-init-76652f3e07b6f659b2fd166a6619cb427dc6bc7e.zip | |
Hetzner: support reading user-data that is base64 encoded. (#448)
Hetzner cloud only supports user-data as a string (presumably utf-8).
In order to allow users on Hetzner to provide binary data to cloud-init,
we will attempt to base64decode the userdata.
The change here adds a 'maybe_b64decode' function that will decode data
if and only if is base64 encoded.
The reason for not using util.b64d is that we do not want the return value
decoded to a string, and util.b64d will do that if it can.  Additionally
we call decode with validate=True which oddly is not the default.
LP: #1884071
Diffstat (limited to 'cloudinit/sources/helpers')
| -rw-r--r-- | cloudinit/sources/helpers/hetzner.py | 19 | 
1 files changed, 19 insertions, 0 deletions
| diff --git a/cloudinit/sources/helpers/hetzner.py b/cloudinit/sources/helpers/hetzner.py index 2554530d..72edb023 100644 --- a/cloudinit/sources/helpers/hetzner.py +++ b/cloudinit/sources/helpers/hetzner.py @@ -7,6 +7,9 @@ from cloudinit import log as logging  from cloudinit import url_helper  from cloudinit import util +import base64 +import binascii +  LOG = logging.getLogger(__name__) @@ -24,3 +27,19 @@ def read_userdata(url, timeout=2, sec_between=2, retries=30):      if not response.ok():          raise RuntimeError("unable to read userdata at %s" % url)      return response.contents + + +def maybe_b64decode(data: bytes) -> bytes: +    """base64 decode data + +    If data is base64 encoded bytes, return b64decode(data). +    If not, return data unmodified. + +    @param data: data as bytes. TypeError is raised if not bytes. +    """ +    if not isinstance(data, bytes): +        raise TypeError("data is '%s', expected bytes" % type(data)) +    try: +        return base64.b64decode(data, validate=True) +    except binascii.Error: +        return data | 
