Merge lp:~mpontillo/maas/show-nodes-on-subnet-page-1567150 into lp:~maas-committers/maas/trunk

Proposed by Mike Pontillo
Status: Merged
Approved by: Mike Pontillo
Approved revision: no longer in the source branch.
Merged at revision: 4966
Proposed branch: lp:~mpontillo/maas/show-nodes-on-subnet-page-1567150
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 147 lines (+58/-22)
3 files modified
src/maasserver/models/staticipaddress.py (+15/-2)
src/maasserver/models/tests/test_staticipaddress.py (+15/-0)
src/maasserver/static/partials/subnet-details.html (+28/-20)
To merge this branch: bzr merge lp:~mpontillo/maas/show-nodes-on-subnet-page-1567150
Reviewer Review Type Date Requested Status
Blake Rouse (community) Approve
Andres Rodriguez (community) Approve
Review via email: mp+293030@code.launchpad.net

This proposal supersedes a proposal from 2016-04-25.

Commit message

Show link to node or controller details page (if possible) on subnet IP address listing.

Description of the change

Here's a couple more options, based on discussions with design. What do people prefer?

Interface and Node in the same column:
    https://imgur.com/MugFeWx

Interface and node in two separate columns:
    https://imgur.com/Zbo2oQj

To post a comment you must log in.
Revision history for this message
Mike Pontillo (mpontillo) wrote : Posted in a previous version of this proposal

This was an easy fix. We already had the data in the controller; just had to expose it on the view.

Revision history for this message
Blake Rouse (blake-rouse) : Posted in a previous version of this proposal
review: Needs Fixing
Revision history for this message
Mike Pontillo (mpontillo) wrote : Posted in a previous version of this proposal

I agree it's a bit weird, though I think it's a big improvement over what we have now. Let's take another look at the design and try a few things before this lands, then.

Revision history for this message
Andres Rodriguez (andreserl) wrote : Posted in a previous version of this proposal

I actually believe rwe should have the source, because that differentiates the actual machine. You may have devices called:

machine1

and a machine

machine2

So it is good for differentiation.

review: Approve
Revision history for this message
Blake Rouse (blake-rouse) wrote : Posted in a previous version of this proposal

Node and Usage is a repeat, this is not correct.

review: Disapprove
Revision history for this message
Mike Pontillo (mpontillo) wrote : Posted in a previous version of this proposal

Well, there isn't a repeat. Though I think the presentation can still be improved.

https://imgur.com/cEOt11z

Revision history for this message
Andres Rodriguez (andreserl) wrote :

Just one comment inline, otherwise it lgtm!

review: Approve
Revision history for this message
Mike Pontillo (mpontillo) wrote :

Replied to your comment below. Also, which option do you like?

Interface and Node in the same column:
    https://imgur.com/MugFeWx

Interface and node in two separate columns:
    https://imgur.com/Zbo2oQj

Revision history for this message
Mike Pontillo (mpontillo) wrote :

Another option (node and interface swapped):

https://imgur.com/jCQIVfA

Revision history for this message
Blake Rouse (blake-rouse) wrote :

Looks good.

review: Approve
Revision history for this message
MAAS Lander (maas-lander) wrote :

Attempt to merge into lp:maas failed due to conflicts:

text conflict in src/maasserver/static/partials/subnet-details.html

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'src/maasserver/models/staticipaddress.py'
2--- src/maasserver/models/staticipaddress.py 2016-04-22 19:34:44 +0000
3+++ src/maasserver/models/staticipaddress.py 2016-04-27 18:24:27 +0000
4@@ -473,14 +473,23 @@
5 return "%s:type=%s" % (self.ip, strtype)
6
7 def get_node(self):
8- """Return the Node of the first interface connected to this IP
9+ """Return the Node of the first Interface connected to this IP
10 address."""
11- interface = self.interface_set.first()
12+ interface = self.get_interface()
13 if interface is not None:
14 return interface.get_node()
15 else:
16 return None
17
18+ def get_interface(self):
19+ """Return the first Interface connected to this IP address."""
20+ # Note that, while this relationship is modeled as a many-to-many,
21+ # MAAS currently only relates a single interface per IP address
22+ # at this time. In the future, we may want to model virtual IPs, in
23+ # which case this will need to change.
24+ interface = self.interface_set.first()
25+ return interface
26+
27 def get_interface_link_type(self):
28 """Return the `INTERFACE_LINK_TYPE`."""
29 if self.alloc_type == IPADDRESS_TYPE.AUTO:
30@@ -650,13 +659,17 @@
31 if with_username and self.user is not None:
32 data["user"] = self.user.username
33 if with_node_summary:
34+ iface = self.get_interface()
35 node = self.get_node()
36 if node is not None:
37 data["node_summary"] = {
38 "system_id": node.system_id,
39 "node_type": node.node_type,
40 "fqdn": node.fqdn,
41+ "hostname": node.hostname,
42 }
43+ if iface is not None:
44+ data["node_summary"]["via"] = iface.get_name()
45 if (with_username and
46 self.alloc_type != IPADDRESS_TYPE.DISCOVERED):
47 # If a user owns this node, overwrite any username we found
48
49=== modified file 'src/maasserver/models/tests/test_staticipaddress.py'
50--- src/maasserver/models/tests/test_staticipaddress.py 2016-04-27 12:15:51 +0000
51+++ src/maasserver/models/tests/test_staticipaddress.py 2016-04-27 18:24:27 +0000
52@@ -905,6 +905,21 @@
53 self.expectThat(json, Not(Contains("user")))
54 self.expectThat(json, Contains("node_summary"))
55
56+ def test__node_summary_includes_interface_name(self):
57+ user = factory.make_User()
58+ subnet = factory.make_Subnet()
59+ node = factory.make_Node_with_Interface_on_Subnet(
60+ disable_ipv4=False, subnet=subnet)
61+ self.expectThat(node.interface_set.count(), Equals(1))
62+ iface = node.interface_set.first()
63+ ip = factory.make_StaticIPAddress(
64+ ip=factory.pick_ip_in_Subnet(subnet), user=user,
65+ interface=node.get_boot_interface())
66+ json = ip.render_json(with_node_summary=True)
67+ self.expectThat(json, Not(Contains("user")))
68+ self.expectThat(json, Contains("node_summary"))
69+ self.expectThat(json['node_summary']['via'], Equals(iface.name))
70+
71 def test__data_is_accurate_and_complete(self):
72 user = factory.make_User()
73 hostname = factory.make_name('hostname')
74
75=== modified file 'src/maasserver/static/partials/subnet-details.html'
76--- src/maasserver/static/partials/subnet-details.html 2016-04-27 02:20:00 +0000
77+++ src/maasserver/static/partials/subnet-details.html 2016-04-27 18:24:27 +0000
78@@ -266,10 +266,11 @@
79 <thead>
80 <tr class="table-listing__row">
81 <th class="table-listing__header table-col--20">IP Address</th>
82- <th class="table-listing__header table-col--20">Node</th>
83+ <th class="table-listing__header table-col--10">Type</th>
84+ <th class="table-listing__header table-col--15">Node</th>
85+ <th class="table-listing__header table-col--10">Interface</th>
86+ <th class="table-listing__header table-col--10">Usage</th>
87 <th class="table-listing__header table-col--10">Owner</th>
88- <th class="table-listing__header table-col--10">Usage</th>
89- <th class="table-listing__header table-col--15">Type</th>
90 <th class="table-listing__header table-col--25">Last seen</th>
91 <!-- XXX mpontillo need data for this -->
92 <!--
93@@ -286,15 +287,29 @@
94 <tbody>
95 <tr data-ng-repeat="ip in subnet.ip_addresses">
96 <td class="table-col--20">{$ ip.ip $}</td>
97- <td class="table-col--20" data-ng-switch="ip.node_summary.node_type">
98- <span data-ng-switch-when="0"><a href="#/node/{$ ip.node_summary.system_id $}">{$ ip.node_summary.fqdn $}</a></span>
99- <span data-ng-switch-when="1">{$ ip.node_summary.fqdn $}</span>
100- <span data-ng-switch-when="2"><a href="#/node/controller/{$ ip.node_summary.system_id $}">{$ ip.node_summary.fqdn $}</a></span>
101- <span data-ng-switch-when="3"><a href="#/node/controller/{$ ip.node_summary.system_id $}">{$ ip.node_summary.fqdn $}</a></span>
102- <span data-ng-switch-when="4"><a href="#/node/controller/{$ ip.node_summary.system_id $}">{$ ip.node_summary.fqdn $}</a></span>
103- <span data-ng-switch-default>Unknown</span>
104- </td>
105- <td class="table-col--10">{$ ip.user ? ip.user : "MAAS" $}</td>
106+ <td class="table-col--10" data-ng-switch="ip.alloc_type">
107+ <span data-ng-switch-when="0">Automatic</span>
108+ <span data-ng-switch-when="1">Static</span>
109+ <span data-ng-switch-when="4">User reserved</span>
110+ <span data-ng-switch-when="5">DHCP</span>
111+ <span data-ng-switch-when="6">Observed</span>
112+ <span data-ng-switch-default>Unknown</span>
113+ </td>
114+ <td class="table-col--15" data-ng-switch="ip.node_summary.node_type">
115+ <span data-ng-switch-when="0"><a href="#/node/{$ ip.node_summary.system_id $}">{$ ip.node_summary.hostname $}</a></span>
116+ <span data-ng-switch-when="1">{$ ip.node_summary.hostname $}</span>
117+ <span data-ng-switch-when="2"><a href="#/node/controller/{$ ip.node_summary.system_id $}">{$ ip.node_summary.hostname $}</a></span>
118+ <span data-ng-switch-when="3"><a href="#/node/controller/{$ ip.node_summary.system_id $}">{$ ip.node_summary.hostname $}</a></span>
119+ <span data-ng-switch-when="4"><a href="#/node/controller/{$ ip.node_summary.system_id $}">{$ ip.node_summary.hostname $}</a></span>
120+ </td>
121+ <td class="table-col--10" data-ng-switch="ip.node_summary.node_type">
122+ <span data-ng-switch-when="0">{$ ip.node_summary.via $}</span>
123+ <span data-ng-switch-when="1">{$ ip.node_summary.via $}</span>
124+ <span data-ng-switch-when="2">{$ ip.node_summary.via $}</span>
125+ <span data-ng-switch-when="3">{$ ip.node_summary.via $}</span>
126+ <span data-ng-switch-when="4">{$ ip.node_summary.via $}</span>
127+ <span data-ng-switch-default>Unknown</span>
128+ </td>
129 <td class="table-col--10" data-ng-switch="ip.node_summary.node_type">
130 <span data-ng-switch-when="0">Machine</span>
131 <span data-ng-switch-when="1">Device</span>
132@@ -303,14 +318,7 @@
133 <span data-ng-switch-when="4">Rack and region controller</span>
134 <span data-ng-switch-default>Unknown</span>
135 </td>
136- <td class="table-col--15" data-ng-switch="ip.alloc_type">
137- <span data-ng-switch-when="0">Automatic</span>
138- <span data-ng-switch-when="1">Static</span>
139- <span data-ng-switch-when="4">User reserved</span>
140- <span data-ng-switch-when="5">DHCP</span>
141- <span data-ng-switch-when="6">Observed</span>
142- <span data-ng-switch-default>Unknown</span>
143- </td>
144+ <td class="table-col--10">{$ ip.user ? ip.user : "MAAS" $}</td>
145 <td class="table-col--25">
146 <time>{$ ip.updated $}</time>
147 </td>