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', 14*9a3b5422Sbeccabroek 'ngToast', 15*9a3b5422Sbeccabroek function( 16*9a3b5422Sbeccabroek $scope, $window, APIUtils, dataService, $timeout, $route, $q, ngToast) { 17cd789508SIftekharul Islam $scope.dataService = dataService; 182a489554SIftekharul Islam $scope.network = {}; 19067a1cd1Sbeccabroek $scope.oldInterface = {}; 202a489554SIftekharul Islam $scope.interface = {}; 212a489554SIftekharul Islam $scope.networkDevice = false; 22ba5e3f34SAndrew Geissler $scope.hostname = ''; 23067a1cd1Sbeccabroek $scope.defaultGateway = ''; 247ddc7274SGunnar Mills $scope.selectedInterface = ''; 25067a1cd1Sbeccabroek $scope.confirmSettings = false; 2684981f0aSGunnar Mills $scope.loading = false; 27067a1cd1Sbeccabroek $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 34067a1cd1Sbeccabroek $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) { 56067a1cd1Sbeccabroek $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 63067a1cd1Sbeccabroek $scope.confirmSettings = false; 6484981f0aSGunnar Mills $scope.loading = true; 65dca79d73SGunnar Mills var promises = []; 66dca79d73SGunnar Mills 67659651e8SGunnar Mills // MAC Address are case-insensitive 68659651e8SGunnar Mills if ($scope.interface.MACAddress.toLowerCase() != 69659651e8SGunnar Mills dataService.mac_address.toLowerCase()) { 70dca79d73SGunnar Mills promises.push(setMACAddress()); 71659651e8SGunnar Mills } 72067a1cd1Sbeccabroek if ($scope.defaultGateway != dataService.defaultgateway) { 73dca79d73SGunnar Mills promises.push(setDefaultGateway()); 74659651e8SGunnar Mills } 75659651e8SGunnar Mills if ($scope.hostname != dataService.hostname) { 76309e06abSGunnar Mills promises.push(setHostname()); 77659651e8SGunnar Mills } 78067a1cd1Sbeccabroek if ($scope.interface.DHCPEnabled != $scope.oldInterface.DHCPEnabled) { 79cb2c3060SGunnar Mills promises.push(setDHCPEnabled()); 80cb2c3060SGunnar Mills } 81309e06abSGunnar Mills 8282658298SGunnar Mills // Remove any empty strings from the array. Important because we add an 8382658298SGunnar Mills // empty string to the end so the user can add a new DNS server, if the 8482658298SGunnar Mills // user doesn't fill out the field, we don't want to add. 8582658298SGunnar Mills $scope.interface.Nameservers = 8682658298SGunnar Mills $scope.interface.Nameservers.filter(Boolean); 870646782dSGunnar Mills // toString() is a cheap way to compare 2 string arrays 880646782dSGunnar Mills if ($scope.interface.Nameservers.toString() != 89067a1cd1Sbeccabroek $scope.oldInterface.Nameservers.toString()) { 900646782dSGunnar Mills promises.push(setNameservers()); 910646782dSGunnar Mills } 920646782dSGunnar Mills 93a45c3852SGunnar Mills // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways 94a45c3852SGunnar Mills if (!$scope.interface.DHCPEnabled) { 95971ac1aaSbeccabroek // Delete existing IPV4 addresses that were removed 96971ac1aaSbeccabroek promises.push(removeIPV4s()); 971a0e7d06Sbeccabroek // Update any changed IPV4 addresses and add new 98a45c3852SGunnar Mills for (var i in $scope.interface.ipv4.values) { 996549114eSGunnar Mills if (!APIUtils.validIPV4IP( 1006549114eSGunnar Mills $scope.interface.ipv4.values[i].Address)) { 101*9a3b5422Sbeccabroek ngToast.danger( 102*9a3b5422Sbeccabroek $scope.interface.ipv4.values[i].Address + 103*9a3b5422Sbeccabroek ' invalid IP parameter'); 1046549114eSGunnar Mills $scope.loading = false; 1056549114eSGunnar Mills return; 1066549114eSGunnar Mills } 1076549114eSGunnar Mills if (!APIUtils.validIPV4IP( 1086549114eSGunnar Mills $scope.interface.ipv4.values[i].Gateway)) { 109*9a3b5422Sbeccabroek ngToast.danger( 110*9a3b5422Sbeccabroek $scope.interface.ipv4.values[i].Address + 111*9a3b5422Sbeccabroek ' 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*9a3b5422Sbeccabroek ngToast.danger( 118*9a3b5422Sbeccabroek $scope.interface.ipv4.values[i].Address + 119*9a3b5422Sbeccabroek ' invalid Prefix Length parameter'); 1206549114eSGunnar Mills $scope.loading = false; 1216549114eSGunnar Mills return; 1226549114eSGunnar Mills } 123067a1cd1Sbeccabroek if ($scope.interface.ipv4.values[i].updateAddress || 124067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateGateway || 125067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updatePrefix) { 1261a0e7d06Sbeccabroek // If IPV4 has an id it means it already exists in the back end, 1271a0e7d06Sbeccabroek // and in order to update it is required to remove previous IPV4 1281a0e7d06Sbeccabroek // address and add new one. See openbmc/openbmc/issues/2163. 1291a0e7d06Sbeccabroek // TODO: update to use PUT once issue 2163 is resolved. 1301a0e7d06Sbeccabroek if ($scope.interface.ipv4.values[i].id) { 1311a0e7d06Sbeccabroek promises.push(updateIPV4(i)); 1321a0e7d06Sbeccabroek } else { 1331a0e7d06Sbeccabroek promises.push(addIPV4(i)); 1341a0e7d06Sbeccabroek } 135a45c3852SGunnar Mills } 136a45c3852SGunnar Mills } 137a45c3852SGunnar Mills } 138a45c3852SGunnar Mills 1390af165b9SGunnar Mills if (promises.length) { 140*9a3b5422Sbeccabroek $q.all(promises).then( 141*9a3b5422Sbeccabroek function(response) { 142*9a3b5422Sbeccabroek // Since an IPV4 interface (e.g. IP address, gateway, or 143*9a3b5422Sbeccabroek // netmask) edit is a delete then an add and the GUI can't 144*9a3b5422Sbeccabroek // calculate the interface id (e.g. 5c083707) beforehand and it 145*9a3b5422Sbeccabroek // is not returned by the REST call, openbmc#3227, reload the 146*9a3b5422Sbeccabroek // page after an edit, which makes a 2nd REST call. Do this for 147*9a3b5422Sbeccabroek // all network changes due to the possibility of a set network 148*9a3b5422Sbeccabroek // failing even though it returned success, openbmc#1641, and to 149*9a3b5422Sbeccabroek // update dataService and oldInterface to know which data has 150*9a3b5422Sbeccabroek // changed if the user continues to edit network settings. 1510af165b9SGunnar Mills // TODO: The reload is not ideal. Revisit this. 1520af165b9SGunnar Mills $timeout(function() { 153a3f75320SGunnar Mills loadNetworkInfo(); 154*9a3b5422Sbeccabroek $scope.loading = false; 155*9a3b5422Sbeccabroek ngToast.success('Network settings saved'); 1560af165b9SGunnar Mills }, 4000); 157*9a3b5422Sbeccabroek }, 158*9a3b5422Sbeccabroek function(error) { 159*9a3b5422Sbeccabroek $scope.loading = false; 160*9a3b5422Sbeccabroek ngToast.danger('Network settings could not be saved'); 161*9a3b5422Sbeccabroek }) 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)); 175*9a3b5422Sbeccabroek return $q.reject(); 1767ddc7274SGunnar Mills }); 177dca79d73SGunnar Mills } 178dca79d73SGunnar Mills 179dca79d73SGunnar Mills function setDefaultGateway() { 180067a1cd1Sbeccabroek return APIUtils.setDefaultGateway($scope.defaultGateway) 181dca79d73SGunnar Mills .then( 182dca79d73SGunnar Mills function(data) {}, 183dca79d73SGunnar Mills function(error) { 184dca79d73SGunnar Mills console.log(JSON.stringify(error)); 185*9a3b5422Sbeccabroek return $q.reject(); 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)); 195*9a3b5422Sbeccabroek return $q.reject(); 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)); 207*9a3b5422Sbeccabroek return $q.reject(); 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)); 224*9a3b5422Sbeccabroek return $q.reject(); 2250646782dSGunnar Mills }); 2260646782dSGunnar Mills } 2270646782dSGunnar Mills 228971ac1aaSbeccabroek function removeIPV4s() { 229067a1cd1Sbeccabroek return $scope.ipv4sToDelete.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)); 235*9a3b5422Sbeccabroek return $q.reject(); 236971ac1aaSbeccabroek }) 237971ac1aaSbeccabroek }); 238971ac1aaSbeccabroek } 239971ac1aaSbeccabroek 2401a0e7d06Sbeccabroek function addIPV4(index) { 2411a0e7d06Sbeccabroek return APIUtils 2421a0e7d06Sbeccabroek .addIPV4( 2431a0e7d06Sbeccabroek $scope.selectedInterface, 2441a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Address, 2451a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].PrefixLength, 2461a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].Gateway) 2471a0e7d06Sbeccabroek .then( 2481a0e7d06Sbeccabroek function(data) {}, 2491a0e7d06Sbeccabroek function(error) { 2501a0e7d06Sbeccabroek console.log(JSON.stringify(error)); 251*9a3b5422Sbeccabroek return $q.reject(); 2521a0e7d06Sbeccabroek }) 2531a0e7d06Sbeccabroek } 2541a0e7d06Sbeccabroek 2551a0e7d06Sbeccabroek function updateIPV4(index) { 256a45c3852SGunnar Mills // The correct way to edit an IPV4 interface is to remove it and then 257a45c3852SGunnar Mills // add a new one 258a45c3852SGunnar Mills return APIUtils 259a45c3852SGunnar Mills .deleteIPV4( 2601a0e7d06Sbeccabroek $scope.selectedInterface, 2611a0e7d06Sbeccabroek $scope.interface.ipv4.values[index].id) 262a45c3852SGunnar Mills .then( 263a45c3852SGunnar Mills function(data) { 264a45c3852SGunnar Mills return APIUtils 265a45c3852SGunnar Mills .addIPV4( 266a45c3852SGunnar Mills $scope.selectedInterface, 267a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Address, 268a45c3852SGunnar Mills $scope.interface.ipv4.values[index].PrefixLength, 269a45c3852SGunnar Mills $scope.interface.ipv4.values[index].Gateway) 270a45c3852SGunnar Mills .then( 271a45c3852SGunnar Mills function(data) {}, 272a45c3852SGunnar Mills function(error) { 273a45c3852SGunnar Mills console.log(JSON.stringify(error)); 274*9a3b5422Sbeccabroek return $q.reject(); 275a45c3852SGunnar Mills }); 276a45c3852SGunnar Mills }, 277a45c3852SGunnar Mills function(error) { 278a45c3852SGunnar Mills console.log(JSON.stringify(error)); 279*9a3b5422Sbeccabroek return $q.reject(); 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; 292067a1cd1Sbeccabroek $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 303067a1cd1Sbeccabroek $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]; 308067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateAddress = false; 309067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updateGateway = false; 310067a1cd1Sbeccabroek $scope.interface.ipv4.values[i].updatePrefix = false; 311971ac1aaSbeccabroek } 3122a489554SIftekharul Islam }); 313cd789508SIftekharul Islam } 314a3f75320SGunnar Mills } 315ba5e3f34SAndrew Geissler ]); 316cd789508SIftekharul Islam})(angular); 317