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', 1427ce84d2Sbeccabroek 'toastService', 159a3b5422Sbeccabroek function( 1627ce84d2Sbeccabroek $scope, $window, APIUtils, dataService, $timeout, $route, $q, 1727ce84d2Sbeccabroek toastService) { 18cd789508SIftekharul Islam $scope.dataService = dataService; 192a489554SIftekharul Islam $scope.network = {}; 20067a1cd1Sbeccabroek $scope.oldInterface = {}; 212a489554SIftekharul Islam $scope.interface = {}; 222a489554SIftekharul Islam $scope.networkDevice = false; 23ba5e3f34SAndrew Geissler $scope.hostname = ''; 24067a1cd1Sbeccabroek $scope.defaultGateway = ''; 257ddc7274SGunnar Mills $scope.selectedInterface = ''; 26067a1cd1Sbeccabroek $scope.confirmSettings = false; 2784981f0aSGunnar Mills $scope.loading = false; 28067a1cd1Sbeccabroek $scope.ipv4sToDelete = []; 292a489554SIftekharul Islam 30a3f75320SGunnar Mills loadNetworkInfo(); 31a3f75320SGunnar Mills 322a489554SIftekharul Islam $scope.selectInterface = function(interfaceId) { 332a489554SIftekharul Islam $scope.interface = $scope.network.interfaces[interfaceId]; 34a45c3852SGunnar Mills // Copy the interface so we know later if changes were made to the page 35067a1cd1Sbeccabroek $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface)); 362a489554SIftekharul Islam $scope.selectedInterface = interfaceId; 372a489554SIftekharul Islam $scope.networkDevice = false; 38ba5e3f34SAndrew Geissler }; 39bc3ab72cSGunnar Mills 40bc3ab72cSGunnar Mills $scope.addDNSField = function() { 41bc3ab72cSGunnar Mills $scope.interface.Nameservers.push(''); 42bc3ab72cSGunnar Mills }; 43bc3ab72cSGunnar Mills 44cff61508Sbeccabroek $scope.removeDNSField = function(index) { 45cff61508Sbeccabroek $scope.interface.Nameservers.splice(index, 1); 46cff61508Sbeccabroek }; 47cff61508Sbeccabroek 481a0e7d06Sbeccabroek $scope.addIpv4Field = function() { 491a0e7d06Sbeccabroek $scope.interface.ipv4.values.push( 501a0e7d06Sbeccabroek {Address: '', PrefixLength: '', Gateway: ''}); 511a0e7d06Sbeccabroek }; 521a0e7d06Sbeccabroek 53971ac1aaSbeccabroek $scope.removeIpv4Address = function(index) { 54971ac1aaSbeccabroek // Check if the IPV4 being removed has an id. This indicates that it is 55971ac1aaSbeccabroek // an existing address and needs to be removed in the back end. 56971ac1aaSbeccabroek if ($scope.interface.ipv4.values[index].id) { 57067a1cd1Sbeccabroek $scope.ipv4sToDelete.push($scope.interface.ipv4.values[index]); 58971ac1aaSbeccabroek } 59971ac1aaSbeccabroek $scope.interface.ipv4.values.splice(index, 1); 60971ac1aaSbeccabroek }; 61971ac1aaSbeccabroek 627ddc7274SGunnar Mills $scope.setNetworkSettings = function() { 63d01504cfSGunnar Mills // Hides the confirm network settings modal 64067a1cd1Sbeccabroek $scope.confirmSettings = false; 6584981f0aSGunnar Mills $scope.loading = true; 66dca79d73SGunnar Mills var promises = []; 67dca79d73SGunnar Mills 68659651e8SGunnar Mills // MAC Address are case-insensitive 69659651e8SGunnar Mills if ($scope.interface.MACAddress.toLowerCase() != 70659651e8SGunnar Mills dataService.mac_address.toLowerCase()) { 71dca79d73SGunnar Mills promises.push(setMACAddress()); 72659651e8SGunnar Mills } 73067a1cd1Sbeccabroek if ($scope.defaultGateway != dataService.defaultgateway) { 74dca79d73SGunnar Mills promises.push(setDefaultGateway()); 75659651e8SGunnar Mills } 76659651e8SGunnar Mills if ($scope.hostname != dataService.hostname) { 77309e06abSGunnar Mills promises.push(setHostname()); 78659651e8SGunnar Mills } 79067a1cd1Sbeccabroek if ($scope.interface.DHCPEnabled != $scope.oldInterface.DHCPEnabled) { 80cb2c3060SGunnar Mills promises.push(setDHCPEnabled()); 81cb2c3060SGunnar Mills } 82309e06abSGunnar Mills 8382658298SGunnar Mills // Remove any empty strings from the array. Important because we add an 8482658298SGunnar Mills // empty string to the end so the user can add a new DNS server, if the 8582658298SGunnar Mills // user doesn't fill out the field, we don't want to add. 8682658298SGunnar Mills $scope.interface.Nameservers = 8782658298SGunnar Mills $scope.interface.Nameservers.filter(Boolean); 880646782dSGunnar Mills // toString() is a cheap way to compare 2 string arrays 890646782dSGunnar Mills if ($scope.interface.Nameservers.toString() != 90067a1cd1Sbeccabroek $scope.oldInterface.Nameservers.toString()) { 910646782dSGunnar Mills promises.push(setNameservers()); 920646782dSGunnar Mills } 930646782dSGunnar Mills 94a45c3852SGunnar Mills // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways 95a45c3852SGunnar Mills if (!$scope.interface.DHCPEnabled) { 96971ac1aaSbeccabroek // Delete existing IPV4 addresses that were removed 97971ac1aaSbeccabroek promises.push(removeIPV4s()); 981a0e7d06Sbeccabroek // Update any changed IPV4 addresses and add new 99a45c3852SGunnar Mills for (var i in $scope.interface.ipv4.values) { 1006549114eSGunnar Mills if (!APIUtils.validIPV4IP( 1016549114eSGunnar Mills $scope.interface.ipv4.values[i].Address)) { 10227ce84d2Sbeccabroek toastService.error( 1039a3b5422Sbeccabroek $scope.interface.ipv4.values[i].Address + 1049a3b5422Sbeccabroek ' invalid IP parameter'); 1056549114eSGunnar Mills $scope.loading = false; 1066549114eSGunnar Mills return; 1076549114eSGunnar Mills } 108*de2da859SDerick Montague if ($scope.interface.ipv4.values[i].Gateway && 109*de2da859SDerick Montague !APIUtils.validIPV4IP( 1106549114eSGunnar Mills $scope.interface.ipv4.values[i].Gateway)) { 11127ce84d2Sbeccabroek toastService.error( 1129a3b5422Sbeccabroek $scope.interface.ipv4.values[i].Address + 1139a3b5422Sbeccabroek ' 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) { 11927ce84d2Sbeccabroek toastService.error( 1209a3b5422Sbeccabroek $scope.interface.ipv4.values[i].Address + 1219a3b5422Sbeccabroek ' invalid Prefix Length parameter'); 1226549114eSGunnar Mills $scope.loading = false; 1236549114eSGunnar Mills return; 1246549114eSGunnar Mills } 125067a1cd1Sbeccabroek if ($scope.interface.ipv4.values[i].updateAddress || 126067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateGateway || 127067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updatePrefix) { 1281a0e7d06Sbeccabroek // If IPV4 has an id it means it already exists in the back end, 1291a0e7d06Sbeccabroek // and in order to update it is required to remove previous IPV4 1301a0e7d06Sbeccabroek // address and add new one. See openbmc/openbmc/issues/2163. 1311a0e7d06Sbeccabroek // TODO: update to use PUT once issue 2163 is resolved. 1321a0e7d06Sbeccabroek if ($scope.interface.ipv4.values[i].id) { 1331a0e7d06Sbeccabroek promises.push(updateIPV4(i)); 1341a0e7d06Sbeccabroek } else { 1351a0e7d06Sbeccabroek promises.push(addIPV4(i)); 1361a0e7d06Sbeccabroek } 137a45c3852SGunnar Mills } 138a45c3852SGunnar Mills } 139a45c3852SGunnar Mills } 140a45c3852SGunnar Mills 1410af165b9SGunnar Mills if (promises.length) { 1429a3b5422Sbeccabroek $q.all(promises).then( 1439a3b5422Sbeccabroek function(response) { 1449a3b5422Sbeccabroek // Since an IPV4 interface (e.g. IP address, gateway, or 1459a3b5422Sbeccabroek // netmask) edit is a delete then an add and the GUI can't 1469a3b5422Sbeccabroek // calculate the interface id (e.g. 5c083707) beforehand and it 1479a3b5422Sbeccabroek // is not returned by the REST call, openbmc#3227, reload the 1489a3b5422Sbeccabroek // page after an edit, which makes a 2nd REST call. Do this for 1499a3b5422Sbeccabroek // all network changes due to the possibility of a set network 1509a3b5422Sbeccabroek // failing even though it returned success, openbmc#1641, and to 1519a3b5422Sbeccabroek // update dataService and oldInterface to know which data has 1529a3b5422Sbeccabroek // changed if the user continues to edit network settings. 1530af165b9SGunnar Mills // TODO: The reload is not ideal. Revisit this. 1540af165b9SGunnar Mills $timeout(function() { 155a3f75320SGunnar Mills loadNetworkInfo(); 1569a3b5422Sbeccabroek $scope.loading = false; 15727ce84d2Sbeccabroek toastService.success('Network settings saved'); 1580af165b9SGunnar Mills }, 4000); 1599a3b5422Sbeccabroek }, 1609a3b5422Sbeccabroek function(error) { 1619a3b5422Sbeccabroek $scope.loading = false; 16227ce84d2Sbeccabroek toastService.error('Network settings could not be saved'); 1639a3b5422Sbeccabroek }) 1640af165b9SGunnar Mills } else { 1650af165b9SGunnar Mills $scope.loading = false; 1660af165b9SGunnar Mills } 167dca79d73SGunnar Mills }; 168dca79d73SGunnar Mills 169dca79d73SGunnar Mills function setMACAddress() { 170dca79d73SGunnar Mills return APIUtils 1717ddc7274SGunnar Mills .setMACAddress( 1727ddc7274SGunnar Mills $scope.selectedInterface, $scope.interface.MACAddress) 1737ddc7274SGunnar Mills .then( 174dca79d73SGunnar Mills function(data) {}, 1757ddc7274SGunnar Mills function(error) { 176dca79d73SGunnar Mills console.log(JSON.stringify(error)); 1779a3b5422Sbeccabroek return $q.reject(); 1787ddc7274SGunnar Mills }); 179dca79d73SGunnar Mills } 180dca79d73SGunnar Mills 181dca79d73SGunnar Mills function setDefaultGateway() { 182067a1cd1Sbeccabroek return APIUtils.setDefaultGateway($scope.defaultGateway) 183dca79d73SGunnar Mills .then( 184dca79d73SGunnar Mills function(data) {}, 185dca79d73SGunnar Mills function(error) { 186dca79d73SGunnar Mills console.log(JSON.stringify(error)); 1879a3b5422Sbeccabroek return $q.reject(); 188dca79d73SGunnar Mills }); 189dca79d73SGunnar Mills } 190309e06abSGunnar Mills 191309e06abSGunnar Mills function setHostname() { 192309e06abSGunnar Mills return APIUtils.setHostname($scope.hostname) 193309e06abSGunnar Mills .then( 194309e06abSGunnar Mills function(data) {}, 195309e06abSGunnar Mills function(error) { 196309e06abSGunnar Mills console.log(JSON.stringify(error)); 1979a3b5422Sbeccabroek return $q.reject(); 198309e06abSGunnar Mills }); 199309e06abSGunnar Mills } 200309e06abSGunnar Mills 201cb2c3060SGunnar Mills function setDHCPEnabled() { 202cb2c3060SGunnar Mills return APIUtils 203cb2c3060SGunnar Mills .setDHCPEnabled( 204cb2c3060SGunnar Mills $scope.selectedInterface, $scope.interface.DHCPEnabled) 205cb2c3060SGunnar Mills .then( 206cb2c3060SGunnar Mills function(data) {}, 207cb2c3060SGunnar Mills function(error) { 208cb2c3060SGunnar Mills console.log(JSON.stringify(error)); 2099a3b5422Sbeccabroek return $q.reject(); 210cb2c3060SGunnar Mills }); 211cb2c3060SGunnar Mills } 212cb2c3060SGunnar Mills 2130646782dSGunnar Mills function setNameservers() { 2140646782dSGunnar Mills return APIUtils 2150646782dSGunnar Mills .setNameservers( 2160646782dSGunnar Mills $scope.selectedInterface, $scope.interface.Nameservers) 2170646782dSGunnar Mills .then( 2180646782dSGunnar Mills function(data) {}, 2190646782dSGunnar Mills function(error) { 2200646782dSGunnar Mills console.log(JSON.stringify(error)); 2219a3b5422Sbeccabroek return $q.reject(); 2220646782dSGunnar Mills }); 2230646782dSGunnar Mills } 2240646782dSGunnar Mills 225971ac1aaSbeccabroek function removeIPV4s() { 226067a1cd1Sbeccabroek return $scope.ipv4sToDelete.map(function(ipv4) { 227971ac1aaSbeccabroek return APIUtils.deleteIPV4($scope.selectedInterface, ipv4.id) 228971ac1aaSbeccabroek .then( 229971ac1aaSbeccabroek function(data) {}, 230971ac1aaSbeccabroek function(error) { 231971ac1aaSbeccabroek console.log(JSON.stringify(error)); 2329a3b5422Sbeccabroek return $q.reject(); 233971ac1aaSbeccabroek }) 234971ac1aaSbeccabroek }); 235971ac1aaSbeccabroek } 236971ac1aaSbeccabroek 2371a0e7d06Sbeccabroek function addIPV4(index) { 2381a0e7d06Sbeccabroek return APIUtils 2391a0e7d06Sbeccabroek .addIPV4( 2401a0e7d06Sbeccabroek $scope.selectedInterface, 2411a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Address, 2421a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].PrefixLength, 2431a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Gateway) 2441a0e7d06Sbeccabroek .then( 2451a0e7d06Sbeccabroek function(data) {}, 2461a0e7d06Sbeccabroek function(error) { 2471a0e7d06Sbeccabroek console.log(JSON.stringify(error)); 2489a3b5422Sbeccabroek return $q.reject(); 2491a0e7d06Sbeccabroek }) 2501a0e7d06Sbeccabroek } 2511a0e7d06Sbeccabroek 2521a0e7d06Sbeccabroek function updateIPV4(index) { 253a45c3852SGunnar Mills // The correct way to edit an IPV4 interface is to remove it and then 254a45c3852SGunnar Mills // add a new one 255a45c3852SGunnar Mills return APIUtils 256a45c3852SGunnar Mills .deleteIPV4( 2571a0e7d06Sbeccabroek $scope.selectedInterface, 2581a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].id) 259a45c3852SGunnar Mills .then( 260a45c3852SGunnar Mills function(data) { 261a45c3852SGunnar Mills return APIUtils 262a45c3852SGunnar Mills .addIPV4( 263a45c3852SGunnar Mills $scope.selectedInterface, 264a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address, 265a45c3852SGunnar Mills $scope.interface.ipv4.values[index].PrefixLength, 266a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Gateway) 267a45c3852SGunnar Mills .then( 268a45c3852SGunnar Mills function(data) {}, 269a45c3852SGunnar Mills function(error) { 270a45c3852SGunnar Mills console.log(JSON.stringify(error)); 2719a3b5422Sbeccabroek return $q.reject(); 272a45c3852SGunnar Mills }); 273a45c3852SGunnar Mills }, 274a45c3852SGunnar Mills function(error) { 275a45c3852SGunnar Mills console.log(JSON.stringify(error)); 2769a3b5422Sbeccabroek return $q.reject(); 277a45c3852SGunnar Mills }); 278a45c3852SGunnar Mills } 279a45c3852SGunnar Mills 2809a0094dcSGunnar Mills $scope.refresh = function() { 281a3f75320SGunnar Mills loadNetworkInfo(); 2829a0094dcSGunnar Mills }; 283a3f75320SGunnar Mills 284a3f75320SGunnar Mills function loadNetworkInfo() { 2852a489554SIftekharul Islam APIUtils.getNetworkInfo().then(function(data) { 286659651e8SGunnar Mills dataService.setNetworkInfo(data); 2872a489554SIftekharul Islam $scope.network = data.formatted_data; 2882a489554SIftekharul Islam $scope.hostname = data.hostname; 289067a1cd1Sbeccabroek $scope.defaultGateway = data.defaultgateway; 2902a489554SIftekharul Islam if ($scope.network.interface_ids.length) { 291ffdef96dSRebecca Shaw // Use the first network interface if the user hasn't chosen one 292a3f75320SGunnar Mills if (!$scope.selectedInterface || 293a3f75320SGunnar Mills !$scope.network.interfaces[$scope.selectedInterface]) { 2942a489554SIftekharul Islam $scope.selectedInterface = $scope.network.interface_ids[0]; 295a3f75320SGunnar Mills } 296d27bb135SAndrew Geissler $scope.interface = 297d27bb135SAndrew Geissler $scope.network.interfaces[$scope.selectedInterface]; 298a45c3852SGunnar Mills // Copy the interface so we know later if changes were made to the 299a45c3852SGunnar Mills // page 300067a1cd1Sbeccabroek $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface)); 3012a489554SIftekharul Islam } 3021a0e7d06Sbeccabroek // Add id values and update flags to corresponding IPV4 objects 303971ac1aaSbeccabroek for (var i = 0; i < $scope.interface.ipv4.values.length; i++) { 304971ac1aaSbeccabroek $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i]; 305067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateAddress = false; 306067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateGateway = false; 307067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updatePrefix = false; 308971ac1aaSbeccabroek } 3092a489554SIftekharul Islam }); 310cd789508SIftekharul Islam } 311a3f75320SGunnar Mills } 312ba5e3f34SAndrew Geissler ]); 313cd789508SIftekharul Islam})(angular); 314