1cd789508SIftekharul Islam/** 2cd789508SIftekharul Islam * Controller for network 3cd789508SIftekharul Islam * 4cd789508SIftekharul Islam * @module app/configuration 5cd789508SIftekharul Islam * @exports networkController 6cd789508SIftekharul Islam * @name networkController 7cd789508SIftekharul Islam */ 8cd789508SIftekharul Islam 9cd789508SIftekharul Islamwindow.angular && (function(angular) { 10cd789508SIftekharul Islam 'use strict'; 11cd789508SIftekharul Islam 12d27bb135SAndrew Geissler angular.module('app.configuration').controller('networkController', [ 130af165b9SGunnar Mills '$scope', '$window', 'APIUtils', 'dataService', '$timeout', '$route', '$q', 140af165b9SGunnar Mills function($scope, $window, APIUtils, dataService, $timeout, $route, $q) { 15cd789508SIftekharul Islam $scope.dataService = dataService; 162a489554SIftekharul Islam $scope.network = {}; 17a45c3852SGunnar Mills $scope.old_interface = {}; 182a489554SIftekharul Islam $scope.interface = {}; 192a489554SIftekharul Islam $scope.networkDevice = false; 20ba5e3f34SAndrew Geissler $scope.hostname = ''; 21e9f5fe77SGunnar Mills $scope.defaultgateway = ''; 227ddc7274SGunnar Mills $scope.set_network_error = ''; 237ddc7274SGunnar Mills $scope.set_network_success = false; 247ddc7274SGunnar Mills $scope.selectedInterface = ''; 25d01504cfSGunnar Mills $scope.confirm_settings = false; 2684981f0aSGunnar Mills $scope.loading = false; 27971ac1aaSbeccabroek $scope.IPV4s_to_delete = []; 282a489554SIftekharul Islam 29a3f75320SGunnar Mills loadNetworkInfo(); 30a3f75320SGunnar Mills 312a489554SIftekharul Islam $scope.selectInterface = function(interfaceId) { 322a489554SIftekharul Islam $scope.interface = $scope.network.interfaces[interfaceId]; 33a45c3852SGunnar Mills // Copy the interface so we know later if changes were made to the page 34a45c3852SGunnar Mills $scope.old_interface = JSON.parse(JSON.stringify($scope.interface)); 352a489554SIftekharul Islam $scope.selectedInterface = interfaceId; 362a489554SIftekharul Islam $scope.networkDevice = false; 37ba5e3f34SAndrew Geissler }; 38bc3ab72cSGunnar Mills 39bc3ab72cSGunnar Mills $scope.addDNSField = function() { 40bc3ab72cSGunnar Mills $scope.interface.Nameservers.push(''); 41bc3ab72cSGunnar Mills }; 42bc3ab72cSGunnar Mills 43cff61508Sbeccabroek $scope.removeDNSField = function(index) { 44cff61508Sbeccabroek $scope.interface.Nameservers.splice(index, 1); 45cff61508Sbeccabroek }; 46cff61508Sbeccabroek 47*1a0e7d06Sbeccabroek $scope.addIpv4Field = function() { 48*1a0e7d06Sbeccabroek $scope.interface.ipv4.values.push( 49*1a0e7d06Sbeccabroek {Address: '', PrefixLength: '', Gateway: ''}); 50*1a0e7d06Sbeccabroek }; 51*1a0e7d06Sbeccabroek 52971ac1aaSbeccabroek $scope.removeIpv4Address = function(index) { 53971ac1aaSbeccabroek // Check if the IPV4 being removed has an id. This indicates that it is 54971ac1aaSbeccabroek // an existing address and needs to be removed in the back end. 55971ac1aaSbeccabroek if ($scope.interface.ipv4.values[index].id) { 56971ac1aaSbeccabroek $scope.IPV4s_to_delete.push($scope.interface.ipv4.values[index]); 57971ac1aaSbeccabroek } 58971ac1aaSbeccabroek $scope.interface.ipv4.values.splice(index, 1); 59971ac1aaSbeccabroek }; 60971ac1aaSbeccabroek 617ddc7274SGunnar Mills $scope.setNetworkSettings = function() { 62d01504cfSGunnar Mills // Hides the confirm network settings modal 63d01504cfSGunnar Mills $scope.confirm_settings = false; 647ddc7274SGunnar Mills $scope.set_network_error = ''; 657ddc7274SGunnar Mills $scope.set_network_success = false; 6684981f0aSGunnar Mills $scope.loading = true; 67dca79d73SGunnar Mills var promises = []; 68dca79d73SGunnar Mills 69659651e8SGunnar Mills // MAC Address are case-insensitive 70659651e8SGunnar Mills if ($scope.interface.MACAddress.toLowerCase() != 71659651e8SGunnar Mills dataService.mac_address.toLowerCase()) { 72dca79d73SGunnar Mills promises.push(setMACAddress()); 73659651e8SGunnar Mills } 74659651e8SGunnar Mills if ($scope.defaultgateway != dataService.defaultgateway) { 75dca79d73SGunnar Mills promises.push(setDefaultGateway()); 76659651e8SGunnar Mills } 77659651e8SGunnar Mills if ($scope.hostname != dataService.hostname) { 78309e06abSGunnar Mills promises.push(setHostname()); 79659651e8SGunnar Mills } 80cb2c3060SGunnar Mills if ($scope.interface.DHCPEnabled != $scope.old_interface.DHCPEnabled) { 81cb2c3060SGunnar Mills promises.push(setDHCPEnabled()); 82cb2c3060SGunnar Mills } 83309e06abSGunnar Mills 8482658298SGunnar Mills // Remove any empty strings from the array. Important because we add an 8582658298SGunnar Mills // empty string to the end so the user can add a new DNS server, if the 8682658298SGunnar Mills // user doesn't fill out the field, we don't want to add. 8782658298SGunnar Mills $scope.interface.Nameservers = 8882658298SGunnar Mills $scope.interface.Nameservers.filter(Boolean); 890646782dSGunnar Mills // toString() is a cheap way to compare 2 string arrays 900646782dSGunnar Mills if ($scope.interface.Nameservers.toString() != 910646782dSGunnar Mills $scope.old_interface.Nameservers.toString()) { 920646782dSGunnar Mills promises.push(setNameservers()); 930646782dSGunnar Mills } 940646782dSGunnar Mills 95a45c3852SGunnar Mills // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways 96a45c3852SGunnar Mills if (!$scope.interface.DHCPEnabled) { 97971ac1aaSbeccabroek // Delete existing IPV4 addresses that were removed 98971ac1aaSbeccabroek promises.push(removeIPV4s()); 99*1a0e7d06Sbeccabroek // Update any changed IPV4 addresses and add new 100a45c3852SGunnar Mills for (var i in $scope.interface.ipv4.values) { 1016549114eSGunnar Mills if (!APIUtils.validIPV4IP( 1026549114eSGunnar Mills $scope.interface.ipv4.values[i].Address)) { 1036549114eSGunnar Mills $scope.set_network_error = 1046549114eSGunnar Mills $scope.interface.ipv4.values[i].Address + 1056549114eSGunnar Mills ' invalid IP parameter'; 1066549114eSGunnar Mills $scope.loading = false; 1076549114eSGunnar Mills return; 1086549114eSGunnar Mills } 1096549114eSGunnar Mills if (!APIUtils.validIPV4IP( 1106549114eSGunnar Mills $scope.interface.ipv4.values[i].Gateway)) { 1116549114eSGunnar Mills $scope.set_network_error = 1126549114eSGunnar Mills $scope.interface.ipv4.values[i].Address + 1136549114eSGunnar Mills ' invalid gateway parameter'; 1146549114eSGunnar Mills $scope.loading = false; 1156549114eSGunnar Mills return; 1166549114eSGunnar Mills } 1176549114eSGunnar Mills // The netmask prefix length will be undefined if outside range 1186549114eSGunnar Mills if (!$scope.interface.ipv4.values[i].PrefixLength) { 1196549114eSGunnar Mills $scope.set_network_error = 1206549114eSGunnar Mills $scope.interface.ipv4.values[i].Address + 1216549114eSGunnar Mills ' invalid Prefix Length parameter'; 1226549114eSGunnar Mills $scope.loading = false; 1236549114eSGunnar Mills return; 1246549114eSGunnar Mills } 125*1a0e7d06Sbeccabroek if ($scope.interface.ipv4.values[i].update_address || 126*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[i].update_gateway || 127*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[i].update_prefix) { 128*1a0e7d06Sbeccabroek // If IPV4 has an id it means it already exists in the back end, 129*1a0e7d06Sbeccabroek // and in order to update it is required to remove previous IPV4 130*1a0e7d06Sbeccabroek // address and add new one. See openbmc/openbmc/issues/2163. 131*1a0e7d06Sbeccabroek // TODO: update to use PUT once issue 2163 is resolved. 132*1a0e7d06Sbeccabroek if ($scope.interface.ipv4.values[i].id) { 133*1a0e7d06Sbeccabroek promises.push(updateIPV4(i)); 134*1a0e7d06Sbeccabroek } else { 135*1a0e7d06Sbeccabroek promises.push(addIPV4(i)); 136*1a0e7d06Sbeccabroek } 137a45c3852SGunnar Mills } 138a45c3852SGunnar Mills } 139a45c3852SGunnar Mills } 140a45c3852SGunnar Mills 1410af165b9SGunnar Mills if (promises.length) { 142dca79d73SGunnar Mills $q.all(promises).finally(function() { 14384981f0aSGunnar Mills $scope.loading = false; 1440af165b9SGunnar Mills if (!$scope.set_network_error) { 145dca79d73SGunnar Mills $scope.set_network_success = true; 1460af165b9SGunnar Mills // Since an IPV4 interface (e.g. IP address, gateway, or netmask) 1470af165b9SGunnar Mills // edit is a delete then an add and the GUI can't calculate the 1480af165b9SGunnar Mills // interface id (e.g. 5c083707) beforehand and it is not returned 1490af165b9SGunnar Mills // by the REST call, openbmc#3227, reload the page after an edit, 1500af165b9SGunnar Mills // which makes a 2nd REST call. 1510af165b9SGunnar Mills // Do this for all network changes due to the possibility of a set 1520af165b9SGunnar Mills // network failing even though it returned success, openbmc#1641, 1530af165b9SGunnar Mills // and to update dataService and old_interface to know which 1540af165b9SGunnar Mills // data has changed if the user continues to edit network 1550af165b9SGunnar Mills // settings. 1560af165b9SGunnar Mills // TODO: The reload is not ideal. Revisit this. 1570af165b9SGunnar Mills $timeout(function() { 158a3f75320SGunnar Mills loadNetworkInfo(); 1590af165b9SGunnar Mills }, 4000); 160dca79d73SGunnar Mills } 161dca79d73SGunnar Mills }); 1620af165b9SGunnar Mills } else { 1630af165b9SGunnar Mills $scope.loading = false; 1640af165b9SGunnar Mills } 165dca79d73SGunnar Mills }; 166dca79d73SGunnar Mills 167dca79d73SGunnar Mills function setMACAddress() { 168dca79d73SGunnar Mills return APIUtils 1697ddc7274SGunnar Mills .setMACAddress( 1707ddc7274SGunnar Mills $scope.selectedInterface, $scope.interface.MACAddress) 1717ddc7274SGunnar Mills .then( 172dca79d73SGunnar Mills function(data) {}, 1737ddc7274SGunnar Mills function(error) { 174dca79d73SGunnar Mills console.log(JSON.stringify(error)); 1757ddc7274SGunnar Mills $scope.set_network_error = 'MAC Address'; 1767ddc7274SGunnar Mills }); 177dca79d73SGunnar Mills } 178dca79d73SGunnar Mills 179dca79d73SGunnar Mills function setDefaultGateway() { 180dca79d73SGunnar Mills return APIUtils.setDefaultGateway($scope.defaultgateway) 181dca79d73SGunnar Mills .then( 182dca79d73SGunnar Mills function(data) {}, 183dca79d73SGunnar Mills function(error) { 184dca79d73SGunnar Mills console.log(JSON.stringify(error)); 185dca79d73SGunnar Mills $scope.set_network_error = 'Default Gateway'; 186dca79d73SGunnar Mills }); 187dca79d73SGunnar Mills } 188309e06abSGunnar Mills 189309e06abSGunnar Mills function setHostname() { 190309e06abSGunnar Mills return APIUtils.setHostname($scope.hostname) 191309e06abSGunnar Mills .then( 192309e06abSGunnar Mills function(data) {}, 193309e06abSGunnar Mills function(error) { 194309e06abSGunnar Mills console.log(JSON.stringify(error)); 195309e06abSGunnar Mills $scope.set_network_error = 'Hostname'; 196309e06abSGunnar Mills }); 197309e06abSGunnar Mills } 198309e06abSGunnar Mills 199cb2c3060SGunnar Mills function setDHCPEnabled() { 200cb2c3060SGunnar Mills return APIUtils 201cb2c3060SGunnar Mills .setDHCPEnabled( 202cb2c3060SGunnar Mills $scope.selectedInterface, $scope.interface.DHCPEnabled) 203cb2c3060SGunnar Mills .then( 204cb2c3060SGunnar Mills function(data) {}, 205cb2c3060SGunnar Mills function(error) { 206cb2c3060SGunnar Mills console.log(JSON.stringify(error)); 207cb2c3060SGunnar Mills $scope.set_network_error = 'DHCP'; 208cb2c3060SGunnar Mills }); 209cb2c3060SGunnar Mills } 210cb2c3060SGunnar Mills 2110646782dSGunnar Mills function setNameservers() { 21282658298SGunnar Mills // Nameservers does not allow an empty array, since we remove all empty 2139863d121SGunnar Mills // strings above, could have an empty array. TODO: openbmc/openbmc#3240 21482658298SGunnar Mills if ($scope.interface.Nameservers.length == 0) { 21582658298SGunnar Mills $scope.interface.Nameservers.push(''); 21682658298SGunnar Mills } 2170646782dSGunnar Mills return APIUtils 2180646782dSGunnar Mills .setNameservers( 2190646782dSGunnar Mills $scope.selectedInterface, $scope.interface.Nameservers) 2200646782dSGunnar Mills .then( 2210646782dSGunnar Mills function(data) {}, 2220646782dSGunnar Mills function(error) { 2230646782dSGunnar Mills console.log(JSON.stringify(error)); 2240646782dSGunnar Mills $scope.set_network_error = 'DNS Servers'; 2250646782dSGunnar Mills }); 2260646782dSGunnar Mills } 2270646782dSGunnar Mills 228971ac1aaSbeccabroek function removeIPV4s() { 229971ac1aaSbeccabroek return $scope.IPV4s_to_delete.map(function(ipv4) { 230971ac1aaSbeccabroek return APIUtils.deleteIPV4($scope.selectedInterface, ipv4.id) 231971ac1aaSbeccabroek .then( 232971ac1aaSbeccabroek function(data) {}, 233971ac1aaSbeccabroek function(error) { 234971ac1aaSbeccabroek console.log(JSON.stringify(error)); 235971ac1aaSbeccabroek $scope.set_network_error = ipv4.Address; 236971ac1aaSbeccabroek }) 237971ac1aaSbeccabroek }); 238971ac1aaSbeccabroek } 239971ac1aaSbeccabroek 240*1a0e7d06Sbeccabroek function addIPV4(index) { 241*1a0e7d06Sbeccabroek return APIUtils 242*1a0e7d06Sbeccabroek .addIPV4( 243*1a0e7d06Sbeccabroek $scope.selectedInterface, 244*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Address, 245*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].PrefixLength, 246*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Gateway) 247*1a0e7d06Sbeccabroek .then( 248*1a0e7d06Sbeccabroek function(data) {}, 249*1a0e7d06Sbeccabroek function(error) { 250*1a0e7d06Sbeccabroek console.log(JSON.stringify(error)); 251*1a0e7d06Sbeccabroek $scope.set_network_error = 252*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Address; 253*1a0e7d06Sbeccabroek }) 254*1a0e7d06Sbeccabroek } 255*1a0e7d06Sbeccabroek 256*1a0e7d06Sbeccabroek function updateIPV4(index) { 257a45c3852SGunnar Mills // The correct way to edit an IPV4 interface is to remove it and then 258a45c3852SGunnar Mills // add a new one 259a45c3852SGunnar Mills return APIUtils 260a45c3852SGunnar Mills .deleteIPV4( 261*1a0e7d06Sbeccabroek $scope.selectedInterface, 262*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].id) 263a45c3852SGunnar Mills .then( 264a45c3852SGunnar Mills function(data) { 265a45c3852SGunnar Mills return APIUtils 266a45c3852SGunnar Mills .addIPV4( 267a45c3852SGunnar Mills $scope.selectedInterface, 268a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address, 269a45c3852SGunnar Mills $scope.interface.ipv4.values[index].PrefixLength, 270a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Gateway) 271a45c3852SGunnar Mills .then( 272a45c3852SGunnar Mills function(data) {}, 273a45c3852SGunnar Mills function(error) { 274a45c3852SGunnar Mills console.log(JSON.stringify(error)); 275a45c3852SGunnar Mills $scope.set_network_error = 276a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address; 277a45c3852SGunnar Mills }); 278a45c3852SGunnar Mills }, 279a45c3852SGunnar Mills function(error) { 280a45c3852SGunnar Mills console.log(JSON.stringify(error)); 281a45c3852SGunnar Mills $scope.set_network_error = 282a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address; 283a45c3852SGunnar Mills }); 284a45c3852SGunnar Mills } 285a45c3852SGunnar Mills 2869a0094dcSGunnar Mills $scope.refresh = function() { 287a3f75320SGunnar Mills loadNetworkInfo(); 2889a0094dcSGunnar Mills }; 289a3f75320SGunnar Mills 290a3f75320SGunnar Mills function loadNetworkInfo() { 2912a489554SIftekharul Islam APIUtils.getNetworkInfo().then(function(data) { 292659651e8SGunnar Mills dataService.setNetworkInfo(data); 2932a489554SIftekharul Islam $scope.network = data.formatted_data; 2942a489554SIftekharul Islam $scope.hostname = data.hostname; 295e9f5fe77SGunnar Mills $scope.defaultgateway = data.defaultgateway; 2962a489554SIftekharul Islam if ($scope.network.interface_ids.length) { 297ffdef96dSRebecca Shaw // Use the first network interface if the user hasn't chosen one 298a3f75320SGunnar Mills if (!$scope.selectedInterface || 299a3f75320SGunnar Mills !$scope.network.interfaces[$scope.selectedInterface]) { 3002a489554SIftekharul Islam $scope.selectedInterface = $scope.network.interface_ids[0]; 301a3f75320SGunnar Mills } 302d27bb135SAndrew Geissler $scope.interface = 303d27bb135SAndrew Geissler $scope.network.interfaces[$scope.selectedInterface]; 304a45c3852SGunnar Mills // Copy the interface so we know later if changes were made to the 305a45c3852SGunnar Mills // page 306a45c3852SGunnar Mills $scope.old_interface = JSON.parse(JSON.stringify($scope.interface)); 3072a489554SIftekharul Islam } 308*1a0e7d06Sbeccabroek // Add id values and update flags to corresponding IPV4 objects 309971ac1aaSbeccabroek for (var i = 0; i < $scope.interface.ipv4.values.length; i++) { 310971ac1aaSbeccabroek $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i]; 311*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[i].update_address = false; 312*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[i].update_gateway = false; 313*1a0e7d06Sbeccabroek $scope.interface.ipv4.values[i].update_prefix = false; 314971ac1aaSbeccabroek } 3152a489554SIftekharul Islam }); 316cd789508SIftekharul Islam } 317a3f75320SGunnar Mills } 318ba5e3f34SAndrew Geissler ]); 319cd789508SIftekharul Islam})(angular); 320