Merge lp:~mhall119/awstrial/add-logging into lp:~newz/awstrial/logging-tests

Proposed by Michael Hall
Status: Merged
Merged at revision: 267
Proposed branch: lp:~mhall119/awstrial/add-logging
Merge into: lp:~newz/awstrial/logging-tests
Diff against target: 400 lines (+142/-38)
11 files modified
awstrial/templates/404.html (+8/-2)
awstrial/templates/500.html (+7/-1)
awstrial/templates/503.html (+24/-2)
awstrial/templates/cloud-init/byobu-countdown (+3/-8)
awstrial/templates/cloud-init/info-callback (+6/-1)
awstrial/templates/contacts.html (+1/-1)
awstrial/templates/instance.html (+1/-1)
awstrial/trial/auth.py (+4/-3)
awstrial/trial/ec2_helper.py (+10/-11)
awstrial/trial/tests.py (+77/-6)
awstrial/trial/views.py (+1/-2)
To merge this branch: bzr merge lp:~mhall119/awstrial/add-logging
Reviewer Review Type Date Requested Status
Matthew Nuzum Pending
Review via email: mp+80013@code.launchpad.net

Description of the change

Mock out DNS.DnsRequest().req() to immitate a tor exit node match or not

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
1=== modified file 'awstrial/templates/404.html'
2--- awstrial/templates/404.html 2011-10-04 15:26:38 +0000
3+++ awstrial/templates/404.html 2011-10-20 23:51:23 +0000
4@@ -9,6 +9,12 @@
5 {% endwith %}
6 {% endblock %}
7
8+{% block logo_img %}
9+{% with '/ubuntu-website/media' as ubuntu_website_media %}
10+{{ block.super }}
11+{% endwith %}
12+{% endblock %}
13+
14 {% block extrahead %}
15 {% with '/media' as MEDIA_URL %}
16 {{ block.super }}
17@@ -18,6 +24,6 @@
18
19
20 {% block content %}
21-<h3>Oops!</h3>
22-<p>This page could not be found (404)</p>
23+<h2>404</h2>
24+<p>This page could not be found</p>
25 {% endblock %}
26
27=== modified file 'awstrial/templates/500.html'
28--- awstrial/templates/500.html 2011-10-04 15:26:38 +0000
29+++ awstrial/templates/500.html 2011-10-20 23:51:23 +0000
30@@ -9,6 +9,12 @@
31 {% endwith %}
32 {% endblock %}
33
34+{% block logo_img %}
35+{% with '/ubuntu-website/media' as ubuntu_website_media %}
36+{{ block.super }}
37+{% endwith %}
38+{% endblock %}
39+
40 {% block extrahead %}
41 {% with '/media' as MEDIA_URL %}
42 {{ block.super }}
43@@ -17,6 +23,6 @@
44 {% block main_nav_links %}{% endblock %}
45
46 {% block content %}
47-<h3>Oops!</h3>
48+<h2>500</h2>
49 <p>It seems an error has been encountered, we have been informed. Please try again later.</p>
50 {% endblock %}
51
52=== modified file 'awstrial/templates/503.html'
53--- awstrial/templates/503.html 2011-09-15 15:20:29 +0000
54+++ awstrial/templates/503.html 2011-10-20 23:51:23 +0000
55@@ -1,7 +1,29 @@
56 {% extends "base.html" %}
57-{% block header %}
58+
59+
60+{% block title %}Error | Try Ubuntu Cloud Guest{% endblock %}
61+
62+{% block defaulthead %}
63+{% with '/ubuntu-website/media' as ubuntu_website_media %}
64+{{ block.super }}
65+{% endwith %}
66+{% endblock %}
67+
68+{% block logo_img %}
69+{% with '/ubuntu-website/media' as ubuntu_website_media %}
70+{{ block.super }}
71+{% endwith %}
72+{% endblock %}
73+
74+{% block extrahead %}
75+{% with '/media' as MEDIA_URL %}
76+{{ block.super }}
77+{% endwith %}
78 <meta http-equiv="REFRESH" content="0;url=http://ubuntu.com/cloud"></HEAD>
79 {% endblock %}
80+{% block main_nav_links %}{% endblock %}
81+
82 {% block content %}
83-<h1>There was an error fulfilling the request at this time. Please try again later.</h1>
84+<h2>503</h2>
85+<p>There was an error fulfilling the request at this time. Please try again later.</p>
86 {% endblock %}
87
88=== renamed file 'awstrial/templates/cloud-init/byobu-enable' => 'awstrial/templates/cloud-init/byobu-countdown'
89--- awstrial/templates/cloud-init/byobu-enable 2010-09-30 12:58:03 +0000
90+++ awstrial/templates/cloud-init/byobu-countdown 2011-10-20 23:51:23 +0000
91@@ -1,14 +1,9 @@
92 #!/bin/sh
93-#sudo -Hu ubuntu byobu-launcher-install # single user
94-sem="/var/lib/cloud/sem/byobu-enable.${INSTANCE_ID}"
95+
96+sem="/var/lib/cloud/sem/byobu-countdown.${INSTANCE_ID}"
97 [ -e "${sem}" ] && exit 0
98
99-debconf-set-selections <<EOF
100-byobu byobu/launch-by-default boolean true
101-EOF
102-dpkg-reconfigure byobu --frontend=noninteractive
103-
104-# above does it for all users, but below is only for 'ubuntu' user
105+# Add AWSTrial countdown widget only for 'ubuntu' user
106 sudo -Hu ubuntu sh -c 'mkdir -p ~/.byobu/bin/ &&
107 cat > ~/.byobu/bin/1_countdown && chmod +x ~/.byobu/bin/1_countdown' <<"EOF"
108 #!/bin/sh
109
110=== modified file 'awstrial/templates/cloud-init/info-callback'
111--- awstrial/templates/cloud-init/info-callback 2011-10-18 13:58:40 +0000
112+++ awstrial/templates/cloud-init/info-callback 2011-10-20 23:51:23 +0000
113@@ -6,9 +6,14 @@
114 CALLBACK_URL="{{ callback_url }}"
115
116 mdurl="http://169.254.169.254/2009-04-04/meta-data/%s"
117+
118 dumpk="""
119 hn=$1; set -e; f=$(mktemp); trap "rm -f '$f'" EXIT;
120-ssh-keyscan -t rsa,dsa localhost 2>/dev/null > "$f"
121+rkeys="rsa,dsa"; [ -f "/etc/ssh/ssh_host_ecdsa_key" ] && rkeys="$rkeys,ecdsa"
122+{% if debug %}
123+echo "Requesting fingerprints for: $rkeys" >> /var/log/instance-testing
124+{% endif %}
125+ssh-keyscan -t "$rkeys" localhost 2>/dev/null > "$f"
126 [ -n "${hn}" ] && sed -i "s,localhost,${hn}," "$f"
127 ssh-keygen -lf "$f"
128 """
129
130=== modified file 'awstrial/templates/contacts.html'
131--- awstrial/templates/contacts.html 2011-10-04 15:26:38 +0000
132+++ awstrial/templates/contacts.html 2011-10-20 23:51:23 +0000
133@@ -14,7 +14,7 @@
134 <p>We will give you the hostname and you can SSH directly to the instance with your public SSH key on file in <a href=http://launchpad.net>Launchpad</a>. You will have full <a href=https://help.ubuntu.com/community/RootSudo>sudo (root) access</a>, so take it for an hour-long joyride, install applications, configure services, test your programs, and evaluate the overall experience. We will terminate and clean up the instance automatically within an hour.</p>
135
136 {% if set_password %}
137- <p><em>You do not have ssh keys on file in your launchpad account. We strongly recommend you follow the documentation mentioned above and add keys to your launchpad account. Ssh key authentication is much more secure than password authentication. However, if you would like to launch an instance without using ssh keys, you may do so. Click 'Launch' below, and you will be generated a one-time use password and forced to change it on first login</em></p>
138+ <p><em>You do not have ssh keys on file in your launchpad account. We strongly recommend you follow the documentation mentioned above and add keys to your launchpad account. Ssh key authentication is much more secure than password authentication. However, if you would like to launch an instance without using ssh keys, you may do so. Click 'Launch' below, and you will be generated a random password which you can then change after login</em></p>
139 {% endif %}
140 <div id="contact" class="clearfix">
141 <div id="c_form">
142
143=== modified file 'awstrial/templates/instance.html'
144--- awstrial/templates/instance.html 2011-10-18 13:58:40 +0000
145+++ awstrial/templates/instance.html 2011-10-20 23:51:23 +0000
146@@ -82,7 +82,7 @@
147 {% endif %}
148 {% else %}
149 {% if instance.password %}
150- <p>Your randomly generated one time password is '<b>{{ instance.password }}</b>'. You will be forced to change that on initial login.</p>
151+ <p>Your randomly generated one time password is '<b>{{ instance.password }}</b>'.</p>
152 {% endif %}
153 <p>You can <a href=https://help.ubuntu.com/community/SSH/OpenSSH/ConnectingTo target="_blank" >SSH</a> to your Cloud Server using:</p>
154 <pre> ssh ubuntu@{{instance.ip}}</pre>
155
156=== modified file 'awstrial/trial/auth.py'
157--- awstrial/trial/auth.py 2011-10-19 19:20:08 +0000
158+++ awstrial/trial/auth.py 2011-10-20 23:51:23 +0000
159@@ -41,8 +41,9 @@
160 if settings.USER_BLOCK_TOR_GATEWAY:
161
162 DNS.ParseResolvConf()
163-
164- client = ".".join(reversed(request.META['REMOTE_ADDR'].strip().split('.')))
165+
166+ remote_addr = request.META['REMOTE_ADDR']
167+ client = ".".join(reversed(remote_addr.strip().split('.')))
168
169 TARGET = ".".join(reversed(socket.gethostbyname(request.META['SERVER_NAME']).strip().split('.')))
170 PORT = "443"
171@@ -54,7 +55,7 @@
172
173 if answer.header['status'] == "NOERROR":
174 logger = logging.getLogger('root')
175- logger.info('Client %s is using TOR' % client)
176+ logger.info('Client %s is using TOR' % remote_addr)
177 return True
178 return False
179
180
181=== modified file 'awstrial/trial/ec2_helper.py'
182--- awstrial/trial/ec2_helper.py 2011-10-18 13:58:40 +0000
183+++ awstrial/trial/ec2_helper.py 2011-10-20 23:51:23 +0000
184@@ -21,6 +21,7 @@
185
186 from trial.models import Campaign, Instances
187 from django.contrib.auth.models import User
188+from django.contrib.sites.models import Site
189 from django.template.loader import render_to_string
190
191 from django.conf import settings
192@@ -62,8 +63,7 @@
193
194 return connection
195
196-def runit(campaign,lpid=None,regions=None,config=None, byobu=False,
197- password=None):
198+def runit(campaign,lpid=None,regions=None,config=None, password=None):
199 sec_key = util.rand_str(32)
200 if regions is None:
201 regions = [r for r in settings.REGIONS_TRY_ORDER
202@@ -72,7 +72,6 @@
203 if settings.REGION2AMI.has_key(r)]
204
205 cust = { }
206- cust['byobu'] = False
207 cust['config'] = config
208 cust['password'] = password
209
210@@ -82,8 +81,9 @@
211 render_to_string("import-launchpad-ssh-keys",
212 { 'debug' : settings.DEBUG, 'launchpad_id' : lpid, 'password' : password } ),
213 part_type=util.CI_SCRIPT, filename="10-launchpad-ssh-keys"))
214-
215- callback_url = "%s/info_callback/%s" % (settings.BASE_URL, sec_key)
216+
217+ site = Site.objects.get(pk=settings.SITE_ID)
218+ callback_url = "%s/info_callback/%s" % (site.name, sec_key)
219 parts.append(
220 util.partItem(
221 render_to_string("info-callback",
222@@ -113,12 +113,11 @@
223 { 'debug' : settings.DEBUG, 'user': 'ubuntu', 'password' : password }),
224 part_type=util.CI_SCRIPT, filename="55-password-enable"))
225
226- if str(byobu).lower() == "true":
227- parts.append(
228- util.partItem(
229- render_to_string("byobu-enable", { 'debug' : settings.DEBUG, }),
230- part_type=util.CI_BOOTHOOK, filename="byobu-enable"))
231- cust['byobu']=True
232+ parts.append(
233+ util.partItem(
234+ render_to_string("byobu-countdown", { 'debug' : settings.DEBUG, }),
235+ part_type=util.CI_BOOTHOOK, filename="byobu-countdown"))
236+ cust['byobu']=True
237
238 instcfg = None
239 for c in settings.CONFIGS:
240
241=== modified file 'awstrial/trial/tests.py'
242--- awstrial/trial/tests.py 2011-10-20 20:41:18 +0000
243+++ awstrial/trial/tests.py 2011-10-20 23:51:23 +0000
244@@ -25,6 +25,7 @@
245 from django.test import TestCase as DjangoTestCase
246 from django.conf import settings
247 from django.contrib.auth.models import User
248+from django.contrib.sites.models import Site
249 from mock import patch, Mock
250 from trial import ec2_helper
251 from trial.models import Campaign, Instances
252@@ -99,6 +100,7 @@
253 self.old_access_key = getattr(settings, 'AWS_ACCESS_KEY_ID', None)
254 self.old_secret_key = getattr(settings, 'AWS_SECRET_ACCESS_KEY', None)
255 self.old_alternate_cloud = getattr(settings, 'ALTERNATE_CLOUD', None)
256+ self.old_site_id = getattr(settings, 'SITE_ID', None)
257 settings.AWS_ACCESS_KEY_ID = 'TestAccessKey'
258 settings.AWS_SECRET_ACCESS_KEY = 'TestSecretKey'
259 settings.ALTERNATE_CLOUD = None
260@@ -107,6 +109,7 @@
261 settings.AWS_ACCESS_KEY_ID = self.old_access_key
262 settings.AWS_SECRET_ACCESS_KEY = self.old_secret_key
263 settings.ALTERNATE_CLOUD = self.old_alternate_cloud
264+ settings.SITE_ID = self.old_site_id
265
266 def call_run_instance(self, campaign):
267 post_data = {
268@@ -117,6 +120,63 @@
269 return self.client.post('/%s/run/' % campaign.name, post_data)
270
271 @patch('boto.ec2.EC2Connection')
272+ def test_uses_sites_framework(self, mock_connection):
273+ """
274+ Checks that the callback url is based off the Site.name for this
275+ configuration
276+ """
277+
278+ newsite = Site.objects.create(
279+ domain='testing.awstrial.org',
280+ name='http://testing.awstrial.org:8000',
281+ )
282+ settings.SITE_ID = newsite.id
283+ self.call_count=0
284+ class MockInstance(object):
285+
286+ def __init__(self, instance_id):
287+ self.id = instance_id
288+
289+ class MockReservation(object):
290+
291+ def __init__(self, instance_ids):
292+ self.instances = [MockInstance(i) for i in instance_ids]
293+
294+ campaign = Campaign.objects.create(
295+ name='test-campaign',
296+ verbose_name='Test Campaign',
297+ max_instances=5,
298+ active=True,
299+ )
300+
301+ def mock_run_instances(conn, *args, **kwargs):
302+ self.call_count += 1
303+ self.assertTrue('user_data' in kwargs)
304+
305+ import StringIO, gzip, email
306+ gzipped_mime_data = StringIO.StringIO()
307+ gzipped_mime_data.write(kwargs['user_data'])
308+ gzipped_mime_data.seek(0)
309+ gzipped_mime_file = gzip.GzipFile(fileobj=gzipped_mime_data, mode='r')
310+ mime_data = gzipped_mime_file.read()
311+ mime_msg = email.message_from_string(mime_data)
312+ self.assertTrue(mime_msg.is_multipart())
313+
314+ for mime_part in mime_msg.get_payload():
315+ if mime_part.get_filename() == '99-info-callback':
316+ self.assertTrue('http://testing.awstrial.org:8000/info_callback/' in mime_part.get_payload())
317+
318+ return MockReservation(['i-test-%s'%self.call_count])
319+ mock_connection.return_value.run_instances.side_effect = mock_run_instances
320+
321+ user = User.objects.create_user('testuser', 'test@example.com', 'testpasswd')
322+ self.client.login(username='testuser', password='testpasswd')
323+
324+ response = self.call_run_instance(campaign)
325+ self.assertEquals(1, Instances.objects.all().count())
326+ instance = Instances.objects.all()[0]
327+
328+ @patch('boto.ec2.EC2Connection')
329 def test_disallow_multiple_instances(self, mock_connection):
330 """
331 Checks that a user can't create multiple isntances by making requests
332@@ -333,11 +393,16 @@
333 super(LogHandlerTestCase, self).setUp()
334 self.memento_handler = self.MementoHandler()
335 self.root_logger = logging.getLogger()
336+ self.root_logger.setLevel(logging.INFO)
337 self.root_logger.addHandler(self.memento_handler)
338+ self.old_block_tor = settings.USER_BLOCK_TOR_GATEWAY
339+ self.old_block_email = settings.USER_BLOCK_EMAIL_BLACKLIST
340
341 def tearDown(self):
342 """Remove the memento handler from the root logger."""
343 self.root_logger.removeHandler(self.memento_handler)
344+ settings.USER_BLOCK_TOR_GATEWAY = self.old_block_tor
345+ settings.USER_BLOCK_EMAIL_BLACKLIST = self.old_block_email
346 super(LogHandlerTestCase, self).tearDown()
347
348 def assertLogLevelContains(self, level, message, with_exc_info=False):
349@@ -346,19 +411,25 @@
350 self.assertTrue(
351 self.memento_handler.check(level, message, with_exc_info))
352
353- def test_client_using_tor(self):
354+ @patch('DNS.DnsRequest')
355+ def test_client_using_tor(self, mock_dns_request):
356 # verify that a client that is a TOR exit node is blocked
357- tor_exit = socket.gethostbyname('ip-port.exitlist.torproject.org')
358+ settings.USER_BLOCK_TOR_GATEWAY = True
359 request = MockRequest()
360 request.META['SERVER_NAME'] = '127.0.0.1'
361- request.META['REMOTE_ADDR'] = tor_exit
362+ request.META['REMOTE_ADDR'] = '127.0.0.2'
363+ mock_dns_request.return_value.req.side_effect = type('answer', (), {'header': {'status': 'NOERROR'}})
364 self.assertTrue(client_using_tor(request))
365+ self.assertLogLevelContains('INFO', 'Client 127.0.0.2 is using TOR')
366
367- def test_client_not_using_tor(self):
368+ @patch('DNS.DnsRequest')
369+ def test_client_not_using_tor(self, mock_dns_request):
370 # verify that a client that is not a TOR exit node is not blocked
371- me = socket.gethostname()
372+ settings.USER_BLOCK_TOR_GATEWAY = True
373 request = MockRequest()
374 request.META['SERVER_NAME'] = '127.0.0.1'
375- request.META['REMOTE_ADDR'] = me
376+ request.META['REMOTE_ADDR'] = '127.0.0.2'
377+ mock_dns_request.return_value.req.side_effect = type('answer', (), {'header': {'status': 'ERROR'}})
378 self.assertFalse(client_using_tor(request))
379+ self.assertFalse(self.memento_handler.check('INFO', 'Client 127.0.0.2 is using TOR'))
380
381
382=== modified file 'awstrial/trial/views.py'
383--- awstrial/trial/views.py 2011-10-18 20:11:39 +0000
384+++ awstrial/trial/views.py 2011-10-20 23:51:23 +0000
385@@ -86,14 +86,13 @@
386 else:
387 regions = settings.REGIONS_TRY_ORDER
388 config = request.POST.get('config', '')
389- byobu = request.POST.get('byobu','')
390 set_password = request.POST.get('set_password',None)
391
392 password=None
393 if set_password:
394 password=util.rand_user_password()
395
396- ec2_helper.runit(campaign,lpid=request.user, regions=regions, config=config, byobu=byobu, password=password)
397+ ec2_helper.runit(campaign,lpid=request.user, regions=regions, config=config, password=password)
398 #send_mail(subject, message, from_email, ['davewalker@ubuntu.com'])
399 #except BadHeaderError: #Example of basic error handling
400 # return HttpResponse('Invalid header found.')

Subscribers

People subscribed via source and target branches

to all changes: