xref: /openbmc/phosphor-webui/app/configuration/controllers/network-controller.js (revision 1a0e7d062c800a0cd056d1c211a27e20d48ed256)
1cd789508SIftekharul Islam/**
2cd789508SIftekharul Islam * Controller for network
3cd789508SIftekharul Islam *
4cd789508SIftekharul Islam * @module app/configuration
5cd789508SIftekharul Islam * @exports networkController
6cd789508SIftekharul Islam * @name networkController
7cd789508SIftekharul Islam */
8cd789508SIftekharul Islam
9cd789508SIftekharul Islamwindow.angular && (function(angular) {
10cd789508SIftekharul Islam  'use strict';
11cd789508SIftekharul Islam
12d27bb135SAndrew Geissler  angular.module('app.configuration').controller('networkController', [
130af165b9SGunnar Mills    '$scope', '$window', 'APIUtils', 'dataService', '$timeout', '$route', '$q',
140af165b9SGunnar Mills    function($scope, $window, APIUtils, dataService, $timeout, $route, $q) {
15cd789508SIftekharul Islam      $scope.dataService = dataService;
162a489554SIftekharul Islam      $scope.network = {};
17a45c3852SGunnar Mills      $scope.old_interface = {};
182a489554SIftekharul Islam      $scope.interface = {};
192a489554SIftekharul Islam      $scope.networkDevice = false;
20ba5e3f34SAndrew Geissler      $scope.hostname = '';
21e9f5fe77SGunnar Mills      $scope.defaultgateway = '';
227ddc7274SGunnar Mills      $scope.set_network_error = '';
237ddc7274SGunnar Mills      $scope.set_network_success = false;
247ddc7274SGunnar Mills      $scope.selectedInterface = '';
25d01504cfSGunnar Mills      $scope.confirm_settings = false;
2684981f0aSGunnar Mills      $scope.loading = false;
27971ac1aaSbeccabroek      $scope.IPV4s_to_delete = [];
282a489554SIftekharul Islam
29a3f75320SGunnar Mills      loadNetworkInfo();
30a3f75320SGunnar Mills
312a489554SIftekharul Islam      $scope.selectInterface = function(interfaceId) {
322a489554SIftekharul Islam        $scope.interface = $scope.network.interfaces[interfaceId];
33a45c3852SGunnar Mills        // Copy the interface so we know later if changes were made to the page
34a45c3852SGunnar Mills        $scope.old_interface = JSON.parse(JSON.stringify($scope.interface));
352a489554SIftekharul Islam        $scope.selectedInterface = interfaceId;
362a489554SIftekharul Islam        $scope.networkDevice = false;
37ba5e3f34SAndrew Geissler      };
38bc3ab72cSGunnar Mills
39bc3ab72cSGunnar Mills      $scope.addDNSField = function() {
40bc3ab72cSGunnar Mills        $scope.interface.Nameservers.push('');
41bc3ab72cSGunnar Mills      };
42bc3ab72cSGunnar Mills
43cff61508Sbeccabroek      $scope.removeDNSField = function(index) {
44cff61508Sbeccabroek        $scope.interface.Nameservers.splice(index, 1);
45cff61508Sbeccabroek      };
46cff61508Sbeccabroek
47*1a0e7d06Sbeccabroek      $scope.addIpv4Field = function() {
48*1a0e7d06Sbeccabroek        $scope.interface.ipv4.values.push(
49*1a0e7d06Sbeccabroek            {Address: '', PrefixLength: '', Gateway: ''});
50*1a0e7d06Sbeccabroek      };
51*1a0e7d06Sbeccabroek
52971ac1aaSbeccabroek      $scope.removeIpv4Address = function(index) {
53971ac1aaSbeccabroek        // Check if the IPV4 being removed has an id. This indicates that it is
54971ac1aaSbeccabroek        // an existing address and needs to be removed in the back end.
55971ac1aaSbeccabroek        if ($scope.interface.ipv4.values[index].id) {
56971ac1aaSbeccabroek          $scope.IPV4s_to_delete.push($scope.interface.ipv4.values[index]);
57971ac1aaSbeccabroek        }
58971ac1aaSbeccabroek        $scope.interface.ipv4.values.splice(index, 1);
59971ac1aaSbeccabroek      };
60971ac1aaSbeccabroek
617ddc7274SGunnar Mills      $scope.setNetworkSettings = function() {
62d01504cfSGunnar Mills        // Hides the confirm network settings modal
63d01504cfSGunnar Mills        $scope.confirm_settings = false;
647ddc7274SGunnar Mills        $scope.set_network_error = '';
657ddc7274SGunnar Mills        $scope.set_network_success = false;
6684981f0aSGunnar Mills        $scope.loading = true;
67dca79d73SGunnar Mills        var promises = [];
68dca79d73SGunnar Mills
69659651e8SGunnar Mills        // MAC Address are case-insensitive
70659651e8SGunnar Mills        if ($scope.interface.MACAddress.toLowerCase() !=
71659651e8SGunnar Mills            dataService.mac_address.toLowerCase()) {
72dca79d73SGunnar Mills          promises.push(setMACAddress());
73659651e8SGunnar Mills        }
74659651e8SGunnar Mills        if ($scope.defaultgateway != dataService.defaultgateway) {
75dca79d73SGunnar Mills          promises.push(setDefaultGateway());
76659651e8SGunnar Mills        }
77659651e8SGunnar Mills        if ($scope.hostname != dataService.hostname) {
78309e06abSGunnar Mills          promises.push(setHostname());
79659651e8SGunnar Mills        }
80cb2c3060SGunnar Mills        if ($scope.interface.DHCPEnabled != $scope.old_interface.DHCPEnabled) {
81cb2c3060SGunnar Mills          promises.push(setDHCPEnabled());
82cb2c3060SGunnar Mills        }
83309e06abSGunnar Mills
8482658298SGunnar Mills        // Remove any empty strings from the array. Important because we add an
8582658298SGunnar Mills        // empty string to the end so the user can add a new DNS server, if the
8682658298SGunnar Mills        // user doesn't fill out the field, we don't want to add.
8782658298SGunnar Mills        $scope.interface.Nameservers =
8882658298SGunnar Mills            $scope.interface.Nameservers.filter(Boolean);
890646782dSGunnar Mills        // toString() is a cheap way to compare 2 string arrays
900646782dSGunnar Mills        if ($scope.interface.Nameservers.toString() !=
910646782dSGunnar Mills            $scope.old_interface.Nameservers.toString()) {
920646782dSGunnar Mills          promises.push(setNameservers());
930646782dSGunnar Mills        }
940646782dSGunnar Mills
95a45c3852SGunnar Mills        // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways
96a45c3852SGunnar Mills        if (!$scope.interface.DHCPEnabled) {
97971ac1aaSbeccabroek          // Delete existing IPV4 addresses that were removed
98971ac1aaSbeccabroek          promises.push(removeIPV4s());
99*1a0e7d06Sbeccabroek          // Update any changed IPV4 addresses and add new
100a45c3852SGunnar Mills          for (var i in $scope.interface.ipv4.values) {
1016549114eSGunnar Mills            if (!APIUtils.validIPV4IP(
1026549114eSGunnar Mills                    $scope.interface.ipv4.values[i].Address)) {
1036549114eSGunnar Mills              $scope.set_network_error =
1046549114eSGunnar Mills                  $scope.interface.ipv4.values[i].Address +
1056549114eSGunnar Mills                  ' invalid IP parameter';
1066549114eSGunnar Mills              $scope.loading = false;
1076549114eSGunnar Mills              return;
1086549114eSGunnar Mills            }
1096549114eSGunnar Mills            if (!APIUtils.validIPV4IP(
1106549114eSGunnar Mills                    $scope.interface.ipv4.values[i].Gateway)) {
1116549114eSGunnar Mills              $scope.set_network_error =
1126549114eSGunnar Mills                  $scope.interface.ipv4.values[i].Address +
1136549114eSGunnar Mills                  ' invalid gateway parameter';
1146549114eSGunnar Mills              $scope.loading = false;
1156549114eSGunnar Mills              return;
1166549114eSGunnar Mills            }
1176549114eSGunnar Mills            // The netmask prefix length will be undefined if outside range
1186549114eSGunnar Mills            if (!$scope.interface.ipv4.values[i].PrefixLength) {
1196549114eSGunnar Mills              $scope.set_network_error =
1206549114eSGunnar Mills                  $scope.interface.ipv4.values[i].Address +
1216549114eSGunnar Mills                  ' invalid Prefix Length parameter';
1226549114eSGunnar Mills              $scope.loading = false;
1236549114eSGunnar Mills              return;
1246549114eSGunnar Mills            }
125*1a0e7d06Sbeccabroek            if ($scope.interface.ipv4.values[i].update_address ||
126*1a0e7d06Sbeccabroek                $scope.interface.ipv4.values[i].update_gateway ||
127*1a0e7d06Sbeccabroek                $scope.interface.ipv4.values[i].update_prefix) {
128*1a0e7d06Sbeccabroek              // If IPV4 has an id it means it already exists in the back end,
129*1a0e7d06Sbeccabroek              // and in order to update it is required to remove previous IPV4
130*1a0e7d06Sbeccabroek              // address and add new one. See openbmc/openbmc/issues/2163.
131*1a0e7d06Sbeccabroek              // TODO: update to use PUT once issue 2163 is resolved.
132*1a0e7d06Sbeccabroek              if ($scope.interface.ipv4.values[i].id) {
133*1a0e7d06Sbeccabroek                promises.push(updateIPV4(i));
134*1a0e7d06Sbeccabroek              } else {
135*1a0e7d06Sbeccabroek                promises.push(addIPV4(i));
136*1a0e7d06Sbeccabroek              }
137a45c3852SGunnar Mills            }
138a45c3852SGunnar Mills          }
139a45c3852SGunnar Mills        }
140a45c3852SGunnar Mills
1410af165b9SGunnar Mills        if (promises.length) {
142dca79d73SGunnar Mills          $q.all(promises).finally(function() {
14384981f0aSGunnar Mills            $scope.loading = false;
1440af165b9SGunnar Mills            if (!$scope.set_network_error) {
145dca79d73SGunnar Mills              $scope.set_network_success = true;
1460af165b9SGunnar Mills              // Since an IPV4 interface (e.g. IP address, gateway, or netmask)
1470af165b9SGunnar Mills              // edit is a delete then an add and the GUI can't calculate the
1480af165b9SGunnar Mills              // interface id (e.g. 5c083707) beforehand and it is not returned
1490af165b9SGunnar Mills              // by the REST call, openbmc#3227, reload the page after an edit,
1500af165b9SGunnar Mills              // which makes a 2nd REST call.
1510af165b9SGunnar Mills              // Do this for all network changes due to the possibility of a set
1520af165b9SGunnar Mills              // network failing even though it returned success, openbmc#1641,
1530af165b9SGunnar Mills              // and to update dataService and old_interface to know which
1540af165b9SGunnar Mills              // data has changed if the user continues to edit network
1550af165b9SGunnar Mills              // settings.
1560af165b9SGunnar Mills              // TODO: The reload is not ideal. Revisit this.
1570af165b9SGunnar Mills              $timeout(function() {
158a3f75320SGunnar Mills                loadNetworkInfo();
1590af165b9SGunnar Mills              }, 4000);
160dca79d73SGunnar Mills            }
161dca79d73SGunnar Mills          });
1620af165b9SGunnar Mills        } else {
1630af165b9SGunnar Mills          $scope.loading = false;
1640af165b9SGunnar Mills        }
165dca79d73SGunnar Mills      };
166dca79d73SGunnar Mills
167dca79d73SGunnar Mills      function setMACAddress() {
168dca79d73SGunnar Mills        return APIUtils
1697ddc7274SGunnar Mills            .setMACAddress(
1707ddc7274SGunnar Mills                $scope.selectedInterface, $scope.interface.MACAddress)
1717ddc7274SGunnar Mills            .then(
172dca79d73SGunnar Mills                function(data) {},
1737ddc7274SGunnar Mills                function(error) {
174dca79d73SGunnar Mills                  console.log(JSON.stringify(error));
1757ddc7274SGunnar Mills                  $scope.set_network_error = 'MAC Address';
1767ddc7274SGunnar Mills                });
177dca79d73SGunnar Mills      }
178dca79d73SGunnar Mills
179dca79d73SGunnar Mills      function setDefaultGateway() {
180dca79d73SGunnar Mills        return APIUtils.setDefaultGateway($scope.defaultgateway)
181dca79d73SGunnar Mills            .then(
182dca79d73SGunnar Mills                function(data) {},
183dca79d73SGunnar Mills                function(error) {
184dca79d73SGunnar Mills                  console.log(JSON.stringify(error));
185dca79d73SGunnar Mills                  $scope.set_network_error = 'Default Gateway';
186dca79d73SGunnar Mills                });
187dca79d73SGunnar Mills      }
188309e06abSGunnar Mills
189309e06abSGunnar Mills      function setHostname() {
190309e06abSGunnar Mills        return APIUtils.setHostname($scope.hostname)
191309e06abSGunnar Mills            .then(
192309e06abSGunnar Mills                function(data) {},
193309e06abSGunnar Mills                function(error) {
194309e06abSGunnar Mills                  console.log(JSON.stringify(error));
195309e06abSGunnar Mills                  $scope.set_network_error = 'Hostname';
196309e06abSGunnar Mills                });
197309e06abSGunnar Mills      }
198309e06abSGunnar Mills
199cb2c3060SGunnar Mills      function setDHCPEnabled() {
200cb2c3060SGunnar Mills        return APIUtils
201cb2c3060SGunnar Mills            .setDHCPEnabled(
202cb2c3060SGunnar Mills                $scope.selectedInterface, $scope.interface.DHCPEnabled)
203cb2c3060SGunnar Mills            .then(
204cb2c3060SGunnar Mills                function(data) {},
205cb2c3060SGunnar Mills                function(error) {
206cb2c3060SGunnar Mills                  console.log(JSON.stringify(error));
207cb2c3060SGunnar Mills                  $scope.set_network_error = 'DHCP';
208cb2c3060SGunnar Mills                });
209cb2c3060SGunnar Mills      }
210cb2c3060SGunnar Mills
2110646782dSGunnar Mills      function setNameservers() {
21282658298SGunnar Mills        // Nameservers does not allow an empty array, since we remove all empty
2139863d121SGunnar Mills        // strings above, could have an empty array. TODO: openbmc/openbmc#3240
21482658298SGunnar Mills        if ($scope.interface.Nameservers.length == 0) {
21582658298SGunnar Mills          $scope.interface.Nameservers.push('');
21682658298SGunnar Mills        }
2170646782dSGunnar Mills        return APIUtils
2180646782dSGunnar Mills            .setNameservers(
2190646782dSGunnar Mills                $scope.selectedInterface, $scope.interface.Nameservers)
2200646782dSGunnar Mills            .then(
2210646782dSGunnar Mills                function(data) {},
2220646782dSGunnar Mills                function(error) {
2230646782dSGunnar Mills                  console.log(JSON.stringify(error));
2240646782dSGunnar Mills                  $scope.set_network_error = 'DNS Servers';
2250646782dSGunnar Mills                });
2260646782dSGunnar Mills      }
2270646782dSGunnar Mills
228971ac1aaSbeccabroek      function removeIPV4s() {
229971ac1aaSbeccabroek        return $scope.IPV4s_to_delete.map(function(ipv4) {
230971ac1aaSbeccabroek          return APIUtils.deleteIPV4($scope.selectedInterface, ipv4.id)
231971ac1aaSbeccabroek              .then(
232971ac1aaSbeccabroek                  function(data) {},
233971ac1aaSbeccabroek                  function(error) {
234971ac1aaSbeccabroek                    console.log(JSON.stringify(error));
235971ac1aaSbeccabroek                    $scope.set_network_error = ipv4.Address;
236971ac1aaSbeccabroek                  })
237971ac1aaSbeccabroek        });
238971ac1aaSbeccabroek      }
239971ac1aaSbeccabroek
240*1a0e7d06Sbeccabroek      function addIPV4(index) {
241*1a0e7d06Sbeccabroek        return APIUtils
242*1a0e7d06Sbeccabroek            .addIPV4(
243*1a0e7d06Sbeccabroek                $scope.selectedInterface,
244*1a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].Address,
245*1a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].PrefixLength,
246*1a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].Gateway)
247*1a0e7d06Sbeccabroek            .then(
248*1a0e7d06Sbeccabroek                function(data) {},
249*1a0e7d06Sbeccabroek                function(error) {
250*1a0e7d06Sbeccabroek                  console.log(JSON.stringify(error));
251*1a0e7d06Sbeccabroek                  $scope.set_network_error =
252*1a0e7d06Sbeccabroek                      $scope.interface.ipv4.values[index].Address;
253*1a0e7d06Sbeccabroek                })
254*1a0e7d06Sbeccabroek      }
255*1a0e7d06Sbeccabroek
256*1a0e7d06Sbeccabroek      function updateIPV4(index) {
257a45c3852SGunnar Mills        // The correct way to edit an IPV4 interface is to remove it and then
258a45c3852SGunnar Mills        // add a new one
259a45c3852SGunnar Mills        return APIUtils
260a45c3852SGunnar Mills            .deleteIPV4(
261*1a0e7d06Sbeccabroek                $scope.selectedInterface,
262*1a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].id)
263a45c3852SGunnar Mills            .then(
264a45c3852SGunnar Mills                function(data) {
265a45c3852SGunnar Mills                  return APIUtils
266a45c3852SGunnar Mills                      .addIPV4(
267a45c3852SGunnar Mills                          $scope.selectedInterface,
268a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].Address,
269a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].PrefixLength,
270a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].Gateway)
271a45c3852SGunnar Mills                      .then(
272a45c3852SGunnar Mills                          function(data) {},
273a45c3852SGunnar Mills                          function(error) {
274a45c3852SGunnar Mills                            console.log(JSON.stringify(error));
275a45c3852SGunnar Mills                            $scope.set_network_error =
276a45c3852SGunnar Mills                                $scope.interface.ipv4.values[index].Address;
277a45c3852SGunnar Mills                          });
278a45c3852SGunnar Mills                },
279a45c3852SGunnar Mills                function(error) {
280a45c3852SGunnar Mills                  console.log(JSON.stringify(error));
281a45c3852SGunnar Mills                  $scope.set_network_error =
282a45c3852SGunnar Mills                      $scope.interface.ipv4.values[index].Address;
283a45c3852SGunnar Mills                });
284a45c3852SGunnar Mills      }
285a45c3852SGunnar Mills
2869a0094dcSGunnar Mills      $scope.refresh = function() {
287a3f75320SGunnar Mills        loadNetworkInfo();
2889a0094dcSGunnar Mills      };
289a3f75320SGunnar Mills
290a3f75320SGunnar Mills      function loadNetworkInfo() {
2912a489554SIftekharul Islam        APIUtils.getNetworkInfo().then(function(data) {
292659651e8SGunnar Mills          dataService.setNetworkInfo(data);
2932a489554SIftekharul Islam          $scope.network = data.formatted_data;
2942a489554SIftekharul Islam          $scope.hostname = data.hostname;
295e9f5fe77SGunnar Mills          $scope.defaultgateway = data.defaultgateway;
2962a489554SIftekharul Islam          if ($scope.network.interface_ids.length) {
297ffdef96dSRebecca Shaw            // Use the first network interface if the user hasn't chosen one
298a3f75320SGunnar Mills            if (!$scope.selectedInterface ||
299a3f75320SGunnar Mills                !$scope.network.interfaces[$scope.selectedInterface]) {
3002a489554SIftekharul Islam              $scope.selectedInterface = $scope.network.interface_ids[0];
301a3f75320SGunnar Mills            }
302d27bb135SAndrew Geissler            $scope.interface =
303d27bb135SAndrew Geissler                $scope.network.interfaces[$scope.selectedInterface];
304a45c3852SGunnar Mills            // Copy the interface so we know later if changes were made to the
305a45c3852SGunnar Mills            // page
306a45c3852SGunnar Mills            $scope.old_interface = JSON.parse(JSON.stringify($scope.interface));
3072a489554SIftekharul Islam          }
308*1a0e7d06Sbeccabroek          // Add id values and update flags to corresponding IPV4 objects
309971ac1aaSbeccabroek          for (var i = 0; i < $scope.interface.ipv4.values.length; i++) {
310971ac1aaSbeccabroek            $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i];
311*1a0e7d06Sbeccabroek            $scope.interface.ipv4.values[i].update_address = false;
312*1a0e7d06Sbeccabroek            $scope.interface.ipv4.values[i].update_gateway = false;
313*1a0e7d06Sbeccabroek            $scope.interface.ipv4.values[i].update_prefix = false;
314971ac1aaSbeccabroek          }
3152a489554SIftekharul Islam        });
316cd789508SIftekharul Islam      }
317a3f75320SGunnar Mills    }
318ba5e3f34SAndrew Geissler  ]);
319cd789508SIftekharul Islam})(angular);
320