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