blob: a9546d4e557a7fc08edebcb5e31dd0319e73f785 [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',
14 function($scope, $window, APIUtils, dataService, $timeout, $route, $q) {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070015 $scope.dataService = dataService;
16 $scope.network = {};
Gunnar Millsa45c3852018-05-30 16:18:45 -050017 $scope.old_interface = {};
Andrew Geisslerd27bb132018-05-24 11:07:27 -070018 $scope.interface = {};
19 $scope.networkDevice = false;
20 $scope.hostname = '';
Gunnar Millse9f5fe72018-05-04 13:43:10 -050021 $scope.defaultgateway = '';
Gunnar Mills7ddc7272018-04-12 16:12:03 -050022 $scope.set_network_error = '';
23 $scope.set_network_success = false;
24 $scope.selectedInterface = '';
Gunnar Millsd01504c2018-05-03 13:01:51 -050025 $scope.confirm_settings = false;
Gunnar Mills84981f02018-05-31 15:19:01 -050026 $scope.loading = false;
beccabroek971ac1a2018-09-24 13:14:05 -050027 $scope.IPV4s_to_delete = [];
Iftekharul Islam2a489552017-11-02 13:23:08 -050028
Gunnar Millsa3f75322018-07-10 17:06:02 -050029 loadNetworkInfo();
30
Andrew Geisslerd27bb132018-05-24 11:07:27 -070031 $scope.selectInterface = function(interfaceId) {
32 $scope.interface = $scope.network.interfaces[interfaceId];
Gunnar Millsa45c3852018-05-30 16:18:45 -050033 // Copy the interface so we know later if changes were made to the page
34 $scope.old_interface = JSON.parse(JSON.stringify($scope.interface));
Andrew Geisslerd27bb132018-05-24 11:07:27 -070035 $scope.selectedInterface = interfaceId;
36 $scope.networkDevice = false;
37 };
Gunnar Millsbc3ab722018-07-10 15:11:01 -050038
39 $scope.addDNSField = function() {
40 $scope.interface.Nameservers.push('');
41 };
42
beccabroekcff61502018-09-13 14:39:23 -050043 $scope.removeDNSField = function(index) {
44 $scope.interface.Nameservers.splice(index, 1);
45 };
46
beccabroek971ac1a2018-09-24 13:14:05 -050047 $scope.removeIpv4Address = function(index) {
48 // Check if the IPV4 being removed has an id. This indicates that it is
49 // an existing address and needs to be removed in the back end.
50 if ($scope.interface.ipv4.values[index].id) {
51 $scope.IPV4s_to_delete.push($scope.interface.ipv4.values[index]);
52 }
53 $scope.interface.ipv4.values.splice(index, 1);
54 };
55
Gunnar Mills7ddc7272018-04-12 16:12:03 -050056 $scope.setNetworkSettings = function() {
Gunnar Millsd01504c2018-05-03 13:01:51 -050057 // Hides the confirm network settings modal
58 $scope.confirm_settings = false;
Gunnar Mills7ddc7272018-04-12 16:12:03 -050059 $scope.set_network_error = '';
60 $scope.set_network_success = false;
Gunnar Mills84981f02018-05-31 15:19:01 -050061 $scope.loading = true;
Gunnar Millsdca79d72018-05-30 13:07:01 -050062 var promises = [];
63
Gunnar Mills659651e2018-05-30 15:21:07 -050064 // MAC Address are case-insensitive
65 if ($scope.interface.MACAddress.toLowerCase() !=
66 dataService.mac_address.toLowerCase()) {
67 promises.push(setMACAddress());
68 }
69 if ($scope.defaultgateway != dataService.defaultgateway) {
70 promises.push(setDefaultGateway());
71 }
72 if ($scope.hostname != dataService.hostname) {
73 promises.push(setHostname());
74 }
Gunnar Millscb2c3062018-05-31 13:13:30 -050075 if ($scope.interface.DHCPEnabled != $scope.old_interface.DHCPEnabled) {
76 promises.push(setDHCPEnabled());
77 }
Gunnar Mills309e06a2018-05-30 13:18:10 -050078
Gunnar Mills82658292018-06-06 16:51:32 -050079 // Remove any empty strings from the array. Important because we add an
80 // empty string to the end so the user can add a new DNS server, if the
81 // user doesn't fill out the field, we don't want to add.
82 $scope.interface.Nameservers =
83 $scope.interface.Nameservers.filter(Boolean);
Gunnar Mills06467822018-06-06 15:43:18 -050084 // toString() is a cheap way to compare 2 string arrays
85 if ($scope.interface.Nameservers.toString() !=
86 $scope.old_interface.Nameservers.toString()) {
87 promises.push(setNameservers());
88 }
89
Gunnar Millsa45c3852018-05-30 16:18:45 -050090 // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways
91 if (!$scope.interface.DHCPEnabled) {
beccabroek971ac1a2018-09-24 13:14:05 -050092 // Delete existing IPV4 addresses that were removed
93 promises.push(removeIPV4s());
94 // Update any changed IPV4 addresses
Gunnar Millsa45c3852018-05-30 16:18:45 -050095 for (var i in $scope.interface.ipv4.values) {
Gunnar Mills65491142018-06-04 14:23:33 -050096 if (!APIUtils.validIPV4IP(
97 $scope.interface.ipv4.values[i].Address)) {
98 $scope.set_network_error =
99 $scope.interface.ipv4.values[i].Address +
100 ' invalid IP parameter';
101 $scope.loading = false;
102 return;
103 }
104 if (!APIUtils.validIPV4IP(
105 $scope.interface.ipv4.values[i].Gateway)) {
106 $scope.set_network_error =
107 $scope.interface.ipv4.values[i].Address +
108 ' invalid gateway parameter';
109 $scope.loading = false;
110 return;
111 }
112 // The netmask prefix length will be undefined if outside range
113 if (!$scope.interface.ipv4.values[i].PrefixLength) {
114 $scope.set_network_error =
115 $scope.interface.ipv4.values[i].Address +
116 ' invalid Prefix Length parameter';
117 $scope.loading = false;
118 return;
119 }
Gunnar Millsa45c3852018-05-30 16:18:45 -0500120 if ($scope.interface.ipv4.values[i].Address !=
121 $scope.old_interface.ipv4.values[i].Address ||
122 $scope.interface.ipv4.values[i].PrefixLength !=
123 $scope.old_interface.ipv4.values[i].PrefixLength ||
124 $scope.interface.ipv4.values[i].Gateway !=
125 $scope.old_interface.ipv4.values[i].Gateway) {
126 promises.push(setIPV4(i));
127 }
128 }
129 }
130
Gunnar Mills0af165b2018-06-01 16:24:56 -0500131 if (promises.length) {
132 $q.all(promises).finally(function() {
133 $scope.loading = false;
134 if (!$scope.set_network_error) {
135 $scope.set_network_success = true;
136 // Since an IPV4 interface (e.g. IP address, gateway, or netmask)
137 // edit is a delete then an add and the GUI can't calculate the
138 // interface id (e.g. 5c083707) beforehand and it is not returned
139 // by the REST call, openbmc#3227, reload the page after an edit,
140 // which makes a 2nd REST call.
141 // Do this for all network changes due to the possibility of a set
142 // network failing even though it returned success, openbmc#1641,
143 // and to update dataService and old_interface to know which
144 // data has changed if the user continues to edit network
145 // settings.
146 // TODO: The reload is not ideal. Revisit this.
147 $timeout(function() {
Gunnar Millsa3f75322018-07-10 17:06:02 -0500148 loadNetworkInfo();
Gunnar Mills0af165b2018-06-01 16:24:56 -0500149 }, 4000);
150 }
151 });
152 } else {
Gunnar Mills84981f02018-05-31 15:19:01 -0500153 $scope.loading = false;
Gunnar Mills0af165b2018-06-01 16:24:56 -0500154 }
Gunnar Millsdca79d72018-05-30 13:07:01 -0500155 };
156
157 function setMACAddress() {
158 return APIUtils
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500159 .setMACAddress(
160 $scope.selectedInterface, $scope.interface.MACAddress)
161 .then(
Gunnar Millsdca79d72018-05-30 13:07:01 -0500162 function(data) {},
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500163 function(error) {
Gunnar Millsdca79d72018-05-30 13:07:01 -0500164 console.log(JSON.stringify(error));
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500165 $scope.set_network_error = 'MAC Address';
166 });
Gunnar Millsdca79d72018-05-30 13:07:01 -0500167 }
168
169 function setDefaultGateway() {
170 return APIUtils.setDefaultGateway($scope.defaultgateway)
171 .then(
172 function(data) {},
173 function(error) {
174 console.log(JSON.stringify(error));
175 $scope.set_network_error = 'Default Gateway';
176 });
177 }
Gunnar Mills309e06a2018-05-30 13:18:10 -0500178
179 function setHostname() {
180 return APIUtils.setHostname($scope.hostname)
181 .then(
182 function(data) {},
183 function(error) {
184 console.log(JSON.stringify(error));
185 $scope.set_network_error = 'Hostname';
186 });
187 }
188
Gunnar Millscb2c3062018-05-31 13:13:30 -0500189 function setDHCPEnabled() {
190 return APIUtils
191 .setDHCPEnabled(
192 $scope.selectedInterface, $scope.interface.DHCPEnabled)
193 .then(
194 function(data) {},
195 function(error) {
196 console.log(JSON.stringify(error));
197 $scope.set_network_error = 'DHCP';
198 });
199 }
200
Gunnar Mills06467822018-06-06 15:43:18 -0500201 function setNameservers() {
Gunnar Mills82658292018-06-06 16:51:32 -0500202 // Nameservers does not allow an empty array, since we remove all empty
Gunnar Mills9863d122018-07-11 13:36:43 -0500203 // strings above, could have an empty array. TODO: openbmc/openbmc#3240
Gunnar Mills82658292018-06-06 16:51:32 -0500204 if ($scope.interface.Nameservers.length == 0) {
205 $scope.interface.Nameservers.push('');
206 }
Gunnar Mills06467822018-06-06 15:43:18 -0500207 return APIUtils
208 .setNameservers(
209 $scope.selectedInterface, $scope.interface.Nameservers)
210 .then(
211 function(data) {},
212 function(error) {
213 console.log(JSON.stringify(error));
214 $scope.set_network_error = 'DNS Servers';
215 });
216 }
217
beccabroek971ac1a2018-09-24 13:14:05 -0500218 function removeIPV4s() {
219 return $scope.IPV4s_to_delete.map(function(ipv4) {
220 return APIUtils.deleteIPV4($scope.selectedInterface, ipv4.id)
221 .then(
222 function(data) {},
223 function(error) {
224 console.log(JSON.stringify(error));
225 $scope.set_network_error = ipv4.Address;
226 })
227 });
228 }
229
Gunnar Millsa45c3852018-05-30 16:18:45 -0500230 function setIPV4(index) {
231 // The correct way to edit an IPV4 interface is to remove it and then
232 // add a new one
233 return APIUtils
234 .deleteIPV4(
235 $scope.selectedInterface, $scope.interface.ipv4.ids[index])
236 .then(
237 function(data) {
238 return APIUtils
239 .addIPV4(
240 $scope.selectedInterface,
241 $scope.interface.ipv4.values[index].Address,
242 $scope.interface.ipv4.values[index].PrefixLength,
243 $scope.interface.ipv4.values[index].Gateway)
244 .then(
245 function(data) {},
246 function(error) {
247 console.log(JSON.stringify(error));
248 $scope.set_network_error =
249 $scope.interface.ipv4.values[index].Address;
250 });
251 },
252 function(error) {
253 console.log(JSON.stringify(error));
254 $scope.set_network_error =
255 $scope.interface.ipv4.values[index].Address;
256 });
257 }
258
Gunnar Mills9a0094d2018-05-02 21:50:56 -0500259 $scope.refresh = function() {
Gunnar Millsa3f75322018-07-10 17:06:02 -0500260 loadNetworkInfo();
Gunnar Mills9a0094d2018-05-02 21:50:56 -0500261 };
Gunnar Millsa3f75322018-07-10 17:06:02 -0500262
263 function loadNetworkInfo() {
264 APIUtils.getNetworkInfo().then(function(data) {
265 dataService.setNetworkInfo(data);
266 $scope.network = data.formatted_data;
267 $scope.hostname = data.hostname;
268 $scope.defaultgateway = data.defaultgateway;
269 if ($scope.network.interface_ids.length) {
Rebecca Shawffdef962018-07-19 13:37:37 -0500270 // Use the first network interface if the user hasn't chosen one
Gunnar Millsa3f75322018-07-10 17:06:02 -0500271 if (!$scope.selectedInterface ||
272 !$scope.network.interfaces[$scope.selectedInterface]) {
273 $scope.selectedInterface = $scope.network.interface_ids[0];
274 }
275 $scope.interface =
276 $scope.network.interfaces[$scope.selectedInterface];
277 // Copy the interface so we know later if changes were made to the
278 // page
279 $scope.old_interface = JSON.parse(JSON.stringify($scope.interface));
280 }
beccabroek971ac1a2018-09-24 13:14:05 -0500281 // Add id values to corresponding IPV4 objects
282 for (var i = 0; i < $scope.interface.ipv4.values.length; i++) {
283 $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i];
284 }
Gunnar Millsa3f75322018-07-10 17:06:02 -0500285 });
286 }
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700287 }
288 ]);
Iftekharul Islamcd789502017-04-19 14:37:55 -0500289})(angular);