Merge ~smoser/cloud-init:bug/1619394 into cloud-init:master

Proposed by Scott Moser
Status: Merged
Merged at revision: 2aa9b1ddf80ffe7d35e8437c59670856d612e64e
Proposed branch: ~smoser/cloud-init:bug/1619394
Merge into: cloud-init:master
Diff against target: 123 lines (+87/-4)
2 files modified
cloudinit/sources/DataSourceOVF.py (+4/-4)
tests/unittests/test_datasource/test_ovf.py (+83/-0)
Reviewer Review Type Date Requested Status
cloud-init Commiters Pending
Review via email: mp+305496@code.launchpad.net
To post a comment you must log in.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1diff --git a/cloudinit/sources/DataSourceOVF.py b/cloudinit/sources/DataSourceOVF.py
2index 43347cf..5b3bdb4 100644
3--- a/cloudinit/sources/DataSourceOVF.py
4+++ b/cloudinit/sources/DataSourceOVF.py
5@@ -237,7 +237,7 @@ def wait_for_imc_cfg_file(dirpath, filename, maxwait=180, naplen=5):
6 def read_vmware_imc(config):
7 md = {}
8 cfg = {}
9- ud = ""
10+ ud = None
11 if config.host_name:
12 if config.domain_name:
13 md['local-hostname'] = config.host_name + "." + config.domain_name
14@@ -256,7 +256,7 @@ def read_ovf_environment(contents):
15 props = get_properties(contents)
16 md = {}
17 cfg = {}
18- ud = ""
19+ ud = None
20 cfg_props = ['password']
21 md_props = ['seedfrom', 'local-hostname', 'public-keys', 'instance-id']
22 for (prop, val) in props.items():
23@@ -268,9 +268,9 @@ def read_ovf_environment(contents):
24 cfg[prop] = val
25 elif prop == "user-data":
26 try:
27- ud = base64.decodestring(val)
28+ ud = base64.b64decode(val.encode())
29 except Exception:
30- ud = val
31+ ud = val.encode()
32 return (md, ud, cfg)
33
34
35diff --git a/tests/unittests/test_datasource/test_ovf.py b/tests/unittests/test_datasource/test_ovf.py
36new file mode 100644
37index 0000000..5f8e7e4
38--- /dev/null
39+++ b/tests/unittests/test_datasource/test_ovf.py
40@@ -0,0 +1,83 @@
41+# vi: ts=4 expandtab
42+#
43+# Copyright (C) 2016 Canonical Ltd.
44+#
45+# Author: Scott Moser <scott.moser@canonical.com>
46+#
47+# This program is free software: you can redistribute it and/or modify
48+# it under the terms of the GNU General Public License version 3, as
49+# published by the Free Software Foundation.
50+#
51+# This program is distributed in the hope that it will be useful,
52+# but WITHOUT ANY WARRANTY; without even the implied warranty of
53+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
54+# GNU General Public License for more details.
55+#
56+# You should have received a copy of the GNU General Public License
57+# along with this program. If not, see <http://www.gnu.org/licenses/>.
58+
59+import base64
60+
61+from .. import helpers as test_helpers
62+
63+from cloudinit.sources import DataSourceOVF as dsovf
64+
65+OVF_ENV_CONTENT = """<?xml version="1.0" encoding="UTF-8"?>
66+<Environment xmlns="http://schemas.dmtf.org/ovf/environment/1"
67+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
68+ xmlns:oe="http://schemas.dmtf.org/ovf/environment/1"
69+ xsi:schemaLocation="http://schemas.dmtf.org/ovf/environment/1 ../dsp8027.xsd"
70+ oe:id="WebTier">
71+ <!-- Information about hypervisor platform -->
72+ <oe:PlatformSection>
73+ <Kind>ESX Server</Kind>
74+ <Version>3.0.1</Version>
75+ <Vendor>VMware, Inc.</Vendor>
76+ <Locale>en_US</Locale>
77+ </oe:PlatformSection>
78+ <!--- Properties defined for this virtual machine -->
79+ <PropertySection>
80+{properties}
81+ </PropertySection>
82+</Environment>
83+"""
84+
85+
86+def fill_properties(props, template=OVF_ENV_CONTENT):
87+ lines = []
88+ prop_tmpl = '<Property oe:key="{key}" oe:value="{val}"/>'
89+ for key, val in props.items():
90+ lines.append(prop_tmpl.format(key=key, val=val))
91+ indent = " "
92+ properties = ''.join([indent + l + "\n" for l in lines])
93+ return template.format(properties=properties)
94+
95+
96+class TestReadOvfEnv(test_helpers.TestCase):
97+ def test_with_b64_userdata(self):
98+ user_data = "#!/bin/sh\necho hello world\n"
99+ user_data_b64 = base64.b64encode(user_data.encode()).decode()
100+ props = {"user-data": user_data_b64, "password": "passw0rd",
101+ "instance-id": "inst-001"}
102+ env = fill_properties(props)
103+ md, ud, cfg = dsovf.read_ovf_environment(env)
104+ self.assertEqual({"instance-id": "inst-001"}, md)
105+ self.assertEqual(user_data.encode(), ud)
106+ self.assertEqual({'password': "passw0rd"}, cfg)
107+
108+ def test_with_non_b64_userdata(self):
109+ user_data = "my-user-data"
110+ props = {"user-data": user_data, "instance-id": "inst-001"}
111+ env = fill_properties(props)
112+ md, ud, cfg = dsovf.read_ovf_environment(env)
113+ self.assertEqual({"instance-id": "inst-001"}, md)
114+ self.assertEqual(user_data.encode(), ud)
115+ self.assertEqual({}, cfg)
116+
117+ def test_with_no_userdata(self):
118+ props = {"password": "passw0rd", "instance-id": "inst-001"}
119+ env = fill_properties(props)
120+ md, ud, cfg = dsovf.read_ovf_environment(env)
121+ self.assertEqual({"instance-id": "inst-001"}, md)
122+ self.assertEqual({'password': "passw0rd"}, cfg)
123+ self.assertEqual(None, ud)

Subscribers

People subscribed via source and target branches