Merge lp:~therve/landscape-client/juju-env-info into lp:~landscape/landscape-client/trunk

Proposed by Thomas Herve
Status: Merged
Merged at revision: 606
Proposed branch: lp:~therve/landscape-client/juju-env-info
Merge into: lp:~landscape/landscape-client/trunk
Diff against target: 310 lines (+91/-68)
3 files modified
landscape/broker/registration.py (+25/-24)
landscape/broker/tests/test_registration.py (+53/-23)
landscape/message_schemas.py (+13/-21)
To merge this branch: bzr merge lp:~therve/landscape-client/juju-env-info
Reviewer Review Type Date Requested Status
Björn Tillenius (community) Approve
Chris Glass (community) Approve
Review via email: mp+143452@code.launchpad.net

Description of the change

The branch adds a new registration fields populated with the content of a file in the data path. I'm not super happy about it yet, but it feels it does the job.

To post a comment you must log in.
Revision history for this message
Chris Glass (tribaal) wrote :

Looks good, +1!

I hope goju will provide an API instead, it would feel "cleaner", but this will do nicely until then :)

review: Approve
Revision history for this message
Björn Tillenius (bjornt) wrote :

I think it's good enough, so I'm giving it a +1. As mentioned on IRC, I'd rather
see each key and value go in the message itself, rather than sending the JSON
blob. I'm not sure how easy it would be to extend our schema to be more flexible,
though. This is one way of allowing a schema to contain any number of optional
keys, but not a very pretty one.

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'landscape/broker/registration.py'
2--- landscape/broker/registration.py 2012-05-17 20:59:23 +0000
3+++ landscape/broker/registration.py 2013-01-16 08:32:22 +0000
4@@ -1,3 +1,4 @@
5+import os
6 import time
7 import logging
8 import socket
9@@ -97,6 +98,7 @@
10 self._fetch_async = fetch_async
11 self._otp = None
12 self._ec2_data = None
13+ self.extra_data_path = os.path.join(self._config.data_path, "extra")
14
15 def should_register(self):
16 id = self._identity
17@@ -205,8 +207,8 @@
18 self._config.url = exchange_url
19 self._config.ping_url = ping_url
20 if "ssl-ca-certificate" in instance_data:
21- from landscape.configuration import \
22- store_public_key_data
23+ from landscape.configuration import (
24+ store_public_key_data)
25 public_key_file = store_public_key_data(
26 self._config, instance_data["ssl-ca-certificate"])
27 self._config.ssl_public_key = public_key_file
28@@ -253,16 +255,16 @@
29 tags = None
30 logging.error("Invalid tags provided for cloud "
31 "registration.")
32+ message = {"hostname": get_fqdn(),
33+ "vm-info": get_vm_info(),
34+ "tags": tags}
35 if self._config.cloud and self._ec2_data is not None:
36 if self._otp:
37 logging.info("Queueing message to register with OTP")
38- message = {"type": "register-cloud-vm",
39- "otp": self._otp,
40- "hostname": get_fqdn(),
41- "account_name": None,
42- "registration_password": None,
43- "tags": tags,
44- "vm-info": get_vm_info()}
45+ message.update({"type": "register-cloud-vm",
46+ "otp": self._otp,
47+ "account_name": None,
48+ "registration_password": None})
49 message.update(self._ec2_data)
50 self._exchange.send(message)
51 elif id.account_name:
52@@ -270,31 +272,30 @@
53 logging.info(
54 u"Queueing message to register with account %r %s"
55 u"as an EC2 instance." % (id.account_name, with_tags))
56- message = {"type": "register-cloud-vm",
57- "otp": None,
58- "hostname": get_fqdn(),
59- "account_name": id.account_name,
60- "registration_password": \
61- id.registration_key,
62- "tags": tags,
63- "vm-info": get_vm_info()}
64+ message.update({
65+ "type": "register-cloud-vm",
66+ "otp": None,
67+ "account_name": id.account_name,
68+ "registration_password": id.registration_key})
69 message.update(self._ec2_data)
70 self._exchange.send(message)
71 else:
72 self._reactor.fire("registration-failed")
73 elif id.account_name:
74+ if os.path.exists(self.extra_data_path):
75+ fd = file(self.extra_data_path)
76+ extra = fd.read()
77+ fd.close()
78+ message["extra"] = extra
79 with_word = ["without", "with"][bool(id.registration_key)]
80 with_tags = ["", u"and tags %s " % tags][bool(tags)]
81 logging.info(u"Queueing message to register with account %r %s"
82 "%s a password." % (id.account_name, with_tags,
83 with_word))
84- message = {"type": "register",
85- "computer_title": id.computer_title,
86- "account_name": id.account_name,
87- "registration_password": id.registration_key,
88- "hostname": get_fqdn(),
89- "tags": tags,
90- "vm-info": get_vm_info()}
91+ message.update({"type": "register",
92+ "computer_title": id.computer_title,
93+ "account_name": id.account_name,
94+ "registration_password": id.registration_key})
95 self._exchange.send(message)
96 elif self._config.provisioning_otp:
97 logging.info(u"Queueing message to register with OTP as a"
98
99=== modified file 'landscape/broker/tests/test_registration.py'
100--- landscape/broker/tests/test_registration.py 2012-05-17 20:59:23 +0000
101+++ landscape/broker/tests/test_registration.py 2013-01-16 08:32:22 +0000
102@@ -297,6 +297,35 @@
103 self.assertEqual(len(messages), 1)
104 self.assertEqual(messages[0]["type"], "register")
105
106+ def test_registration_with_extra_data(self):
107+ """
108+ The broker sends the content of the extra data file if present during
109+ registration.
110+ """
111+ extra_file = os.path.join(self.config.data_path, "extra")
112+ fd = file(extra_file, "wb")
113+ fd.write("data!\n")
114+ fd.close()
115+
116+ self.mstore.set_accepted_types(["register"])
117+ self.config.computer_title = "Computer Title"
118+ self.config.account_name = "account_name"
119+ self.config.registration_key = "SEKRET"
120+ self.reactor.fire("pre-exchange")
121+ self.assertMessages(
122+ self.mstore.get_pending_messages(),
123+ [{"type": "register",
124+ "computer_title": "Computer Title",
125+ "account_name": "account_name",
126+ "registration_password": "SEKRET",
127+ "hostname": "ooga.local",
128+ "tags": None,
129+ "extra": "data!\n",
130+ "vm-info": get_vm_info()}])
131+ self.assertEqual(self.logfile.getvalue().strip(),
132+ "INFO: Queueing message to register with account "
133+ "'account_name' with a password.")
134+
135 def test_no_message_when_should_register_is_false(self):
136 """If we already have a secure id, do not queue a register message.
137 """
138@@ -499,11 +528,11 @@
139 return user_data
140
141 def prepare_query_results(
142- self, user_data=None, instance_key="key1", launch_index=0,
143- local_hostname="ooga.local", public_hostname="ooga.amazon.com",
144- reservation_key=u"res1", ramdisk_key=u"ram1", kernel_key=u"kernel1",
145- image_key=u"image1", local_ip="10.0.0.1", public_ip="10.0.0.2",
146- ssl_ca_certificate=None):
147+ self, user_data=None, instance_key="key1", launch_index=0,
148+ local_hostname="ooga.local", public_hostname="ooga.amazon.com",
149+ reservation_key=u"res1", ramdisk_key=u"ram1",
150+ kernel_key=u"kernel1", image_key=u"image1", local_ip="10.0.0.1",
151+ public_ip="10.0.0.2", ssl_ca_certificate=None):
152 if user_data is None:
153 user_data = self.get_user_data(
154 ssl_ca_certificate=ssl_ca_certificate)
155@@ -512,18 +541,17 @@
156 api_base = "http://169.254.169.254/latest"
157 self.query_results.clear()
158 for url_suffix, value in [
159- ("/user-data", user_data),
160- ("/meta-data/instance-id", instance_key),
161- ("/meta-data/reservation-id", reservation_key),
162- ("/meta-data/local-hostname", local_hostname),
163- ("/meta-data/public-hostname", public_hostname),
164- ("/meta-data/ami-launch-index", str(launch_index)),
165- ("/meta-data/kernel-id", kernel_key),
166- ("/meta-data/ramdisk-id", ramdisk_key),
167- ("/meta-data/ami-id", image_key),
168- ("/meta-data/local-ipv4", local_ip),
169- ("/meta-data/public-ipv4", public_ip),
170- ]:
171+ ("/user-data", user_data),
172+ ("/meta-data/instance-id", instance_key),
173+ ("/meta-data/reservation-id", reservation_key),
174+ ("/meta-data/local-hostname", local_hostname),
175+ ("/meta-data/public-hostname", public_hostname),
176+ ("/meta-data/ami-launch-index", str(launch_index)),
177+ ("/meta-data/kernel-id", kernel_key),
178+ ("/meta-data/ramdisk-id", ramdisk_key),
179+ ("/meta-data/ami-id", image_key),
180+ ("/meta-data/local-ipv4", local_ip),
181+ ("/meta-data/public-ipv4", public_ip)]:
182 self.query_results[api_base + url_suffix] = value
183
184 def prepare_cloud_registration(self, account_name=None,
185@@ -664,7 +692,8 @@
186 If we have an SSL certificate CA included in the user-data, this should
187 be written out, and the configuration updated to reflect this.
188 """
189- key_filename = os.path.join(self.config.data_path,
190+ key_filename = os.path.join(
191+ self.config.data_path,
192 "%s.ssl_public_key" % os.path.basename(self.config_filename))
193
194 print_text_mock = self.mocker.replace(print_text)
195@@ -758,11 +787,12 @@
196 account_name=u"onward",
197 registration_password=u"password",
198 tags=u"london,server")])
199- self.assertEqual(self.logfile.getvalue().strip()[:-7],
200- "INFO: Queueing message to register with account u'onward' and "
201- "tags london,server as an EC2 instance.\n "
202- "INFO: Starting message exchange with http://localhost:91919.\n "
203- "INFO: Message exchange completed in")
204+ self.assertEqual(
205+ self.logfile.getvalue().strip()[:-7],
206+ "INFO: Queueing message to register with account u'onward' and "
207+ "tags london,server as an EC2 instance.\n "
208+ "INFO: Starting message exchange with http://localhost:91919.\n"
209+ " INFO: Message exchange completed in")
210
211 def test_queueing_cloud_registration_message_resets_message_store(self):
212 """
213
214=== modified file 'landscape/message_schemas.py'
215--- landscape/message_schemas.py 2013-01-15 09:15:51 +0000
216+++ landscape/message_schemas.py 2013-01-16 08:32:22 +0000
217@@ -104,21 +104,17 @@
218
219
220 LOAD_AVERAGE = Message("load-average", {
221- "load-averages": List(Tuple(Int(), Float())),
222- })
223+ "load-averages": List(Tuple(Int(), Float()))})
224
225 CPU_USAGE = Message("cpu-usage", {
226- "cpu-usages": List(Tuple(Int(), Float())),
227- })
228+ "cpu-usages": List(Tuple(Int(), Float()))})
229
230 CEPH_USAGE = Message("ceph-usage", {
231 "ceph-usages": List(Tuple(Int(), Float())),
232- "ring-id": utf8,
233- })
234+ "ring-id": utf8})
235
236 MEMORY_INFO = Message("memory-info", {
237- "memory-info": List(Tuple(Float(), Int(), Int())),
238- })
239+ "memory-info": List(Tuple(Float(), Int(), Int()))})
240
241 RESYNCHRONIZE = Message(
242 "resynchronize",
243@@ -137,8 +133,7 @@
244 "device": utf8,
245 "filesystem": utf8,
246 "total-space": Int()}),
247- )),
248- })
249+ ))})
250
251 FREE_SPACE = Message("free-space", {
252 "free-space": List(Tuple(Float(), utf8, Int()))})
253@@ -154,9 +149,10 @@
254 "hostname": utf8,
255 "account_name": utf8,
256 "tags": Any(utf8, Constant(None)),
257- "vm-info": String()},
258+ "vm-info": String(),
259+ "extra": Any(utf8, None)},
260 # hostname wasn't around in old versions
261- optional=["registration_password", "hostname", "tags", "vm-info"])
262+ optional=["registration_password", "hostname", "tags", "vm-info", "extra"])
263
264
265 REGISTER_PROVISIONED_MACHINE = Message(
266@@ -182,12 +178,11 @@
267 "vm-info": String(),
268 "public_ipv4": Unicode(),
269 "local_ipv4": Unicode()},
270- optional=["tags", "vm-info", "public_ipv4", "local_ipv4"])
271+ optional=["tags", "vm-info", "public_ipv4", "local_ipv4"])
272
273 TEMPERATURE = Message("temperature", {
274 "thermal-zone": utf8,
275- "temperatures": List(Tuple(Int(), Float())),
276- })
277+ "temperatures": List(Tuple(Int(), Float()))})
278
279 PROCESSOR_INFO = Message(
280 "processor-info",
281@@ -196,8 +191,7 @@
282 "model": utf8,
283 "cache-size": Int(),
284 },
285- optional=["vendor", "cache-size"])),
286- })
287+ optional=["vendor", "cache-size"]))})
288
289 user_data = KeyDict({
290 "uid": Int(),
291@@ -324,8 +318,7 @@
292
293 UNKNOWN_PACKAGE_HASHES = Message("unknown-package-hashes", {
294 "hashes": List(String()),
295- "request-id": Int(),
296- })
297+ "request-id": Int()})
298
299 PACKAGE_REPORTER_RESULT = Message("package-reporter-result", {
300 "code": Int(),
301@@ -342,8 +335,7 @@
302 "version": utf8,
303 "type": Int(),
304 })),
305- "request-id": Int(),
306- })
307+ "request-id": Int()})
308
309 TEXT_MESSAGE = Message("text-message", {
310 "message": Unicode()})

Subscribers

People subscribed via source and target branches

to all changes: