Merge lp:~blake-rouse/maas/fix-1592137 into lp:~maas-committers/maas/trunk

Proposed by Blake Rouse
Status: Merged
Approved by: Blake Rouse
Approved revision: no longer in the source branch.
Merged at revision: 5127
Proposed branch: lp:~blake-rouse/maas/fix-1592137
Merge into: lp:~maas-committers/maas/trunk
Diff against target: 725 lines (+450/-97)
7 files modified
src/maasserver/enum.py (+7/-3)
src/maasserver/static/js/angular/controllers/subnet_details.js (+91/-5)
src/maasserver/static/js/angular/controllers/tests/test_subnet_details.js (+154/-0)
src/maasserver/static/js/angular/services/converter.js (+55/-0)
src/maasserver/static/js/angular/services/tests/test_converter.js (+104/-0)
src/maasserver/static/js/angular/services/validation.js (+15/-55)
src/maasserver/static/partials/subnet-details.html (+24/-34)
To merge this branch: bzr merge lp:~blake-rouse/maas/fix-1592137
Reviewer Review Type Date Requested Status
Mike Pontillo (community) Approve
Jeffrey C Jones (community) Approve
Review via email: mp+297468@code.launchpad.net

Commit message

Add the ability to sort the IP address table on the subnet details page.

To post a comment you must log in.
Revision history for this message
Jeffrey C Jones (trapnine) wrote :

LGTM, might want to move some display strings to a central location, comments below.

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

Looks really good!

I made a number of comments below; nothing really blocking, but some things to consider and some minor cleanup.

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

Thanks for the reviews. Addressed all comments.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'src/maasserver/enum.py'
--- src/maasserver/enum.py 2016-04-11 16:23:26 +0000
+++ src/maasserver/enum.py 2016-06-16 14:50:25 +0000
@@ -134,6 +134,8 @@
134 REGION_AND_RACK_CONTROLLER = 4134 REGION_AND_RACK_CONTROLLER = 4
135135
136136
137# This is copied in static/js/angular/controllers/subnet_details.js. If you
138# update any choices you also need to update the controller.
137NODE_TYPE_CHOICES = (139NODE_TYPE_CHOICES = (
138 (NODE_TYPE.MACHINE, "Machine"),140 (NODE_TYPE.MACHINE, "Machine"),
139 (NODE_TYPE.DEVICE, "Device"),141 (NODE_TYPE.DEVICE, "Device"),
@@ -226,12 +228,14 @@
226 DISCOVERED = 6228 DISCOVERED = 6
227229
228230
231# This is copied in static/js/angular/controllers/subnet_details.js. If you
232# update any choices you also need to update the controller.
229IPADDRESS_TYPE_CHOICES = (233IPADDRESS_TYPE_CHOICES = (
230 (IPADDRESS_TYPE.AUTO, "Auto"),234 (IPADDRESS_TYPE.AUTO, "Automatic"),
231 (IPADDRESS_TYPE.STICKY, "Sticky"),235 (IPADDRESS_TYPE.STICKY, "Static"),
232 (IPADDRESS_TYPE.USER_RESERVED, "User reserved"),236 (IPADDRESS_TYPE.USER_RESERVED, "User reserved"),
233 (IPADDRESS_TYPE.DHCP, "DHCP"),237 (IPADDRESS_TYPE.DHCP, "DHCP"),
234 (IPADDRESS_TYPE.DISCOVERED, "Discovered"),238 (IPADDRESS_TYPE.DISCOVERED, "Observed"),
235 )239 )
236240
237241
238242
=== modified file 'src/maasserver/static/js/angular/controllers/subnet_details.js'
--- src/maasserver/static/js/angular/controllers/subnet_details.js 2016-06-09 17:18:10 +0000
+++ src/maasserver/static/js/angular/controllers/subnet_details.js 2016-06-16 14:50:25 +0000
@@ -8,10 +8,11 @@
8 '$scope', '$rootScope', '$routeParams', '$filter', '$location',8 '$scope', '$rootScope', '$routeParams', '$filter', '$location',
9 'SubnetsManager', 'IPRangesManager', 'SpacesManager', 'VLANsManager',9 'SubnetsManager', 'IPRangesManager', 'SpacesManager', 'VLANsManager',
10 'UsersManager', 'FabricsManager', 'ManagerHelperService', 'ErrorService',10 'UsersManager', 'FabricsManager', 'ManagerHelperService', 'ErrorService',
11 'ConverterService',
11 function(12 function(
12 $scope, $rootScope, $routeParams, $filter, $location, SubnetsManager,13 $scope, $rootScope, $routeParams, $filter, $location, SubnetsManager,
13 IPRangesManager, SpacesManager, VLANsManager, UsersManager,14 IPRangesManager, SpacesManager, VLANsManager, UsersManager,
14 FabricsManager, ManagerHelperService, ErrorService) {15 FabricsManager, ManagerHelperService, ErrorService, ConverterService) {
1516
16 // Set title and page.17 // Set title and page.
17 $rootScope.title = "Loading...";18 $rootScope.title = "Loading...";
@@ -29,10 +30,29 @@
29 $scope.spaces = SpacesManager.getItems();30 $scope.spaces = SpacesManager.getItems();
30 $scope.vlans = VLANsManager.getItems();31 $scope.vlans = VLANsManager.getItems();
31 $scope.fabrics = FabricsManager.getItems();32 $scope.fabrics = FabricsManager.getItems();
33 $scope.reverse = false;
32 $scope.newRange = null;34 $scope.newRange = null;
33 $scope.editIPRange = null;35 $scope.editIPRange = null;
34 $scope.deleteIPRange = null;36 $scope.deleteIPRange = null;
3537
38 // Alloc type mapping.
39 var ALLOC_TYPES = {
40 0: 'Automatic',
41 1: 'Static',
42 4: 'User reserved',
43 5: 'DHCP',
44 6: 'Observed'
45 };
46
47 // Node type mapping.
48 var NODE_TYPES = {
49 0: 'Machine',
50 1: 'Device',
51 2: 'Rack controller',
52 3: 'Region controller',
53 4: 'Rack and region controller'
54 };
55
36 // Updates the page title.56 // Updates the page title.
37 function updateTitle() {57 function updateTitle() {
38 subnet = $scope.subnet;58 subnet = $scope.subnet;
@@ -44,10 +64,75 @@
44 }64 }
45 }65 }
4666
47 $scope.isSuperUser = function() {67 // Update the IP version of the CIDR.
48 return UsersManager.isSuperUser();68 function updateIPVersion() {
49 };69 var ip = $scope.subnet.cidr.split('/')[0];
5070 if(ip.indexOf(':') === -1) {
71 $scope.ipVersion = 4;
72 } else {
73 $scope.ipVersion = 6;
74 }
75 }
76
77 // Sort for IP address.
78 $scope.ipSort = function(ipAddress) {
79 if($scope.ipVersion === 4) {
80 return ConverterService.ipv4ToInteger(ipAddress.ip);
81 } else {
82 return ConverterService.ipv6Expand(ipAddress.ip);
83 }
84 };
85
86 // Set default predicate to the ipSort function.
87 $scope.predicate = $scope.ipSort;
88
89 // Return the name of the allocation type.
90 $scope.getAllocType = function(allocType) {
91 var str = ALLOC_TYPES[allocType];
92 if(angular.isString(str)) {
93 return str;
94 } else {
95 return "Unknown";
96 }
97 };
98
99 // Sort based on the name of the allocation type.
100 $scope.allocTypeSort = function(ipAddress) {
101 return $scope.getAllocType(ipAddress.alloc_type);
102 };
103
104 // Return the name of the node type.
105 $scope.getNodeType = function(nodeType) {
106 var str = NODE_TYPES[nodeType];
107 if(angular.isString(str)) {
108 return str;
109 } else {
110 return "Unknown";
111 }
112 };
113
114 // Sort based on the node type string.
115 $scope.nodeTypeSort = function(ipAddress) {
116 return $scope.getNodeType(ipAddress.node_summary.node_type);
117 };
118
119 // Sort based on the owner name.
120 $scope.ownerSort = function(ipAddress) {
121 var owner = ipAddress.user;
122 if(angular.isString(owner) && owner.length > 0) {
123 return owner;
124 } else {
125 return "MAAS";
126 }
127 };
128
129 // Called to change the sort order of the IP table.
130 $scope.sortIPTable = function(predicate) {
131 $scope.predicate = predicate;
132 $scope.reverse = !$scope.reverse;
133 };
134
135 // Return the name of the VLAN.
51 $scope.getVLANName = function(vlan) {136 $scope.getVLANName = function(vlan) {
52 return VLANsManager.getName(vlan);137 return VLANsManager.getName(vlan);
53 };138 };
@@ -179,6 +264,7 @@
179 };264 };
180 $scope.$watch("subnet.fabric", updateFabric);265 $scope.$watch("subnet.fabric", updateFabric);
181 $scope.$watch("subnet.vlan", updateFabric);266 $scope.$watch("subnet.vlan", updateFabric);
267 $scope.$watch("subnet.cidr", updateIPVersion);
182 }268 }
183269
184 // Load all the required managers.270 // Load all the required managers.
185271
=== modified file 'src/maasserver/static/js/angular/controllers/tests/test_subnet_details.js'
--- src/maasserver/static/js/angular/controllers/tests/test_subnet_details.js 2016-06-13 14:21:20 +0000
+++ src/maasserver/static/js/angular/controllers/tests/test_subnet_details.js 2016-06-16 14:50:25 +0000
@@ -72,6 +72,7 @@
72 // Load any injected managers and services.72 // Load any injected managers and services.
73 var SubnetsManager, IPRangesManager, SpacesManager, VLANsManager;73 var SubnetsManager, IPRangesManager, SpacesManager, VLANsManager;
74 var FabricsManager, UsersManager, HelperService, ErrorService;74 var FabricsManager, UsersManager, HelperService, ErrorService;
75 var ConverterService;
75 beforeEach(inject(function($injector) {76 beforeEach(inject(function($injector) {
76 SubnetsManager = $injector.get("SubnetsManager");77 SubnetsManager = $injector.get("SubnetsManager");
77 IPRangesManager = $injector.get("IPRangesManager");78 IPRangesManager = $injector.get("IPRangesManager");
@@ -81,6 +82,7 @@
81 UsersManager = $injector.get("UsersManager");82 UsersManager = $injector.get("UsersManager");
82 ManagerHelperService = $injector.get("ManagerHelperService");83 ManagerHelperService = $injector.get("ManagerHelperService");
83 ErrorService = $injector.get("ErrorService");84 ErrorService = $injector.get("ErrorService");
85 ConverterService = $injector.get("ConverterService");
84 }));86 }));
8587
86 var fabric, vlan, space, subnet;88 var fabric, vlan, space, subnet;
@@ -209,6 +211,158 @@
209 expect($rootScope.title).toBe(subnet.cidr + " (" + subnet.name + ")");211 expect($rootScope.title).toBe(subnet.cidr + " (" + subnet.name + ")");
210 });212 });
211213
214 describe("ipSort", function() {
215
216 it("calls ipv4ToInteger when ipVersion == 4", function() {
217 var controller = makeControllerResolveSetActiveItem();
218 $scope.ipVersion = 4;
219 var expected = {};
220 spyOn(ConverterService, "ipv4ToInteger").and.returnValue(expected);
221 var ipAddress = {
222 ip: {}
223 };
224 var observed = $scope.ipSort(ipAddress);
225 expect(ConverterService.ipv4ToInteger).toHaveBeenCalledWith(
226 ipAddress.ip);
227 expect(observed).toBe(expected);
228 });
229
230 it("calls ipv6Expand when ipVersion == 6", function() {
231 var controller = makeControllerResolveSetActiveItem();
232 $scope.ipVersion = 6;
233 var expected = {};
234 spyOn(ConverterService, "ipv6Expand").and.returnValue(expected);
235 var ipAddress = {
236 ip: {}
237 };
238 var observed = $scope.ipSort(ipAddress);
239 expect(ConverterService.ipv6Expand).toHaveBeenCalledWith(
240 ipAddress.ip);
241 expect(observed).toBe(expected);
242 });
243
244 it("is predicate default", function() {
245 var controller = makeControllerResolveSetActiveItem();
246 expect($scope.predicate).toBe($scope.ipSort);
247 });
248 });
249
250 describe("getAllocType", function() {
251
252 var scenarios = {
253 0: 'Automatic',
254 1: 'Static',
255 4: 'User reserved',
256 5: 'DHCP',
257 6: 'Observed',
258 7: 'Unknown'
259 };
260
261 angular.forEach(scenarios, function(expected, allocType) {
262 it("allocType( " + allocType + ") = " + expected, function() {
263 var controller = makeControllerResolveSetActiveItem();
264 expect($scope.getAllocType(allocType)).toBe(expected);
265 });
266 });
267 });
268
269 describe("allocTypeSort", function() {
270
271 it("calls getAllocType", function() {
272 var controller = makeControllerResolveSetActiveItem();
273 var expected = {};
274 spyOn($scope, "getAllocType").and.returnValue(expected);
275 var ipAddress = {
276 alloc_type: {}
277 };
278 var observed = $scope.allocTypeSort(ipAddress);
279 expect($scope.getAllocType).toHaveBeenCalledWith(
280 ipAddress.alloc_type);
281 expect(observed).toBe(expected);
282 });
283 });
284
285 describe("getNodeType", function() {
286
287 var scenarios = {
288 0: 'Machine',
289 1: 'Device',
290 2: 'Rack controller',
291 3: 'Region controller',
292 4: 'Rack and region controller',
293 5: 'Unknown'
294 };
295
296 angular.forEach(scenarios, function(expected, nodeType) {
297 it("nodeType( " + nodeType + ") = " + expected, function() {
298 var controller = makeControllerResolveSetActiveItem();
299 expect($scope.getNodeType(nodeType)).toBe(expected);
300 });
301 });
302 });
303
304 describe("nodeTypeSort", function() {
305
306 it("calls getNodeType", function() {
307 var controller = makeControllerResolveSetActiveItem();
308 var expected = {};
309 spyOn($scope, "getNodeType").and.returnValue(expected);
310 var ipAddress = {
311 node_summary: {
312 node_type: {}
313 }
314 };
315 var observed = $scope.nodeTypeSort(ipAddress);
316 expect($scope.getNodeType).toHaveBeenCalledWith(
317 ipAddress.node_summary.node_type);
318 expect(observed).toBe(expected);
319 });
320 });
321
322 describe("ownerSort", function() {
323
324 it("returns owner", function() {
325 var controller = makeControllerResolveSetActiveItem();
326 var ipAddress = {
327 user: makeName("owner")
328 };
329 var observed = $scope.ownerSort(ipAddress);
330 expect(observed).toBe(ipAddress.user);
331 });
332
333 it("returns MAAS for empty string", function() {
334 var controller = makeControllerResolveSetActiveItem();
335 var ipAddress = {
336 user: ""
337 };
338 var observed = $scope.ownerSort(ipAddress);
339 expect(observed).toBe("MAAS");
340 });
341
342 it("returns MAAS for null", function() {
343 var controller = makeControllerResolveSetActiveItem();
344 var ipAddress = {
345 user: null
346 };
347 var observed = $scope.ownerSort(ipAddress);
348 expect(observed).toBe("MAAS");
349 });
350 });
351
352 describe("sortIPTable", function() {
353
354 it("sets predicate and inverts reverse", function() {
355 var controller = makeControllerResolveSetActiveItem();
356 $scope.reverse = true;
357 var predicate = {};
358 $scope.sortIPTable(predicate);
359 expect($scope.predicate).toBe(predicate);
360 expect($scope.reverse).toBe(false);
361 $scope.sortIPTable(predicate);
362 expect($scope.reverse).toBe(true);
363 });
364 });
365
212 describe("deleteButton", function() {366 describe("deleteButton", function() {
213367
214 it("confirms delete", function() {368 it("confirms delete", function() {
215369
=== modified file 'src/maasserver/static/js/angular/services/converter.js'
--- src/maasserver/static/js/angular/services/converter.js 2016-03-28 13:54:47 +0000
+++ src/maasserver/static/js/angular/services/converter.js 2016-06-16 14:50:25 +0000
@@ -86,4 +86,59 @@
86 this.roundByBlockSize = function(bytes, block_size) {86 this.roundByBlockSize = function(bytes, block_size) {
87 return block_size * Math.floor(bytes / block_size);87 return block_size * Math.floor(bytes / block_size);
88 };88 };
89
90 // Convert string ipv4 address into octets array.
91 this.ipv4ToOctets = function(ipAddress) {
92 var parts = ipAddress.split('.');
93 var octets = [];
94 angular.forEach(parts, function(part) {
95 octets.push(parseInt(part, 10));
96 });
97 return octets;
98 };
99
100 // Convert string ipv4 address into integer.
101 this.ipv4ToInteger = function(ipAddress) {
102 var octets = this.ipv4ToOctets(ipAddress);
103 return (
104 (octets[0] * Math.pow(256,3)) +
105 (octets[1] * Math.pow(256,2)) +
106 (octets[2] * 256) + octets[3]);
107 };
108
109 // Convert ipv6 address to a full ipv6 address, removing the
110 // '::' shortcut and padding each group with zeros.
111 this.ipv6Expand = function(ipAddress) {
112 var i, expandedAddress = ipAddress;
113 if(expandedAddress.indexOf("::") !== -1) {
114 // '::' is present so replace it with the required
115 // number of '0000:' based on its location in the string.
116 var split = ipAddress.split("::");
117 var groups = 0;
118 for(i = 0; i < split.length; i++) {
119 groups += split[i].split(":").length;
120 }
121 expandedAddress = split[0] + ":";
122 for(i = 0; i < 8 - groups; i++) {
123 expandedAddress += "0000:";
124 }
125 expandedAddress += split[1];
126 }
127 // Pad the output of each part with zeros.
128 var output = [], parts = expandedAddress.split(":");
129 angular.forEach(parts, function(part) {
130 output.push("0000".substr(part.length) + part);
131 });
132 return output.join(":");
133 };
134
135 // Convert string ipv6 into groups array.
136 this.ipv6ToGroups = function(ipAddress) {
137 var groups = [];
138 var parts = this.ipv6Expand(ipAddress).split(":");
139 angular.forEach(parts, function(part) {
140 groups.push(parseInt(part, 16));
141 });
142 return groups;
143 };
89 });144 });
90145
=== modified file 'src/maasserver/static/js/angular/services/tests/test_converter.js'
--- src/maasserver/static/js/angular/services/tests/test_converter.js 2016-03-28 13:54:47 +0000
+++ src/maasserver/static/js/angular/services/tests/test_converter.js 2016-06-16 14:50:25 +0000
@@ -201,4 +201,108 @@
201 1024 * 1024 * 1024);201 1024 * 1024 * 1024);
202 });202 });
203 });203 });
204
205 describe("ipv4ToOctets", function() {
206
207 var scenarios = [
208 {
209 input: "192.168.1.1",
210 output: [192,168,1,1]
211 },
212 {
213 input: "172.16.1.1",
214 output: [172,16,1,1]
215 },
216 {
217 input: "10.1.1.1",
218 output: [10,1,1,1]
219 }
220 ];
221
222 angular.forEach(scenarios, function(scenario) {
223 it("converts: " + scenario.input, function() {
224 var result = ConverterService.ipv4ToOctets(scenario.input);
225 expect(result).toEqual(scenario.output);
226 });
227 });
228 });
229
230 describe("ipv4ToInteger", function() {
231
232 var scenarios = [
233 {
234 input: "192.168.1.1",
235 output: 3232235777
236 },
237 {
238 input: "172.16.1.1",
239 output: 2886729985
240 },
241 {
242 input: "10.1.1.1",
243 output: 167837953
244 }
245 ];
246
247 angular.forEach(scenarios, function(scenario) {
248 it("converts: " + scenario.input, function() {
249 var result = ConverterService.ipv4ToInteger(scenario.input);
250 expect(result).toEqual(scenario.output);
251 });
252 });
253 });
254
255 describe("ipv6Expand", function() {
256
257 var scenarios = [
258 {
259 input: "::1",
260 output: "0000:0000:0000:0000:0000:0000:0000:0001"
261 },
262 {
263 input: "2001:db8::1",
264 output: "2001:0db8:0000:0000:0000:0000:0000:0001"
265 },
266 {
267 input: "2001:db8:1::1",
268 output: "2001:0db8:0001:0000:0000:0000:0000:0001"
269 },
270 {
271 input: "2001:db8::",
272 output: "2001:0db8:0000:0000:0000:0000:0000:0000"
273 }
274 ];
275
276 angular.forEach(scenarios, function(scenario) {
277 it("expands: " + scenario.input, function() {
278 var result = ConverterService.ipv6Expand(scenario.input);
279 expect(result).toBe(scenario.output);
280 });
281 });
282 });
283
284 describe("ipv6ToGroups", function() {
285
286 var scenarios = [
287 {
288 input: "::1",
289 output: [0, 0, 0, 0, 0, 0, 0, 1]
290 },
291 {
292 input: "2001:db8::1",
293 output: [8193, 3512, 0, 0, 0, 0, 0, 1]
294 },
295 {
296 input: "2001:db8:1::1",
297 output: [8193, 3512, 1, 0, 0, 0, 0, 1]
298 }
299 ];
300
301 angular.forEach(scenarios, function(scenario) {
302 it("converts: " + scenario.input, function() {
303 var result = ConverterService.ipv6ToGroups(scenario.input);
304 expect(result).toEqual(scenario.output);
305 });
306 });
307 });
204});308});
205309
=== modified file 'src/maasserver/static/js/angular/services/validation.js'
--- src/maasserver/static/js/angular/services/validation.js 2016-03-28 13:54:47 +0000
+++ src/maasserver/static/js/angular/services/validation.js 2016-06-16 14:50:25 +0000
@@ -6,7 +6,8 @@
6 * Used by controllers to validate user inputs.6 * Used by controllers to validate user inputs.
7 */7 */
88
9angular.module('MAAS').service('ValidationService', function() {9angular.module('MAAS').service('ValidationService', [
10 'ConverterService', function(ConverterService) {
1011
11 // Pattern that matches a domainname.12 // Pattern that matches a domainname.
12 // XXX 2016-02-24 lamont: This also matches "example.com.",13 // XXX 2016-02-24 lamont: This also matches "example.com.",
@@ -50,47 +51,6 @@
50 return true;51 return true;
51 }52 }
5253
53 // Convert string ipv4 address into octets array.
54 function ipv4ToOctets(ipAddress) {
55 var parts = ipAddress.split('.');
56 var octets = [];
57 angular.forEach(parts, function(part) {
58 octets.push(parseInt(part, 10));
59 });
60 return octets;
61 }
62
63 // Convert ipv6 address to a full ipv6 address, removing the
64 // '::' shortcut.
65 function ipv6Expand(ipAddress) {
66 var i, expandedAddress = ipAddress;
67 if(expandedAddress.indexOf("::") !== -1) {
68 // '::' is present so replace it with the required
69 // number of '0000:' based on its location in the string.
70 var split = ipAddress.split("::");
71 var groups = 0;
72 for(i = 0; i < split.length; i++) {
73 groups += split[i].split(":").length;
74 }
75 expandedAddress = split[0] + ":";
76 for(i = 0; i < 8 - groups; i++) {
77 expandedAddress += "0000:";
78 }
79 expandedAddress += split[1];
80 }
81 return expandedAddress;
82 }
83
84 // Convert string ipv6 into octets array.
85 function ipv6ToOctets(ipAddress) {
86 var octets = [];
87 var parts = ipv6Expand(ipAddress).split(":");
88 angular.forEach(parts, function(part) {
89 octets.push(parseInt(part, 16));
90 });
91 return octets;
92 }
93
94 // Return true if the domainname is valid, false otherwise.54 // Return true if the domainname is valid, false otherwise.
95 this.validateDomainName = function(domainname) {55 this.validateDomainName = function(domainname) {
96 // Invalid if the domain is not a string, empty, or more than56 // Invalid if the domain is not a string, empty, or more than
@@ -140,8 +100,8 @@
140 ipAddress.indexOf(':') === -1) {100 ipAddress.indexOf(':') === -1) {
141 return false;101 return false;
142 }102 }
143 var expandedAddress = ipv6Expand(ipAddress);103 var expandedAddress = ConverterService.ipv6Expand(ipAddress);
144 var octets = ipv6ToOctets(expandedAddress);104 var octets = ConverterService.ipv6ToGroups(expandedAddress);
145 if(octets.length !== 8) {105 if(octets.length !== 8) {
146 return false;106 return false;
147 }107 }
@@ -180,14 +140,14 @@
180 if(this.validateIPv4(ipAddress) &&140 if(this.validateIPv4(ipAddress) &&
181 this.validateIPv4(networkAddress)) {141 this.validateIPv4(networkAddress)) {
182 return cidrMatcher(142 return cidrMatcher(
183 ipv4ToOctets(ipAddress),143 ConverterService.ipv4ToOctets(ipAddress),
184 ipv4ToOctets(networkAddress),144 ConverterService.ipv4ToOctets(networkAddress),
185 8, cidrBits);145 8, cidrBits);
186 } else if(this.validateIPv6(ipAddress) &&146 } else if(this.validateIPv6(ipAddress) &&
187 this.validateIPv6(networkAddress)) {147 this.validateIPv6(networkAddress)) {
188 return cidrMatcher(148 return cidrMatcher(
189 ipv6ToOctets(ipAddress),149 ConverterService.ipv6ToGroups(ipAddress),
190 ipv6ToOctets(networkAddress),150 ConverterService.ipv6ToGroups(networkAddress),
191 16, cidrBits);151 16, cidrBits);
192 }152 }
193 return false;153 return false;
@@ -210,9 +170,9 @@
210170
211 // Check that each octet is of the ip address is more or equal171 // Check that each octet is of the ip address is more or equal
212 // to the low address and less or equal to the high address.172 // to the low address and less or equal to the high address.
213 ipOctets = ipv4ToOctets(ipAddress);173 ipOctets = ConverterService.ipv4ToOctets(ipAddress);
214 lowOctets = ipv4ToOctets(lowAddress);174 lowOctets = ConverterService.ipv4ToOctets(lowAddress);
215 highOctets = ipv4ToOctets(highAddress);175 highOctets = ConverterService.ipv4ToOctets(highAddress);
216 for(i = 0; i < 4; i++) {176 for(i = 0; i < 4; i++) {
217 if(ipOctets[i] > highOctets[i] ||177 if(ipOctets[i] > highOctets[i] ||
218 ipOctets[i] < lowOctets[i]) {178 ipOctets[i] < lowOctets[i]) {
@@ -226,9 +186,9 @@
226186
227 // Check that each octet is of the ip address is more or equal187 // Check that each octet is of the ip address is more or equal
228 // to the low address and less or equal to the high address.188 // to the low address and less or equal to the high address.
229 ipOctets = ipv6ToOctets(ipAddress);189 ipOctets = ConverterService.ipv6ToGroups(ipAddress);
230 lowOctets = ipv6ToOctets(lowAddress);190 lowOctets = ConverterService.ipv6ToGroups(lowAddress);
231 highOctets = ipv6ToOctets(highAddress);191 highOctets = ConverterService.ipv6ToGroups(highAddress);
232 for(i = 0; i < 8; i++) {192 for(i = 0; i < 8; i++) {
233 if(ipOctets[i] > highOctets[i] ||193 if(ipOctets[i] > highOctets[i] ||
234 ipOctets[i] < lowOctets[i]) {194 ipOctets[i] < lowOctets[i]) {
@@ -239,4 +199,4 @@
239 }199 }
240 return false;200 return false;
241 };201 };
242 });202 }]);
243203
=== modified file 'src/maasserver/static/partials/subnet-details.html'
--- src/maasserver/static/partials/subnet-details.html 2016-06-09 20:08:35 +0000
+++ src/maasserver/static/partials/subnet-details.html 2016-06-16 14:50:25 +0000
@@ -250,36 +250,33 @@
250 <table class="table-listing">250 <table class="table-listing">
251 <thead>251 <thead>
252 <tr class="table-listing__row">252 <tr class="table-listing__row">
253 <th class="table-listing__header table-col--20">IP Address</th>253 <th class="table-listing__header table-col--20">
254 <th class="table-listing__header table-col--10">Type</th>254 <a href="" data-ng-click="sortIPTable(ipSort)" data-ng-class="{sort: predicate === ipSort, 'sort-asc': reverse === false, 'sort-desc': reverse === true}">IP Address</a>
255 <th class="table-listing__header table-col--15">Node</th>255 </th>
256 <th class="table-listing__header table-col--10">Interface</th>256 <th class="table-listing__header table-col--10">
257 <th class="table-listing__header table-col--10">Usage</th>257 <a href="" data-ng-click="sortIPTable(allocTypeSort)" data-ng-class="{sort: predicate === allocTypeSort, 'sort-asc': reverse === false, 'sort-desc': reverse === true}">Type</a>
258 <th class="table-listing__header table-col--10">Owner</th>258 </th>
259 <th class="table-listing__header table-col--25">Last seen</th>259 <th class="table-listing__header table-col--15">
260 <!-- XXX mpontillo need data for this -->260 <a href="" data-ng-click="sortIPTable('node_summary.hostname')" data-ng-class="{sort: predicate === 'node_summary.hostname', 'sort-asc': reverse === false, 'sort-desc': reverse === true}">Node</a>
261 <!--261 </th>
262 <th class="table-listing__header table-col--25" colspan="2">262 <th class="table-listing__header table-col--10">
263 <a class="table-listing__header-link" href="#">Purpose</a>263 <a href="" data-ng-click="sortIPTable('node_summary.via')" data-ng-class="{sort: predicate === 'node_summary.via', 'sort-asc': reverse === false, 'sort-desc': reverse === true}">Interface</a>
264 <span class="divide"></span>264 </th>
265 <a class="table-listing__header-link active" href="#">Last seen</a>265 <th class="table-listing__header table-col--10">
266 <span class="divide"></span>266 <a href="" data-ng-click="sortIPTable(nodeTypeSort)" data-ng-class="{sort: predicate === nodeTypeSort, 'sort-asc': reverse === false, 'sort-desc': reverse === true}">Usage</a>
267 <a class="table-listing__header-link" href="#">Detected</a>267 </th>
268 </th>268 <th class="table-listing__header table-col--10">
269 -->269 <a href="" data-ng-click="sortIPTable(ownerSort)" data-ng-class="{sort: predicate === ownerSort, 'sort-asc': reverse === false, 'sort-desc': reverse === true}">Owner</a>
270 </th>
271 <th class="table-listing__header table-col--25">
272 <a href="" data-ng-click="sortIPTable('updated')" data-ng-class="{sort: predicate === 'updated', 'sort-asc': reverse === false, 'sort-desc': reverse === true}">Last seen</a>
273 </th>
270 </tr>274 </tr>
271 </thead>275 </thead>
272 <tbody>276 <tbody>
273 <tr data-ng-repeat="ip in subnet.ip_addresses">277 <tr data-ng-repeat="ip in subnet.ip_addresses | orderBy:predicate:reverse track by ip.ip">
274 <td class="table-col--20">{$ ip.ip $}</td>278 <td class="table-col--20">{$ ip.ip $}</td>
275 <td class="table-col--10" data-ng-switch="ip.alloc_type">279 <td class="table-col--10">{$ getAllocType(ip.alloc_type) $}</td>
276 <span data-ng-switch-when="0">Automatic</span>
277 <span data-ng-switch-when="1">Static</span>
278 <span data-ng-switch-when="4">User reserved</span>
279 <span data-ng-switch-when="5">DHCP</span>
280 <span data-ng-switch-when="6">Observed</span>
281 <span data-ng-switch-default>Unknown</span>
282 </td>
283 <td class="table-col--15" data-ng-switch="ip.node_summary.node_type">280 <td class="table-col--15" data-ng-switch="ip.node_summary.node_type">
284 <span data-ng-switch-when="0"><a href="#/node/{$ ip.node_summary.system_id $}">{$ ip.node_summary.hostname $}</a></span>281 <span data-ng-switch-when="0"><a href="#/node/{$ ip.node_summary.system_id $}">{$ ip.node_summary.hostname $}</a></span>
285 <span data-ng-switch-when="1">{$ ip.node_summary.hostname $}</span>282 <span data-ng-switch-when="1">{$ ip.node_summary.hostname $}</span>
@@ -295,14 +292,7 @@
295 <span data-ng-switch-when="4">{$ ip.node_summary.via $}</span>292 <span data-ng-switch-when="4">{$ ip.node_summary.via $}</span>
296 <span data-ng-switch-default>Unknown</span>293 <span data-ng-switch-default>Unknown</span>
297 </td>294 </td>
298 <td class="table-col--10" data-ng-switch="ip.node_summary.node_type">295 <td class="table-col--10">{$ getNodeType(ip.node_summary.node_type) $}</td>
299 <span data-ng-switch-when="0">Machine</span>
300 <span data-ng-switch-when="1">Device</span>
301 <span data-ng-switch-when="2">Rack controller</span>
302 <span data-ng-switch-when="3">Region controller</span>
303 <span data-ng-switch-when="4">Rack and region controller</span>
304 <span data-ng-switch-default>Unknown</span>
305 </td>
306 <td class="table-col--10">{$ ip.user ? ip.user : "MAAS" $}</td>296 <td class="table-col--10">{$ ip.user ? ip.user : "MAAS" $}</td>
307 <td class="table-col--25">297 <td class="table-col--25">
308 <time>{$ ip.updated $}</time>298 <time>{$ ip.updated $}</time>