Merge lp:~daniel-thewatkins/cloud-init/fix-gce-az into lp:~cloud-init-dev/cloud-init/trunk

Proposed by Dan Watkins on 2015-07-06
Status: Merged
Approved by: Scott Moser on 2015-07-20
Approved revision: no longer in the source branch.
Merged at revision: 1121
Proposed branch: lp:~daniel-thewatkins/cloud-init/fix-gce-az
Merge into: lp:~cloud-init-dev/cloud-init/trunk
Diff against target: 158 lines (+23/-37)
2 files modified
cloudinit/sources/DataSourceGCE.py (+4/-0)
tests/unittests/test_datasource/test_gce.py (+19/-37)
To merge this branch: bzr merge lp:~daniel-thewatkins/cloud-init/fix-gce-az
Reviewer Review Type Date Requested Status
cloud-init commiters 2015-07-06 Pending
Review via email: mp+263907@code.launchpad.net

Description of the Change

GCE returns a string like "projects/123456789/zones/us-central1-a" as availability zone, which isn't very useful for us. This normalises that to a sensible value.

To post a comment you must log in.
1119. By Scott Moser on 2015-07-10

Fix regressed logic causing rightscale userdata to no longer work.

Change the logic for user data handling back to the original intent. A style
change also modified the logic of the user data handling leading to user data
being ignored even if it exists.

1120. By Scott Moser on 2015-07-16

CloudSigma: encode/decode data before communicating over the serial channel

this fixes the cloudsigma datasource when used with python3.

1121. By Dan Watkins on 2015-07-20

Return a sensible value for DataSourceGCE.availability_zone.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'cloudinit/sources/DataSourceGCE.py'
2--- cloudinit/sources/DataSourceGCE.py 2015-04-20 14:24:22 +0000
3+++ cloudinit/sources/DataSourceGCE.py 2015-07-06 14:37:59 +0000
4@@ -116,6 +116,10 @@
5 lines = self.metadata['public-keys'].splitlines()
6 self.metadata['public-keys'] = [self._trim_key(k) for k in lines]
7
8+ if self.metadata['availability-zone']:
9+ self.metadata['availability-zone'] = self.metadata[
10+ 'availability-zone'].split('/')[-1]
11+
12 encoding = self.metadata.get('user-data-encoding')
13 if encoding:
14 if encoding == 'base64':
15
16=== modified file 'tests/unittests/test_datasource/test_gce.py'
17--- tests/unittests/test_datasource/test_gce.py 2015-04-20 14:24:22 +0000
18+++ tests/unittests/test_datasource/test_gce.py 2015-07-06 14:37:59 +0000
19@@ -55,8 +55,8 @@
20 r'http://metadata.google.internal./computeMetadata/v1/.*')
21
22
23-def _new_request_callback(gce_meta=None):
24- if not gce_meta:
25+def _set_mock_metadata(gce_meta=None):
26+ if gce_meta is None:
27 gce_meta = GCE_META
28
29 def _request_callback(method, uri, headers):
30@@ -70,9 +70,10 @@
31 else:
32 return (404, headers, '')
33
34- return _request_callback
35-
36-
37+ httpretty.register_uri(httpretty.GET, MD_URL_RE, body=_request_callback)
38+
39+
40+@httpretty.activate
41 class TestDataSourceGCE(test_helpers.HttprettyTestCase):
42
43 def setUp(self):
44@@ -81,23 +82,16 @@
45 helpers.Paths({}))
46 super(TestDataSourceGCE, self).setUp()
47
48- @httpretty.activate
49 def test_connection(self):
50- httpretty.register_uri(
51- httpretty.GET, MD_URL_RE,
52- body=_new_request_callback())
53-
54+ _set_mock_metadata()
55 success = self.ds.get_data()
56 self.assertTrue(success)
57
58 req_header = httpretty.last_request().headers
59 self.assertDictContainsSubset(HEADERS, req_header)
60
61- @httpretty.activate
62 def test_metadata(self):
63- httpretty.register_uri(
64- httpretty.GET, MD_URL_RE,
65- body=_new_request_callback())
66+ _set_mock_metadata()
67 self.ds.get_data()
68
69 shostname = GCE_META.get('instance/hostname').split('.')[0]
70@@ -107,18 +101,12 @@
71 self.assertEqual(GCE_META.get('instance/id'),
72 self.ds.get_instance_id())
73
74- self.assertEqual(GCE_META.get('instance/zone'),
75- self.ds.availability_zone)
76-
77 self.assertEqual(GCE_META.get('instance/attributes/user-data'),
78 self.ds.get_userdata_raw())
79
80 # test partial metadata (missing user-data in particular)
81- @httpretty.activate
82 def test_metadata_partial(self):
83- httpretty.register_uri(
84- httpretty.GET, MD_URL_RE,
85- body=_new_request_callback(GCE_META_PARTIAL))
86+ _set_mock_metadata(GCE_META_PARTIAL)
87 self.ds.get_data()
88
89 self.assertEqual(GCE_META_PARTIAL.get('instance/id'),
90@@ -127,58 +115,52 @@
91 shostname = GCE_META_PARTIAL.get('instance/hostname').split('.')[0]
92 self.assertEqual(shostname, self.ds.get_hostname())
93
94- @httpretty.activate
95 def test_metadata_encoding(self):
96- httpretty.register_uri(
97- httpretty.GET, MD_URL_RE,
98- body=_new_request_callback(GCE_META_ENCODING))
99+ _set_mock_metadata(GCE_META_ENCODING)
100 self.ds.get_data()
101
102 decoded = b64decode(
103 GCE_META_ENCODING.get('instance/attributes/user-data'))
104 self.assertEqual(decoded, self.ds.get_userdata_raw())
105
106- @httpretty.activate
107 def test_missing_required_keys_return_false(self):
108 for required_key in ['instance/id', 'instance/zone',
109 'instance/hostname']:
110 meta = GCE_META_PARTIAL.copy()
111 del meta[required_key]
112- httpretty.register_uri(httpretty.GET, MD_URL_RE,
113- body=_new_request_callback(meta))
114+ _set_mock_metadata(meta)
115 self.assertEqual(False, self.ds.get_data())
116 httpretty.reset()
117
118- @httpretty.activate
119 def test_project_level_ssh_keys_are_used(self):
120- httpretty.register_uri(httpretty.GET, MD_URL_RE,
121- body=_new_request_callback())
122+ _set_mock_metadata()
123 self.ds.get_data()
124
125 # we expect a list of public ssh keys with user names stripped
126 self.assertEqual(['ssh-rsa AA2..+aRD0fyVw== root@server'],
127 self.ds.get_public_ssh_keys())
128
129- @httpretty.activate
130 def test_instance_level_ssh_keys_are_used(self):
131 key_content = 'ssh-rsa JustAUser root@server'
132 meta = GCE_META.copy()
133 meta['instance/attributes/sshKeys'] = 'user:{0}'.format(key_content)
134
135- httpretty.register_uri(httpretty.GET, MD_URL_RE,
136- body=_new_request_callback(meta))
137+ _set_mock_metadata(meta)
138 self.ds.get_data()
139
140 self.assertIn(key_content, self.ds.get_public_ssh_keys())
141
142- @httpretty.activate
143 def test_instance_level_keys_replace_project_level_keys(self):
144 key_content = 'ssh-rsa JustAUser root@server'
145 meta = GCE_META.copy()
146 meta['instance/attributes/sshKeys'] = 'user:{0}'.format(key_content)
147
148- httpretty.register_uri(httpretty.GET, MD_URL_RE,
149- body=_new_request_callback(meta))
150+ _set_mock_metadata(meta)
151 self.ds.get_data()
152
153 self.assertEqual([key_content], self.ds.get_public_ssh_keys())
154+
155+ def test_only_last_part_of_zone_used_for_availability_zone(self):
156+ _set_mock_metadata()
157+ self.ds.get_data()
158+ self.assertEqual('bar', self.ds.availability_zone)