1/** 2 * Controller for network 3 * 4 * @module app/configuration 5 * @exports networkController 6 * @name networkController 7 */ 8 9window.angular && (function(angular) { 10 'use strict'; 11 12 angular.module('app.configuration').controller('networkController', [ 13 '$scope', '$window', 'APIUtils', 'dataService', '$timeout', '$route', '$q', 14 function($scope, $window, APIUtils, dataService, $timeout, $route, $q) { 15 $scope.dataService = dataService; 16 $scope.network = {}; 17 $scope.old_interface = {}; 18 $scope.interface = {}; 19 $scope.networkDevice = false; 20 $scope.hostname = ''; 21 $scope.defaultgateway = ''; 22 $scope.set_network_error = ''; 23 $scope.set_network_success = false; 24 $scope.selectedInterface = ''; 25 $scope.confirm_settings = false; 26 $scope.loading = false; 27 28 loadNetworkInfo(); 29 30 $scope.selectInterface = function(interfaceId) { 31 $scope.interface = $scope.network.interfaces[interfaceId]; 32 // Copy the interface so we know later if changes were made to the page 33 $scope.old_interface = JSON.parse(JSON.stringify($scope.interface)); 34 $scope.selectedInterface = interfaceId; 35 $scope.networkDevice = false; 36 }; 37 $scope.setNetworkSettings = function() { 38 // Hides the confirm network settings modal 39 $scope.confirm_settings = false; 40 $scope.set_network_error = ''; 41 $scope.set_network_success = false; 42 $scope.loading = true; 43 var promises = []; 44 45 // MAC Address are case-insensitive 46 if ($scope.interface.MACAddress.toLowerCase() != 47 dataService.mac_address.toLowerCase()) { 48 promises.push(setMACAddress()); 49 } 50 if ($scope.defaultgateway != dataService.defaultgateway) { 51 promises.push(setDefaultGateway()); 52 } 53 if ($scope.hostname != dataService.hostname) { 54 promises.push(setHostname()); 55 } 56 if ($scope.interface.DHCPEnabled != $scope.old_interface.DHCPEnabled) { 57 promises.push(setDHCPEnabled()); 58 } 59 60 // Remove any empty strings from the array. Important because we add an 61 // empty string to the end so the user can add a new DNS server, if the 62 // user doesn't fill out the field, we don't want to add. 63 $scope.interface.Nameservers = 64 $scope.interface.Nameservers.filter(Boolean); 65 // toString() is a cheap way to compare 2 string arrays 66 if ($scope.interface.Nameservers.toString() != 67 $scope.old_interface.Nameservers.toString()) { 68 promises.push(setNameservers()); 69 } 70 71 // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways 72 if (!$scope.interface.DHCPEnabled) { 73 for (var i in $scope.interface.ipv4.values) { 74 if (!APIUtils.validIPV4IP( 75 $scope.interface.ipv4.values[i].Address)) { 76 $scope.set_network_error = 77 $scope.interface.ipv4.values[i].Address + 78 ' invalid IP parameter'; 79 $scope.loading = false; 80 return; 81 } 82 if (!APIUtils.validIPV4IP( 83 $scope.interface.ipv4.values[i].Gateway)) { 84 $scope.set_network_error = 85 $scope.interface.ipv4.values[i].Address + 86 ' invalid gateway parameter'; 87 $scope.loading = false; 88 return; 89 } 90 // The netmask prefix length will be undefined if outside range 91 if (!$scope.interface.ipv4.values[i].PrefixLength) { 92 $scope.set_network_error = 93 $scope.interface.ipv4.values[i].Address + 94 ' invalid Prefix Length parameter'; 95 $scope.loading = false; 96 return; 97 } 98 if ($scope.interface.ipv4.values[i].Address != 99 $scope.old_interface.ipv4.values[i].Address || 100 $scope.interface.ipv4.values[i].PrefixLength != 101 $scope.old_interface.ipv4.values[i].PrefixLength || 102 $scope.interface.ipv4.values[i].Gateway != 103 $scope.old_interface.ipv4.values[i].Gateway) { 104 promises.push(setIPV4(i)); 105 } 106 } 107 } 108 109 if (promises.length) { 110 $q.all(promises).finally(function() { 111 $scope.loading = false; 112 if (!$scope.set_network_error) { 113 $scope.set_network_success = true; 114 // Since an IPV4 interface (e.g. IP address, gateway, or netmask) 115 // edit is a delete then an add and the GUI can't calculate the 116 // interface id (e.g. 5c083707) beforehand and it is not returned 117 // by the REST call, openbmc#3227, reload the page after an edit, 118 // which makes a 2nd REST call. 119 // Do this for all network changes due to the possibility of a set 120 // network failing even though it returned success, openbmc#1641, 121 // and to update dataService and old_interface to know which 122 // data has changed if the user continues to edit network 123 // settings. 124 // TODO: The reload is not ideal. Revisit this. 125 $timeout(function() { 126 loadNetworkInfo(); 127 }, 4000); 128 } 129 }); 130 } else { 131 $scope.loading = false; 132 } 133 134 }; 135 136 function setMACAddress() { 137 return APIUtils 138 .setMACAddress( 139 $scope.selectedInterface, $scope.interface.MACAddress) 140 .then( 141 function(data) {}, 142 function(error) { 143 console.log(JSON.stringify(error)); 144 $scope.set_network_error = 'MAC Address'; 145 }); 146 } 147 148 function setDefaultGateway() { 149 return APIUtils.setDefaultGateway($scope.defaultgateway) 150 .then( 151 function(data) {}, 152 function(error) { 153 console.log(JSON.stringify(error)); 154 $scope.set_network_error = 'Default Gateway'; 155 }); 156 } 157 158 function setHostname() { 159 return APIUtils.setHostname($scope.hostname) 160 .then( 161 function(data) {}, 162 function(error) { 163 console.log(JSON.stringify(error)); 164 $scope.set_network_error = 'Hostname'; 165 }); 166 } 167 168 function setDHCPEnabled() { 169 return APIUtils 170 .setDHCPEnabled( 171 $scope.selectedInterface, $scope.interface.DHCPEnabled) 172 .then( 173 function(data) {}, 174 function(error) { 175 console.log(JSON.stringify(error)); 176 $scope.set_network_error = 'DHCP'; 177 }); 178 } 179 180 function setNameservers() { 181 // Nameservers does not allow an empty array, since we remove all empty 182 // strings above, could have an empty array. TODO: openbmc/openbmc#3240 183 if ($scope.interface.Nameservers.length == 0) { 184 $scope.interface.Nameservers.push(''); 185 } 186 return APIUtils 187 .setNameservers( 188 $scope.selectedInterface, $scope.interface.Nameservers) 189 .then( 190 function(data) {}, 191 function(error) { 192 console.log(JSON.stringify(error)); 193 $scope.set_network_error = 'DNS Servers'; 194 }); 195 } 196 197 function setIPV4(index) { 198 // The correct way to edit an IPV4 interface is to remove it and then 199 // add a new one 200 return APIUtils 201 .deleteIPV4( 202 $scope.selectedInterface, $scope.interface.ipv4.ids[index]) 203 .then( 204 function(data) { 205 return APIUtils 206 .addIPV4( 207 $scope.selectedInterface, 208 $scope.interface.ipv4.values[index].Address, 209 $scope.interface.ipv4.values[index].PrefixLength, 210 $scope.interface.ipv4.values[index].Gateway) 211 .then( 212 function(data) {}, 213 function(error) { 214 console.log(JSON.stringify(error)); 215 $scope.set_network_error = 216 $scope.interface.ipv4.values[index].Address; 217 }); 218 }, 219 function(error) { 220 console.log(JSON.stringify(error)); 221 $scope.set_network_error = 222 $scope.interface.ipv4.values[index].Address; 223 }); 224 } 225 226 $scope.refresh = function() { 227 loadNetworkInfo(); 228 }; 229 230 function loadNetworkInfo() { 231 APIUtils.getNetworkInfo().then(function(data) { 232 dataService.setNetworkInfo(data); 233 $scope.network = data.formatted_data; 234 $scope.hostname = data.hostname; 235 $scope.defaultgateway = data.defaultgateway; 236 if ($scope.network.interface_ids.length) { 237 // Use the first network interface if the user hasn't chosen one 238 if (!$scope.selectedInterface || 239 !$scope.network.interfaces[$scope.selectedInterface]) { 240 $scope.selectedInterface = $scope.network.interface_ids[0]; 241 } 242 $scope.interface = 243 $scope.network.interfaces[$scope.selectedInterface]; 244 // Copy the interface so we know later if changes were made to the 245 // page 246 $scope.old_interface = JSON.parse(JSON.stringify($scope.interface)); 247 } 248 }); 249 } 250 } 251 ]); 252 253})(angular); 254