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 = {}; 17*067a1cd1Sbeccabroek $scope.oldInterface = {}; 182a489554SIftekharul Islam $scope.interface = {}; 192a489554SIftekharul Islam $scope.networkDevice = false; 20ba5e3f34SAndrew Geissler $scope.hostname = ''; 21*067a1cd1Sbeccabroek $scope.defaultGateway = ''; 22*067a1cd1Sbeccabroek $scope.setNetworkError = ''; 23*067a1cd1Sbeccabroek $scope.setNetworkSuccess = false; 247ddc7274SGunnar Mills $scope.selectedInterface = ''; 25*067a1cd1Sbeccabroek $scope.confirmSettings = false; 2684981f0aSGunnar Mills $scope.loading = false; 27*067a1cd1Sbeccabroek $scope.ipv4sToDelete = []; 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 34*067a1cd1Sbeccabroek $scope.oldInterface = 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 471a0e7d06Sbeccabroek $scope.addIpv4Field = function() { 481a0e7d06Sbeccabroek $scope.interface.ipv4.values.push( 491a0e7d06Sbeccabroek {Address: '', PrefixLength: '', Gateway: ''}); 501a0e7d06Sbeccabroek }; 511a0e7d06Sbeccabroek 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) { 56*067a1cd1Sbeccabroek $scope.ipv4sToDelete.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 63*067a1cd1Sbeccabroek $scope.confirmSettings = false; 64*067a1cd1Sbeccabroek $scope.setNetworkError = ''; 65*067a1cd1Sbeccabroek $scope.setNetworkSuccess = 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 } 74*067a1cd1Sbeccabroek 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 } 80*067a1cd1Sbeccabroek if ($scope.interface.DHCPEnabled != $scope.oldInterface.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() != 91*067a1cd1Sbeccabroek $scope.oldInterface.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()); 991a0e7d06Sbeccabroek // 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)) { 103*067a1cd1Sbeccabroek $scope.setNetworkError = $scope.interface.ipv4.values[i].Address + 1046549114eSGunnar Mills ' invalid IP parameter'; 1056549114eSGunnar Mills $scope.loading = false; 1066549114eSGunnar Mills return; 1076549114eSGunnar Mills } 1086549114eSGunnar Mills if (!APIUtils.validIPV4IP( 1096549114eSGunnar Mills $scope.interface.ipv4.values[i].Gateway)) { 110*067a1cd1Sbeccabroek $scope.setNetworkError = $scope.interface.ipv4.values[i].Address + 1116549114eSGunnar Mills ' invalid gateway parameter'; 1126549114eSGunnar Mills $scope.loading = false; 1136549114eSGunnar Mills return; 1146549114eSGunnar Mills } 1156549114eSGunnar Mills // The netmask prefix length will be undefined if outside range 1166549114eSGunnar Mills if (!$scope.interface.ipv4.values[i].PrefixLength) { 117*067a1cd1Sbeccabroek $scope.setNetworkError = $scope.interface.ipv4.values[i].Address + 1186549114eSGunnar Mills ' invalid Prefix Length parameter'; 1196549114eSGunnar Mills $scope.loading = false; 1206549114eSGunnar Mills return; 1216549114eSGunnar Mills } 122*067a1cd1Sbeccabroek if ($scope.interface.ipv4.values[i].updateAddress || 123*067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateGateway || 124*067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updatePrefix) { 1251a0e7d06Sbeccabroek // If IPV4 has an id it means it already exists in the back end, 1261a0e7d06Sbeccabroek // and in order to update it is required to remove previous IPV4 1271a0e7d06Sbeccabroek // address and add new one. See openbmc/openbmc/issues/2163. 1281a0e7d06Sbeccabroek // TODO: update to use PUT once issue 2163 is resolved. 1291a0e7d06Sbeccabroek if ($scope.interface.ipv4.values[i].id) { 1301a0e7d06Sbeccabroek promises.push(updateIPV4(i)); 1311a0e7d06Sbeccabroek } else { 1321a0e7d06Sbeccabroek promises.push(addIPV4(i)); 1331a0e7d06Sbeccabroek } 134a45c3852SGunnar Mills } 135a45c3852SGunnar Mills } 136a45c3852SGunnar Mills } 137a45c3852SGunnar Mills 1380af165b9SGunnar Mills if (promises.length) { 139dca79d73SGunnar Mills $q.all(promises).finally(function() { 14084981f0aSGunnar Mills $scope.loading = false; 141*067a1cd1Sbeccabroek if (!$scope.setNetworkError) { 142*067a1cd1Sbeccabroek $scope.setNetworkSuccess = true; 1430af165b9SGunnar Mills // Since an IPV4 interface (e.g. IP address, gateway, or netmask) 1440af165b9SGunnar Mills // edit is a delete then an add and the GUI can't calculate the 1450af165b9SGunnar Mills // interface id (e.g. 5c083707) beforehand and it is not returned 1460af165b9SGunnar Mills // by the REST call, openbmc#3227, reload the page after an edit, 1470af165b9SGunnar Mills // which makes a 2nd REST call. 1480af165b9SGunnar Mills // Do this for all network changes due to the possibility of a set 1490af165b9SGunnar Mills // network failing even though it returned success, openbmc#1641, 150*067a1cd1Sbeccabroek // and to update dataService and oldInterface to know which 1510af165b9SGunnar Mills // data has changed if the user continues to edit network 1520af165b9SGunnar Mills // settings. 1530af165b9SGunnar Mills // TODO: The reload is not ideal. Revisit this. 1540af165b9SGunnar Mills $timeout(function() { 155a3f75320SGunnar Mills loadNetworkInfo(); 1560af165b9SGunnar Mills }, 4000); 157dca79d73SGunnar Mills } 158dca79d73SGunnar Mills }); 1590af165b9SGunnar Mills } else { 1600af165b9SGunnar Mills $scope.loading = false; 1610af165b9SGunnar Mills } 162dca79d73SGunnar Mills }; 163dca79d73SGunnar Mills 164dca79d73SGunnar Mills function setMACAddress() { 165dca79d73SGunnar Mills return APIUtils 1667ddc7274SGunnar Mills .setMACAddress( 1677ddc7274SGunnar Mills $scope.selectedInterface, $scope.interface.MACAddress) 1687ddc7274SGunnar Mills .then( 169dca79d73SGunnar Mills function(data) {}, 1707ddc7274SGunnar Mills function(error) { 171dca79d73SGunnar Mills console.log(JSON.stringify(error)); 172*067a1cd1Sbeccabroek $scope.setNetworkError = 'MAC Address'; 1737ddc7274SGunnar Mills }); 174dca79d73SGunnar Mills } 175dca79d73SGunnar Mills 176dca79d73SGunnar Mills function setDefaultGateway() { 177*067a1cd1Sbeccabroek return APIUtils.setDefaultGateway($scope.defaultGateway) 178dca79d73SGunnar Mills .then( 179dca79d73SGunnar Mills function(data) {}, 180dca79d73SGunnar Mills function(error) { 181dca79d73SGunnar Mills console.log(JSON.stringify(error)); 182*067a1cd1Sbeccabroek $scope.setNetworkError = 'Default Gateway'; 183dca79d73SGunnar Mills }); 184dca79d73SGunnar Mills } 185309e06abSGunnar Mills 186309e06abSGunnar Mills function setHostname() { 187309e06abSGunnar Mills return APIUtils.setHostname($scope.hostname) 188309e06abSGunnar Mills .then( 189309e06abSGunnar Mills function(data) {}, 190309e06abSGunnar Mills function(error) { 191309e06abSGunnar Mills console.log(JSON.stringify(error)); 192*067a1cd1Sbeccabroek $scope.setNetworkError = 'Hostname'; 193309e06abSGunnar Mills }); 194309e06abSGunnar Mills } 195309e06abSGunnar Mills 196cb2c3060SGunnar Mills function setDHCPEnabled() { 197cb2c3060SGunnar Mills return APIUtils 198cb2c3060SGunnar Mills .setDHCPEnabled( 199cb2c3060SGunnar Mills $scope.selectedInterface, $scope.interface.DHCPEnabled) 200cb2c3060SGunnar Mills .then( 201cb2c3060SGunnar Mills function(data) {}, 202cb2c3060SGunnar Mills function(error) { 203cb2c3060SGunnar Mills console.log(JSON.stringify(error)); 204*067a1cd1Sbeccabroek $scope.setNetworkError = 'DHCP'; 205cb2c3060SGunnar Mills }); 206cb2c3060SGunnar Mills } 207cb2c3060SGunnar Mills 2080646782dSGunnar Mills function setNameservers() { 20982658298SGunnar Mills // Nameservers does not allow an empty array, since we remove all empty 2109863d121SGunnar Mills // strings above, could have an empty array. TODO: openbmc/openbmc#3240 21182658298SGunnar Mills if ($scope.interface.Nameservers.length == 0) { 21282658298SGunnar Mills $scope.interface.Nameservers.push(''); 21382658298SGunnar Mills } 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)); 221*067a1cd1Sbeccabroek $scope.setNetworkError = 'DNS Servers'; 2220646782dSGunnar Mills }); 2230646782dSGunnar Mills } 2240646782dSGunnar Mills 225971ac1aaSbeccabroek function removeIPV4s() { 226*067a1cd1Sbeccabroek 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)); 232*067a1cd1Sbeccabroek $scope.setNetworkError = ipv4.Address; 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)); 248*067a1cd1Sbeccabroek $scope.setNetworkError = 2491a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Address; 2501a0e7d06Sbeccabroek }) 2511a0e7d06Sbeccabroek } 2521a0e7d06Sbeccabroek 2531a0e7d06Sbeccabroek function updateIPV4(index) { 254a45c3852SGunnar Mills // The correct way to edit an IPV4 interface is to remove it and then 255a45c3852SGunnar Mills // add a new one 256a45c3852SGunnar Mills return APIUtils 257a45c3852SGunnar Mills .deleteIPV4( 2581a0e7d06Sbeccabroek $scope.selectedInterface, 2591a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].id) 260a45c3852SGunnar Mills .then( 261a45c3852SGunnar Mills function(data) { 262a45c3852SGunnar Mills return APIUtils 263a45c3852SGunnar Mills .addIPV4( 264a45c3852SGunnar Mills $scope.selectedInterface, 265a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address, 266a45c3852SGunnar Mills $scope.interface.ipv4.values[index].PrefixLength, 267a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Gateway) 268a45c3852SGunnar Mills .then( 269a45c3852SGunnar Mills function(data) {}, 270a45c3852SGunnar Mills function(error) { 271a45c3852SGunnar Mills console.log(JSON.stringify(error)); 272*067a1cd1Sbeccabroek $scope.setNetworkError = 273a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address; 274a45c3852SGunnar Mills }); 275a45c3852SGunnar Mills }, 276a45c3852SGunnar Mills function(error) { 277a45c3852SGunnar Mills console.log(JSON.stringify(error)); 278*067a1cd1Sbeccabroek $scope.setNetworkError = 279a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address; 280a45c3852SGunnar Mills }); 281a45c3852SGunnar Mills } 282a45c3852SGunnar Mills 2839a0094dcSGunnar Mills $scope.refresh = function() { 284a3f75320SGunnar Mills loadNetworkInfo(); 2859a0094dcSGunnar Mills }; 286a3f75320SGunnar Mills 287a3f75320SGunnar Mills function loadNetworkInfo() { 2882a489554SIftekharul Islam APIUtils.getNetworkInfo().then(function(data) { 289659651e8SGunnar Mills dataService.setNetworkInfo(data); 2902a489554SIftekharul Islam $scope.network = data.formatted_data; 2912a489554SIftekharul Islam $scope.hostname = data.hostname; 292*067a1cd1Sbeccabroek $scope.defaultGateway = data.defaultgateway; 2932a489554SIftekharul Islam if ($scope.network.interface_ids.length) { 294ffdef96dSRebecca Shaw // Use the first network interface if the user hasn't chosen one 295a3f75320SGunnar Mills if (!$scope.selectedInterface || 296a3f75320SGunnar Mills !$scope.network.interfaces[$scope.selectedInterface]) { 2972a489554SIftekharul Islam $scope.selectedInterface = $scope.network.interface_ids[0]; 298a3f75320SGunnar Mills } 299d27bb135SAndrew Geissler $scope.interface = 300d27bb135SAndrew Geissler $scope.network.interfaces[$scope.selectedInterface]; 301a45c3852SGunnar Mills // Copy the interface so we know later if changes were made to the 302a45c3852SGunnar Mills // page 303*067a1cd1Sbeccabroek $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface)); 3042a489554SIftekharul Islam } 3051a0e7d06Sbeccabroek // Add id values and update flags to corresponding IPV4 objects 306971ac1aaSbeccabroek for (var i = 0; i < $scope.interface.ipv4.values.length; i++) { 307971ac1aaSbeccabroek $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i]; 308*067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateAddress = false; 309*067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateGateway = false; 310*067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updatePrefix = false; 311971ac1aaSbeccabroek } 3122a489554SIftekharul Islam }); 313cd789508SIftekharul Islam } 314a3f75320SGunnar Mills } 315ba5e3f34SAndrew Geissler ]); 316cd789508SIftekharul Islam})(angular); 317