blob: d2d99ba984bd9970edb924cc1177681835cf476e [file] [log] [blame]
Iftekharul Islamcd789502017-04-19 14:37:55 -05001/**
2 * Controller for network
3 *
4 * @module app/configuration
5 * @exports networkController
6 * @name networkController
Iftekharul Islamcd789502017-04-19 14:37:55 -05007 */
8
Andrew Geisslerba5e3f32018-05-24 10:58:00 -07009window.angular && (function(angular) {
10 'use strict';
Iftekharul Islamcd789502017-04-19 14:37:55 -050011
Andrew Geisslerd27bb132018-05-24 11:07:27 -070012 angular.module('app.configuration').controller('networkController', [
Gunnar Mills0af165b2018-06-01 16:24:56 -050013 '$scope', '$window', 'APIUtils', 'dataService', '$timeout', '$route', '$q',
beccabroek27ce84d2019-02-05 15:43:17 -060014 'toastService',
beccabroek9a3b5422019-01-15 14:45:12 -060015 function(
beccabroek27ce84d2019-02-05 15:43:17 -060016 $scope, $window, APIUtils, dataService, $timeout, $route, $q,
17 toastService) {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070018 $scope.dataService = dataService;
19 $scope.network = {};
beccabroek067a1cd2018-10-05 10:25:21 -050020 $scope.oldInterface = {};
Andrew Geisslerd27bb132018-05-24 11:07:27 -070021 $scope.interface = {};
22 $scope.networkDevice = false;
23 $scope.hostname = '';
beccabroek067a1cd2018-10-05 10:25:21 -050024 $scope.defaultGateway = '';
Gunnar Mills7ddc7272018-04-12 16:12:03 -050025 $scope.selectedInterface = '';
beccabroek067a1cd2018-10-05 10:25:21 -050026 $scope.confirmSettings = false;
Gunnar Mills84981f02018-05-31 15:19:01 -050027 $scope.loading = false;
beccabroek067a1cd2018-10-05 10:25:21 -050028 $scope.ipv4sToDelete = [];
Iftekharul Islam2a489552017-11-02 13:23:08 -050029
Gunnar Millsa3f75322018-07-10 17:06:02 -050030 loadNetworkInfo();
31
Andrew Geisslerd27bb132018-05-24 11:07:27 -070032 $scope.selectInterface = function(interfaceId) {
33 $scope.interface = $scope.network.interfaces[interfaceId];
Gunnar Millsa45c3852018-05-30 16:18:45 -050034 // Copy the interface so we know later if changes were made to the page
beccabroek067a1cd2018-10-05 10:25:21 -050035 $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface));
Andrew Geisslerd27bb132018-05-24 11:07:27 -070036 $scope.selectedInterface = interfaceId;
37 $scope.networkDevice = false;
38 };
Gunnar Millsbc3ab722018-07-10 15:11:01 -050039
40 $scope.addDNSField = function() {
41 $scope.interface.Nameservers.push('');
42 };
43
beccabroekcff61502018-09-13 14:39:23 -050044 $scope.removeDNSField = function(index) {
45 $scope.interface.Nameservers.splice(index, 1);
46 };
47
beccabroek1a0e7d02018-09-24 15:03:40 -050048 $scope.addIpv4Field = function() {
49 $scope.interface.ipv4.values.push(
50 {Address: '', PrefixLength: '', Gateway: ''});
51 };
52
beccabroek971ac1a2018-09-24 13:14:05 -050053 $scope.removeIpv4Address = function(index) {
54 // Check if the IPV4 being removed has an id. This indicates that it is
55 // an existing address and needs to be removed in the back end.
56 if ($scope.interface.ipv4.values[index].id) {
beccabroek067a1cd2018-10-05 10:25:21 -050057 $scope.ipv4sToDelete.push($scope.interface.ipv4.values[index]);
beccabroek971ac1a2018-09-24 13:14:05 -050058 }
59 $scope.interface.ipv4.values.splice(index, 1);
60 };
61
Gunnar Mills7ddc7272018-04-12 16:12:03 -050062 $scope.setNetworkSettings = function() {
Gunnar Millsd01504c2018-05-03 13:01:51 -050063 // Hides the confirm network settings modal
beccabroek067a1cd2018-10-05 10:25:21 -050064 $scope.confirmSettings = false;
Gunnar Mills84981f02018-05-31 15:19:01 -050065 $scope.loading = true;
Gunnar Millsdca79d72018-05-30 13:07:01 -050066 var promises = [];
67
Gunnar Mills659651e2018-05-30 15:21:07 -050068 // MAC Address are case-insensitive
69 if ($scope.interface.MACAddress.toLowerCase() !=
70 dataService.mac_address.toLowerCase()) {
71 promises.push(setMACAddress());
72 }
beccabroek067a1cd2018-10-05 10:25:21 -050073 if ($scope.defaultGateway != dataService.defaultgateway) {
Gunnar Mills659651e2018-05-30 15:21:07 -050074 promises.push(setDefaultGateway());
75 }
76 if ($scope.hostname != dataService.hostname) {
77 promises.push(setHostname());
78 }
beccabroek067a1cd2018-10-05 10:25:21 -050079 if ($scope.interface.DHCPEnabled != $scope.oldInterface.DHCPEnabled) {
Gunnar Millscb2c3062018-05-31 13:13:30 -050080 promises.push(setDHCPEnabled());
81 }
Gunnar Mills309e06a2018-05-30 13:18:10 -050082
Gunnar Mills82658292018-06-06 16:51:32 -050083 // Remove any empty strings from the array. Important because we add an
84 // empty string to the end so the user can add a new DNS server, if the
85 // user doesn't fill out the field, we don't want to add.
86 $scope.interface.Nameservers =
87 $scope.interface.Nameservers.filter(Boolean);
Gunnar Mills06467822018-06-06 15:43:18 -050088 // toString() is a cheap way to compare 2 string arrays
89 if ($scope.interface.Nameservers.toString() !=
beccabroek067a1cd2018-10-05 10:25:21 -050090 $scope.oldInterface.Nameservers.toString()) {
Gunnar Mills06467822018-06-06 15:43:18 -050091 promises.push(setNameservers());
92 }
93
Gunnar Millsa45c3852018-05-30 16:18:45 -050094 // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways
95 if (!$scope.interface.DHCPEnabled) {
beccabroek971ac1a2018-09-24 13:14:05 -050096 // Delete existing IPV4 addresses that were removed
97 promises.push(removeIPV4s());
beccabroek1a0e7d02018-09-24 15:03:40 -050098 // Update any changed IPV4 addresses and add new
Gunnar Millsa45c3852018-05-30 16:18:45 -050099 for (var i in $scope.interface.ipv4.values) {
Gunnar Mills65491142018-06-04 14:23:33 -0500100 if (!APIUtils.validIPV4IP(
101 $scope.interface.ipv4.values[i].Address)) {
beccabroek27ce84d2019-02-05 15:43:17 -0600102 toastService.error(
beccabroek9a3b5422019-01-15 14:45:12 -0600103 $scope.interface.ipv4.values[i].Address +
104 ' invalid IP parameter');
Gunnar Mills65491142018-06-04 14:23:33 -0500105 $scope.loading = false;
106 return;
107 }
108 if (!APIUtils.validIPV4IP(
109 $scope.interface.ipv4.values[i].Gateway)) {
beccabroek27ce84d2019-02-05 15:43:17 -0600110 toastService.error(
beccabroek9a3b5422019-01-15 14:45:12 -0600111 $scope.interface.ipv4.values[i].Address +
112 ' invalid gateway parameter');
Gunnar Mills65491142018-06-04 14:23:33 -0500113 $scope.loading = false;
114 return;
115 }
116 // The netmask prefix length will be undefined if outside range
117 if (!$scope.interface.ipv4.values[i].PrefixLength) {
beccabroek27ce84d2019-02-05 15:43:17 -0600118 toastService.error(
beccabroek9a3b5422019-01-15 14:45:12 -0600119 $scope.interface.ipv4.values[i].Address +
120 ' invalid Prefix Length parameter');
Gunnar Mills65491142018-06-04 14:23:33 -0500121 $scope.loading = false;
122 return;
123 }
beccabroek067a1cd2018-10-05 10:25:21 -0500124 if ($scope.interface.ipv4.values[i].updateAddress ||
125 $scope.interface.ipv4.values[i].updateGateway ||
126 $scope.interface.ipv4.values[i].updatePrefix) {
beccabroek1a0e7d02018-09-24 15:03:40 -0500127 // If IPV4 has an id it means it already exists in the back end,
128 // and in order to update it is required to remove previous IPV4
129 // address and add new one. See openbmc/openbmc/issues/2163.
130 // TODO: update to use PUT once issue 2163 is resolved.
131 if ($scope.interface.ipv4.values[i].id) {
132 promises.push(updateIPV4(i));
133 } else {
134 promises.push(addIPV4(i));
135 }
Gunnar Millsa45c3852018-05-30 16:18:45 -0500136 }
137 }
138 }
139
Gunnar Mills0af165b2018-06-01 16:24:56 -0500140 if (promises.length) {
beccabroek9a3b5422019-01-15 14:45:12 -0600141 $q.all(promises).then(
142 function(response) {
143 // Since an IPV4 interface (e.g. IP address, gateway, or
144 // netmask) edit is a delete then an add and the GUI can't
145 // calculate the interface id (e.g. 5c083707) beforehand and it
146 // is not returned by the REST call, openbmc#3227, reload the
147 // page after an edit, which makes a 2nd REST call. Do this for
148 // all network changes due to the possibility of a set network
149 // failing even though it returned success, openbmc#1641, and to
150 // update dataService and oldInterface to know which data has
151 // changed if the user continues to edit network settings.
152 // TODO: The reload is not ideal. Revisit this.
153 $timeout(function() {
154 loadNetworkInfo();
155 $scope.loading = false;
beccabroek27ce84d2019-02-05 15:43:17 -0600156 toastService.success('Network settings saved');
beccabroek9a3b5422019-01-15 14:45:12 -0600157 }, 4000);
158 },
159 function(error) {
160 $scope.loading = false;
beccabroek27ce84d2019-02-05 15:43:17 -0600161 toastService.error('Network settings could not be saved');
beccabroek9a3b5422019-01-15 14:45:12 -0600162 })
Gunnar Mills0af165b2018-06-01 16:24:56 -0500163 } else {
Gunnar Mills84981f02018-05-31 15:19:01 -0500164 $scope.loading = false;
Gunnar Mills0af165b2018-06-01 16:24:56 -0500165 }
Gunnar Millsdca79d72018-05-30 13:07:01 -0500166 };
167
168 function setMACAddress() {
169 return APIUtils
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500170 .setMACAddress(
171 $scope.selectedInterface, $scope.interface.MACAddress)
172 .then(
Gunnar Millsdca79d72018-05-30 13:07:01 -0500173 function(data) {},
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500174 function(error) {
Gunnar Millsdca79d72018-05-30 13:07:01 -0500175 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600176 return $q.reject();
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500177 });
Gunnar Millsdca79d72018-05-30 13:07:01 -0500178 }
179
180 function setDefaultGateway() {
beccabroek067a1cd2018-10-05 10:25:21 -0500181 return APIUtils.setDefaultGateway($scope.defaultGateway)
Gunnar Millsdca79d72018-05-30 13:07:01 -0500182 .then(
183 function(data) {},
184 function(error) {
185 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600186 return $q.reject();
Gunnar Millsdca79d72018-05-30 13:07:01 -0500187 });
188 }
Gunnar Mills309e06a2018-05-30 13:18:10 -0500189
190 function setHostname() {
191 return APIUtils.setHostname($scope.hostname)
192 .then(
193 function(data) {},
194 function(error) {
195 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600196 return $q.reject();
Gunnar Mills309e06a2018-05-30 13:18:10 -0500197 });
198 }
199
Gunnar Millscb2c3062018-05-31 13:13:30 -0500200 function setDHCPEnabled() {
201 return APIUtils
202 .setDHCPEnabled(
203 $scope.selectedInterface, $scope.interface.DHCPEnabled)
204 .then(
205 function(data) {},
206 function(error) {
207 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600208 return $q.reject();
Gunnar Millscb2c3062018-05-31 13:13:30 -0500209 });
210 }
211
Gunnar Mills06467822018-06-06 15:43:18 -0500212 function setNameservers() {
Gunnar Mills82658292018-06-06 16:51:32 -0500213 // Nameservers does not allow an empty array, since we remove all empty
Gunnar Mills9863d122018-07-11 13:36:43 -0500214 // strings above, could have an empty array. TODO: openbmc/openbmc#3240
Gunnar Mills82658292018-06-06 16:51:32 -0500215 if ($scope.interface.Nameservers.length == 0) {
216 $scope.interface.Nameservers.push('');
217 }
Gunnar Mills06467822018-06-06 15:43:18 -0500218 return APIUtils
219 .setNameservers(
220 $scope.selectedInterface, $scope.interface.Nameservers)
221 .then(
222 function(data) {},
223 function(error) {
224 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600225 return $q.reject();
Gunnar Mills06467822018-06-06 15:43:18 -0500226 });
227 }
228
beccabroek971ac1a2018-09-24 13:14:05 -0500229 function removeIPV4s() {
beccabroek067a1cd2018-10-05 10:25:21 -0500230 return $scope.ipv4sToDelete.map(function(ipv4) {
beccabroek971ac1a2018-09-24 13:14:05 -0500231 return APIUtils.deleteIPV4($scope.selectedInterface, ipv4.id)
232 .then(
233 function(data) {},
234 function(error) {
235 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600236 return $q.reject();
beccabroek971ac1a2018-09-24 13:14:05 -0500237 })
238 });
239 }
240
beccabroek1a0e7d02018-09-24 15:03:40 -0500241 function addIPV4(index) {
242 return APIUtils
243 .addIPV4(
244 $scope.selectedInterface,
245 $scope.interface.ipv4.values[index].Address,
246 $scope.interface.ipv4.values[index].PrefixLength,
247 $scope.interface.ipv4.values[index].Gateway)
248 .then(
249 function(data) {},
250 function(error) {
251 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600252 return $q.reject();
beccabroek1a0e7d02018-09-24 15:03:40 -0500253 })
254 }
255
256 function updateIPV4(index) {
Gunnar Millsa45c3852018-05-30 16:18:45 -0500257 // The correct way to edit an IPV4 interface is to remove it and then
258 // add a new one
259 return APIUtils
260 .deleteIPV4(
beccabroek1a0e7d02018-09-24 15:03:40 -0500261 $scope.selectedInterface,
262 $scope.interface.ipv4.values[index].id)
Gunnar Millsa45c3852018-05-30 16:18:45 -0500263 .then(
264 function(data) {
265 return APIUtils
266 .addIPV4(
267 $scope.selectedInterface,
268 $scope.interface.ipv4.values[index].Address,
269 $scope.interface.ipv4.values[index].PrefixLength,
270 $scope.interface.ipv4.values[index].Gateway)
271 .then(
272 function(data) {},
273 function(error) {
274 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600275 return $q.reject();
Gunnar Millsa45c3852018-05-30 16:18:45 -0500276 });
277 },
278 function(error) {
279 console.log(JSON.stringify(error));
beccabroek9a3b5422019-01-15 14:45:12 -0600280 return $q.reject();
Gunnar Millsa45c3852018-05-30 16:18:45 -0500281 });
282 }
283
Gunnar Mills9a0094d2018-05-02 21:50:56 -0500284 $scope.refresh = function() {
Gunnar Millsa3f75322018-07-10 17:06:02 -0500285 loadNetworkInfo();
Gunnar Mills9a0094d2018-05-02 21:50:56 -0500286 };
Gunnar Millsa3f75322018-07-10 17:06:02 -0500287
288 function loadNetworkInfo() {
289 APIUtils.getNetworkInfo().then(function(data) {
290 dataService.setNetworkInfo(data);
291 $scope.network = data.formatted_data;
292 $scope.hostname = data.hostname;
beccabroek067a1cd2018-10-05 10:25:21 -0500293 $scope.defaultGateway = data.defaultgateway;
Gunnar Millsa3f75322018-07-10 17:06:02 -0500294 if ($scope.network.interface_ids.length) {
Rebecca Shawffdef962018-07-19 13:37:37 -0500295 // Use the first network interface if the user hasn't chosen one
Gunnar Millsa3f75322018-07-10 17:06:02 -0500296 if (!$scope.selectedInterface ||
297 !$scope.network.interfaces[$scope.selectedInterface]) {
298 $scope.selectedInterface = $scope.network.interface_ids[0];
299 }
300 $scope.interface =
301 $scope.network.interfaces[$scope.selectedInterface];
302 // Copy the interface so we know later if changes were made to the
303 // page
beccabroek067a1cd2018-10-05 10:25:21 -0500304 $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface));
Gunnar Millsa3f75322018-07-10 17:06:02 -0500305 }
beccabroek1a0e7d02018-09-24 15:03:40 -0500306 // Add id values and update flags to corresponding IPV4 objects
beccabroek971ac1a2018-09-24 13:14:05 -0500307 for (var i = 0; i < $scope.interface.ipv4.values.length; i++) {
308 $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i];
beccabroek067a1cd2018-10-05 10:25:21 -0500309 $scope.interface.ipv4.values[i].updateAddress = false;
310 $scope.interface.ipv4.values[i].updateGateway = false;
311 $scope.interface.ipv4.values[i].updatePrefix = false;
beccabroek971ac1a2018-09-24 13:14:05 -0500312 }
Gunnar Millsa3f75322018-07-10 17:06:02 -0500313 });
314 }
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700315 }
316 ]);
Iftekharul Islamcd789502017-04-19 14:37:55 -0500317})(angular);