blob: 9905157ab9af9490d26782203438df553b436430 [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
Gunnar Millsbc3ab722018-07-10 15:11:01 -050012 angular.module('app.configuration').directive('setFocusDnsField', function() {
13 return function(scope, element, attrs) {
14 var elem = window.document.getElementById(element[0].id);
15 // Focus on the newly created DNS server field
16 // Since this directive is also called when initializing DNS server fields
17 // on a page load, need to determine if the call is from a page load or
18 // from the user pressing the "Add new DNS server" button. The easiest way
19 // to do this is to check if the field is empty, if it is we know
20 // this is a new field since all empty fields are removed from the array.
21 if (!scope[attrs.ngModel] && elem) {
22 elem.focus();
23 }
24 };
25 });
26
Andrew Geisslerd27bb132018-05-24 11:07:27 -070027 angular.module('app.configuration').controller('networkController', [
Gunnar Mills0af165b2018-06-01 16:24:56 -050028 '$scope', '$window', 'APIUtils', 'dataService', '$timeout', '$route', '$q',
29 function($scope, $window, APIUtils, dataService, $timeout, $route, $q) {
Andrew Geisslerd27bb132018-05-24 11:07:27 -070030 $scope.dataService = dataService;
31 $scope.network = {};
Gunnar Millsa45c3852018-05-30 16:18:45 -050032 $scope.old_interface = {};
Andrew Geisslerd27bb132018-05-24 11:07:27 -070033 $scope.interface = {};
34 $scope.networkDevice = false;
35 $scope.hostname = '';
Gunnar Millse9f5fe72018-05-04 13:43:10 -050036 $scope.defaultgateway = '';
Gunnar Mills7ddc7272018-04-12 16:12:03 -050037 $scope.set_network_error = '';
38 $scope.set_network_success = false;
39 $scope.selectedInterface = '';
Gunnar Millsd01504c2018-05-03 13:01:51 -050040 $scope.confirm_settings = false;
Gunnar Mills84981f02018-05-31 15:19:01 -050041 $scope.loading = false;
Iftekharul Islam2a489552017-11-02 13:23:08 -050042
Gunnar Millsa3f75322018-07-10 17:06:02 -050043 loadNetworkInfo();
44
Andrew Geisslerd27bb132018-05-24 11:07:27 -070045 $scope.selectInterface = function(interfaceId) {
46 $scope.interface = $scope.network.interfaces[interfaceId];
Gunnar Millsa45c3852018-05-30 16:18:45 -050047 // Copy the interface so we know later if changes were made to the page
48 $scope.old_interface = JSON.parse(JSON.stringify($scope.interface));
Andrew Geisslerd27bb132018-05-24 11:07:27 -070049 $scope.selectedInterface = interfaceId;
50 $scope.networkDevice = false;
51 };
Gunnar Millsbc3ab722018-07-10 15:11:01 -050052
53 $scope.addDNSField = function() {
54 $scope.interface.Nameservers.push('');
55 };
56
Gunnar Mills7ddc7272018-04-12 16:12:03 -050057 $scope.setNetworkSettings = function() {
Gunnar Millsd01504c2018-05-03 13:01:51 -050058 // Hides the confirm network settings modal
59 $scope.confirm_settings = false;
Gunnar Mills7ddc7272018-04-12 16:12:03 -050060 $scope.set_network_error = '';
61 $scope.set_network_success = false;
Gunnar Mills84981f02018-05-31 15:19:01 -050062 $scope.loading = true;
Gunnar Millsdca79d72018-05-30 13:07:01 -050063 var promises = [];
64
Gunnar Mills659651e2018-05-30 15:21:07 -050065 // MAC Address are case-insensitive
66 if ($scope.interface.MACAddress.toLowerCase() !=
67 dataService.mac_address.toLowerCase()) {
68 promises.push(setMACAddress());
69 }
70 if ($scope.defaultgateway != dataService.defaultgateway) {
71 promises.push(setDefaultGateway());
72 }
73 if ($scope.hostname != dataService.hostname) {
74 promises.push(setHostname());
75 }
Gunnar Millscb2c3062018-05-31 13:13:30 -050076 if ($scope.interface.DHCPEnabled != $scope.old_interface.DHCPEnabled) {
77 promises.push(setDHCPEnabled());
78 }
Gunnar Mills309e06a2018-05-30 13:18:10 -050079
Gunnar Mills82658292018-06-06 16:51:32 -050080 // Remove any empty strings from the array. Important because we add an
81 // empty string to the end so the user can add a new DNS server, if the
82 // user doesn't fill out the field, we don't want to add.
83 $scope.interface.Nameservers =
84 $scope.interface.Nameservers.filter(Boolean);
Gunnar Mills06467822018-06-06 15:43:18 -050085 // toString() is a cheap way to compare 2 string arrays
86 if ($scope.interface.Nameservers.toString() !=
87 $scope.old_interface.Nameservers.toString()) {
88 promises.push(setNameservers());
89 }
90
Gunnar Millsa45c3852018-05-30 16:18:45 -050091 // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways
92 if (!$scope.interface.DHCPEnabled) {
93 for (var i in $scope.interface.ipv4.values) {
Gunnar Mills65491142018-06-04 14:23:33 -050094 if (!APIUtils.validIPV4IP(
95 $scope.interface.ipv4.values[i].Address)) {
96 $scope.set_network_error =
97 $scope.interface.ipv4.values[i].Address +
98 ' invalid IP parameter';
99 $scope.loading = false;
100 return;
101 }
102 if (!APIUtils.validIPV4IP(
103 $scope.interface.ipv4.values[i].Gateway)) {
104 $scope.set_network_error =
105 $scope.interface.ipv4.values[i].Address +
106 ' invalid gateway parameter';
107 $scope.loading = false;
108 return;
109 }
110 // The netmask prefix length will be undefined if outside range
111 if (!$scope.interface.ipv4.values[i].PrefixLength) {
112 $scope.set_network_error =
113 $scope.interface.ipv4.values[i].Address +
114 ' invalid Prefix Length parameter';
115 $scope.loading = false;
116 return;
117 }
Gunnar Millsa45c3852018-05-30 16:18:45 -0500118 if ($scope.interface.ipv4.values[i].Address !=
119 $scope.old_interface.ipv4.values[i].Address ||
120 $scope.interface.ipv4.values[i].PrefixLength !=
121 $scope.old_interface.ipv4.values[i].PrefixLength ||
122 $scope.interface.ipv4.values[i].Gateway !=
123 $scope.old_interface.ipv4.values[i].Gateway) {
124 promises.push(setIPV4(i));
125 }
126 }
127 }
128
Gunnar Mills0af165b2018-06-01 16:24:56 -0500129 if (promises.length) {
130 $q.all(promises).finally(function() {
131 $scope.loading = false;
132 if (!$scope.set_network_error) {
133 $scope.set_network_success = true;
134 // Since an IPV4 interface (e.g. IP address, gateway, or netmask)
135 // edit is a delete then an add and the GUI can't calculate the
136 // interface id (e.g. 5c083707) beforehand and it is not returned
137 // by the REST call, openbmc#3227, reload the page after an edit,
138 // which makes a 2nd REST call.
139 // Do this for all network changes due to the possibility of a set
140 // network failing even though it returned success, openbmc#1641,
141 // and to update dataService and old_interface to know which
142 // data has changed if the user continues to edit network
143 // settings.
144 // TODO: The reload is not ideal. Revisit this.
145 $timeout(function() {
Gunnar Millsa3f75322018-07-10 17:06:02 -0500146 loadNetworkInfo();
Gunnar Mills0af165b2018-06-01 16:24:56 -0500147 }, 4000);
148 }
149 });
150 } else {
Gunnar Mills84981f02018-05-31 15:19:01 -0500151 $scope.loading = false;
Gunnar Mills0af165b2018-06-01 16:24:56 -0500152 }
Gunnar Millsdca79d72018-05-30 13:07:01 -0500153
154 };
155
156 function setMACAddress() {
157 return APIUtils
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500158 .setMACAddress(
159 $scope.selectedInterface, $scope.interface.MACAddress)
160 .then(
Gunnar Millsdca79d72018-05-30 13:07:01 -0500161 function(data) {},
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500162 function(error) {
Gunnar Millsdca79d72018-05-30 13:07:01 -0500163 console.log(JSON.stringify(error));
Gunnar Mills7ddc7272018-04-12 16:12:03 -0500164 $scope.set_network_error = 'MAC Address';
165 });
Gunnar Millsdca79d72018-05-30 13:07:01 -0500166 }
167
168 function setDefaultGateway() {
169 return APIUtils.setDefaultGateway($scope.defaultgateway)
170 .then(
171 function(data) {},
172 function(error) {
173 console.log(JSON.stringify(error));
174 $scope.set_network_error = 'Default Gateway';
175 });
176 }
Gunnar Mills309e06a2018-05-30 13:18:10 -0500177
178 function setHostname() {
179 return APIUtils.setHostname($scope.hostname)
180 .then(
181 function(data) {},
182 function(error) {
183 console.log(JSON.stringify(error));
184 $scope.set_network_error = 'Hostname';
185 });
186 }
187
Gunnar Millscb2c3062018-05-31 13:13:30 -0500188 function setDHCPEnabled() {
189 return APIUtils
190 .setDHCPEnabled(
191 $scope.selectedInterface, $scope.interface.DHCPEnabled)
192 .then(
193 function(data) {},
194 function(error) {
195 console.log(JSON.stringify(error));
196 $scope.set_network_error = 'DHCP';
197 });
198 }
199
Gunnar Mills06467822018-06-06 15:43:18 -0500200 function setNameservers() {
Gunnar Mills82658292018-06-06 16:51:32 -0500201 // Nameservers does not allow an empty array, since we remove all empty
Gunnar Mills9863d122018-07-11 13:36:43 -0500202 // strings above, could have an empty array. TODO: openbmc/openbmc#3240
Gunnar Mills82658292018-06-06 16:51:32 -0500203 if ($scope.interface.Nameservers.length == 0) {
204 $scope.interface.Nameservers.push('');
205 }
Gunnar Mills06467822018-06-06 15:43:18 -0500206 return APIUtils
207 .setNameservers(
208 $scope.selectedInterface, $scope.interface.Nameservers)
209 .then(
210 function(data) {},
211 function(error) {
212 console.log(JSON.stringify(error));
213 $scope.set_network_error = 'DNS Servers';
214 });
215 }
216
Gunnar Millsa45c3852018-05-30 16:18:45 -0500217 function setIPV4(index) {
218 // The correct way to edit an IPV4 interface is to remove it and then
219 // add a new one
220 return APIUtils
221 .deleteIPV4(
222 $scope.selectedInterface, $scope.interface.ipv4.ids[index])
223 .then(
224 function(data) {
225 return APIUtils
226 .addIPV4(
227 $scope.selectedInterface,
228 $scope.interface.ipv4.values[index].Address,
229 $scope.interface.ipv4.values[index].PrefixLength,
230 $scope.interface.ipv4.values[index].Gateway)
231 .then(
232 function(data) {},
233 function(error) {
234 console.log(JSON.stringify(error));
235 $scope.set_network_error =
236 $scope.interface.ipv4.values[index].Address;
237 });
238 },
239 function(error) {
240 console.log(JSON.stringify(error));
241 $scope.set_network_error =
242 $scope.interface.ipv4.values[index].Address;
243 });
244 }
245
Gunnar Mills9a0094d2018-05-02 21:50:56 -0500246 $scope.refresh = function() {
Gunnar Millsa3f75322018-07-10 17:06:02 -0500247 loadNetworkInfo();
Gunnar Mills9a0094d2018-05-02 21:50:56 -0500248 };
Gunnar Millsa3f75322018-07-10 17:06:02 -0500249
250 function loadNetworkInfo() {
251 APIUtils.getNetworkInfo().then(function(data) {
252 dataService.setNetworkInfo(data);
253 $scope.network = data.formatted_data;
254 $scope.hostname = data.hostname;
255 $scope.defaultgateway = data.defaultgateway;
256 if ($scope.network.interface_ids.length) {
Rebecca Shawffdef962018-07-19 13:37:37 -0500257 // Use the first network interface if the user hasn't chosen one
Gunnar Millsa3f75322018-07-10 17:06:02 -0500258 if (!$scope.selectedInterface ||
259 !$scope.network.interfaces[$scope.selectedInterface]) {
260 $scope.selectedInterface = $scope.network.interface_ids[0];
261 }
262 $scope.interface =
263 $scope.network.interfaces[$scope.selectedInterface];
264 // Copy the interface so we know later if changes were made to the
265 // page
266 $scope.old_interface = JSON.parse(JSON.stringify($scope.interface));
267 }
268 });
269 }
Andrew Geisslerd27bb132018-05-24 11:07:27 -0700270 }
271 ]);
Iftekharul Islamcd789502017-04-19 14:37:55 -0500272
273})(angular);