Merge lp:~rvb/maas/bug-1062607 into lp:~maas-committers/maas/trunk

Proposed by Raphaël Badin
Status: Merged
Approved by: Raphaël Badin
Approved revision: no longer in the source branch.
Merged at revision: 1225
Proposed branch: lp:~rvb/maas/bug-1062607
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 77 lines (+47/-4)
2 files modified
src/maasserver/tests/test_views_settings_clusters.py (+36/-4)
src/maasserver/urls.py (+11/-0)
To merge this branch: bzr merge lp:~rvb/maas/bug-1062607
Reviewer Review Type Date Requested Status
Jeroen T. Vermeulen (community) Approve
Review via email: mp+128543@code.launchpad.net

Commit message

Cope with doubles slashes being removed by apache when editing an interface.

Description of the change

This branch fixes the url machinery so that it will cope with the fact that apache transforms multiple slashes in a url into a single one. That pattern appears in the url that maas generates when one edits an interface with an empty name.

= Notes =

Maybe one can find a better way to express the fact that the new url matchers should match an empty interface "(?P<interface>[\w\-]{0})"…?

Note that I've tested in a production instance (behind apache), that this actually fixes bug 1062607.

To post a comment you must log in.
Revision history for this message
Gavin Panella (allenap) wrote :

Include a prefix, like "@" or "if=", then the regex can be "if=(?P<interface>[\w\-]{0})" ?

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

I don't see how this can work: "(?P<interface>[\w\-]{0})" will only match a string of length zero. If you want zero or more instances, that's actually easier: "(?P<interface>[\w\-]*)"

I could be missing something, of course. But if not, this suggests a missing test.

review: Needs Fixing
Revision history for this message
Raphaël Badin (rvb) wrote :

> I don't see how this can work: "(?P<interface>[\w\-]{0})" will only match a
> string of length zero.

Indeed, that's exactly the intention, I want it to match 'interface' so that the view will be called with interface=''.

> If you want zero or more instances, that's actually
> easier: "(?P<interface>[\w\-]*)"

Yeah, but the problem is the '/'.

Here is the url we have for the 'eth0' interface:
http://localhost:8080/MAAS/clusters/24449ff8-3540-4dfa-b434-ab79cc550401/interfaces/eth0/edit/

Here is the url we have for the '' interface:
http://localhost:8080/MAAS/clusters/24449ff8-3540-4dfa-b434-ab79cc550401/interfaces//edit/
The problem is that apache transforms it into
http://localhost:8080/MAAS/clusters/24449ff8-3540-4dfa-b434-ab79cc550401/interfaces/edit/
That's the url that the new regex matches.

Revision history for this message
Raphaël Badin (rvb) wrote :

> Include a prefix, like "@" or "if=", then the regex can be
> "if=(?P<interface>[\w\-]{0})" ?

That's actually a bit more complicated than the solution I have here I think. What I like about my solution is that is adds two completely new urls that we could remove once bug 1063881 is fixed and the new regex are easy to read.

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

I think I see what you're saying now. But then why not just "(?P<interface>)" to get the empty string there?

Revision history for this message
Raphaël Badin (rvb) wrote :

> I think I see what you're saying now. But then why not just "(?P<interface>)"
> to get the empty string there?

Because that would match stuff like:
http://localhost:8080/MAAS/clusters/24449ff8-3540-4dfa-b434-ab79cc550401/interfaces/blahedit/

And I don't want that :)

I just want to match:

http://localhost:8080/MAAS/clusters/24449ff8-3540-4dfa-b434-ab79cc550401/interfaces/edit/

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

I don't see what you mean... (?P<interface>) matches only the empty string, nothing else.

Revision history for this message
Raphaël Badin (rvb) wrote :

> I don't see what you mean... (?P<interface>) matches only the empty string,
> nothing else.

Ah, you're right, I've updated the branch.

Revision history for this message
Jeroen T. Vermeulen (jtv) wrote :

OK

review: Approve

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/tests/test_views_settings_clusters.py'
2--- src/maasserver/tests/test_views_settings_clusters.py 2012-10-03 07:57:55 +0000
3+++ src/maasserver/tests/test_views_settings_clusters.py 2012-10-08 18:01:35 +0000
4@@ -29,11 +29,14 @@
5 reload_object,
6 )
7 from maasserver.testing.factory import factory
8-from maasserver.testing.testcase import (
9- AdminLoggedInTestCase,
10- )
11+from maasserver.testing.testcase import AdminLoggedInTestCase
12 from maastesting.matchers import ContainsAll
13-from testtools.matchers import MatchesStructure
14+from testtools.matchers import (
15+ AllMatch,
16+ Contains,
17+ Equals,
18+ MatchesStructure,
19+ )
20
21
22 class ClusterListingTest(AdminLoggedInTestCase):
23@@ -142,3 +145,32 @@
24 self.assertThat(
25 reload_object(interface),
26 MatchesStructure.byEquality(**data))
27+
28+
29+# XXX: rvb 2012-10-08 bug=1063881: apache transforms '//' into '/' in
30+# the urls it passes around and this happens when an interface has an empty
31+# name.
32+class ClusterInterfaceDoubleSlashBugTest(AdminLoggedInTestCase):
33+
34+ def test_edit_delete_empty_cluster_interface_when_slash_removed(self):
35+ nodegroup = factory.make_node_group()
36+ interface = factory.make_node_group_interface(
37+ nodegroup=nodegroup, interface='',
38+ management=NODEGROUPINTERFACE_MANAGEMENT.UNMANAGED)
39+ edit_link = reverse(
40+ 'cluster-interface-edit',
41+ args=[nodegroup.uuid, interface.interface])
42+ delete_link = reverse(
43+ 'cluster-interface-delete',
44+ args=[nodegroup.uuid, interface.interface])
45+ links = [edit_link, delete_link]
46+ # Just make sure that the urls contains '//'. If this is not
47+ # true anymore, because we've refactored the urls, this test can
48+ # problably be removed.
49+ self.assertThat(links, AllMatch(Contains('//')))
50+ # Simulate what apache (when used as a frontend) does to the
51+ # urls.
52+ new_links = [link.replace('//', '/') for link in links]
53+ response_statuses = [
54+ self.client.get(link).status_code for link in new_links]
55+ self.assertThat(response_statuses, AllMatch(Equals(httplib.OK)))
56
57=== modified file 'src/maasserver/urls.py'
58--- src/maasserver/urls.py 2012-10-08 08:28:23 +0000
59+++ src/maasserver/urls.py 2012-10-08 18:01:35 +0000
60@@ -141,6 +141,17 @@
61 r'^clusters/(?P<uuid>[\w\-]+)/interfaces/(?P<interface>[\w\-]*)/'
62 'delete/$',
63 ClusterInterfaceDelete.as_view(), name='cluster-interface-delete'),
64+ # XXX: rvb 2012-10-08 bug=1063881:
65+ # These two urls are only here to cope with the fact that an interface
66+ # can have an empty name, thus leading to urls containing the
67+ # pattern '//' that is then reduced by apache into '/'.
68+ adminurl(
69+ r'^clusters/(?P<uuid>[\w\-]+)/interfaces/(?P<interface>)'
70+ 'edit/$', ClusterInterfaceEdit.as_view()),
71+ adminurl(
72+ r'^clusters/(?P<uuid>[\w\-]+)/interfaces/(?P<interface>)'
73+ 'delete/$', ClusterInterfaceDelete.as_view()),
74+ # /XXX
75 adminurl(r'^settings/$', settings, name='settings'),
76 adminurl(
77 r'^settings/archives/add/$', settings_add_archive,