xref: /openbmc/phosphor-webui/app/configuration/controllers/network-controller.js (revision 9aee5e672b5429169a299494f368f9c4498432bf)
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',
1427ce84d2Sbeccabroek    'toastService',
159a3b5422Sbeccabroek    function(
1627ce84d2Sbeccabroek        $scope, $window, APIUtils, dataService, $timeout, $route, $q,
1727ce84d2Sbeccabroek        toastService) {
18cd789508SIftekharul Islam      $scope.dataService = dataService;
192a489554SIftekharul Islam      $scope.network = {};
20067a1cd1Sbeccabroek      $scope.oldInterface = {};
212a489554SIftekharul Islam      $scope.interface = {};
222a489554SIftekharul Islam      $scope.networkDevice = false;
23ba5e3f34SAndrew Geissler      $scope.hostname = '';
24067a1cd1Sbeccabroek      $scope.defaultGateway = '';
257ddc7274SGunnar Mills      $scope.selectedInterface = '';
26067a1cd1Sbeccabroek      $scope.confirmSettings = false;
2784981f0aSGunnar Mills      $scope.loading = false;
28067a1cd1Sbeccabroek      $scope.ipv4sToDelete = [];
292a489554SIftekharul Islam
30a3f75320SGunnar Mills      loadNetworkInfo();
31a3f75320SGunnar Mills
322a489554SIftekharul Islam      $scope.selectInterface = function(interfaceId) {
332a489554SIftekharul Islam        $scope.interface = $scope.network.interfaces[interfaceId];
34a45c3852SGunnar Mills        // Copy the interface so we know later if changes were made to the page
35067a1cd1Sbeccabroek        $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface));
362a489554SIftekharul Islam        $scope.selectedInterface = interfaceId;
372a489554SIftekharul Islam        $scope.networkDevice = false;
38ba5e3f34SAndrew Geissler      };
39bc3ab72cSGunnar Mills
40bc3ab72cSGunnar Mills      $scope.addDNSField = function() {
41bc3ab72cSGunnar Mills        $scope.interface.Nameservers.push('');
42bc3ab72cSGunnar Mills      };
43bc3ab72cSGunnar Mills
44cff61508Sbeccabroek      $scope.removeDNSField = function(index) {
45cff61508Sbeccabroek        $scope.interface.Nameservers.splice(index, 1);
46cff61508Sbeccabroek      };
47cff61508Sbeccabroek
481a0e7d06Sbeccabroek      $scope.addIpv4Field = function() {
491a0e7d06Sbeccabroek        $scope.interface.ipv4.values.push(
501a0e7d06Sbeccabroek            {Address: '', PrefixLength: '', Gateway: ''});
511a0e7d06Sbeccabroek      };
521a0e7d06Sbeccabroek
53971ac1aaSbeccabroek      $scope.removeIpv4Address = function(index) {
54971ac1aaSbeccabroek        // Check if the IPV4 being removed has an id. This indicates that it is
55971ac1aaSbeccabroek        // an existing address and needs to be removed in the back end.
56971ac1aaSbeccabroek        if ($scope.interface.ipv4.values[index].id) {
57067a1cd1Sbeccabroek          $scope.ipv4sToDelete.push($scope.interface.ipv4.values[index]);
58971ac1aaSbeccabroek        }
59971ac1aaSbeccabroek        $scope.interface.ipv4.values.splice(index, 1);
60971ac1aaSbeccabroek      };
61971ac1aaSbeccabroek
627ddc7274SGunnar Mills      $scope.setNetworkSettings = function() {
63d01504cfSGunnar Mills        // Hides the confirm network settings modal
64067a1cd1Sbeccabroek        $scope.confirmSettings = false;
6584981f0aSGunnar Mills        $scope.loading = true;
66dca79d73SGunnar Mills        var promises = [];
67dca79d73SGunnar Mills
68659651e8SGunnar Mills        // MAC Address are case-insensitive
69659651e8SGunnar Mills        if ($scope.interface.MACAddress.toLowerCase() !=
70659651e8SGunnar Mills            dataService.mac_address.toLowerCase()) {
71dca79d73SGunnar Mills          promises.push(setMACAddress());
72659651e8SGunnar Mills        }
73067a1cd1Sbeccabroek        if ($scope.defaultGateway != dataService.defaultgateway) {
74dca79d73SGunnar Mills          promises.push(setDefaultGateway());
75659651e8SGunnar Mills        }
76659651e8SGunnar Mills        if ($scope.hostname != dataService.hostname) {
77309e06abSGunnar Mills          promises.push(setHostname());
78659651e8SGunnar Mills        }
79067a1cd1Sbeccabroek        if ($scope.interface.DHCPEnabled != $scope.oldInterface.DHCPEnabled) {
80cb2c3060SGunnar Mills          promises.push(setDHCPEnabled());
81cb2c3060SGunnar Mills        }
82309e06abSGunnar Mills
8382658298SGunnar Mills        // Remove any empty strings from the array. Important because we add an
8482658298SGunnar Mills        // empty string to the end so the user can add a new DNS server, if the
8582658298SGunnar Mills        // user doesn't fill out the field, we don't want to add.
8682658298SGunnar Mills        $scope.interface.Nameservers =
8782658298SGunnar Mills            $scope.interface.Nameservers.filter(Boolean);
880646782dSGunnar Mills        // toString() is a cheap way to compare 2 string arrays
890646782dSGunnar Mills        if ($scope.interface.Nameservers.toString() !=
90067a1cd1Sbeccabroek            $scope.oldInterface.Nameservers.toString()) {
910646782dSGunnar Mills          promises.push(setNameservers());
920646782dSGunnar Mills        }
930646782dSGunnar Mills
94a45c3852SGunnar Mills        // Set IPV4 IP Addresses, Netmask Prefix Lengths, and Gateways
95a45c3852SGunnar Mills        if (!$scope.interface.DHCPEnabled) {
96971ac1aaSbeccabroek          // Delete existing IPV4 addresses that were removed
97971ac1aaSbeccabroek          promises.push(removeIPV4s());
981a0e7d06Sbeccabroek          // Update any changed IPV4 addresses and add new
99a45c3852SGunnar Mills          for (var i in $scope.interface.ipv4.values) {
1006549114eSGunnar Mills            if (!APIUtils.validIPV4IP(
1016549114eSGunnar Mills                    $scope.interface.ipv4.values[i].Address)) {
10227ce84d2Sbeccabroek              toastService.error(
1039a3b5422Sbeccabroek                  $scope.interface.ipv4.values[i].Address +
1049a3b5422Sbeccabroek                  ' invalid IP parameter');
1056549114eSGunnar Mills              $scope.loading = false;
1066549114eSGunnar Mills              return;
1076549114eSGunnar Mills            }
108*de2da859SDerick Montague            if ($scope.interface.ipv4.values[i].Gateway &&
109*de2da859SDerick Montague                !APIUtils.validIPV4IP(
1106549114eSGunnar Mills                    $scope.interface.ipv4.values[i].Gateway)) {
11127ce84d2Sbeccabroek              toastService.error(
1129a3b5422Sbeccabroek                  $scope.interface.ipv4.values[i].Address +
1139a3b5422Sbeccabroek                  ' 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) {
11927ce84d2Sbeccabroek              toastService.error(
1209a3b5422Sbeccabroek                  $scope.interface.ipv4.values[i].Address +
1219a3b5422Sbeccabroek                  ' invalid Prefix Length parameter');
1226549114eSGunnar Mills              $scope.loading = false;
1236549114eSGunnar Mills              return;
1246549114eSGunnar Mills            }
125067a1cd1Sbeccabroek            if ($scope.interface.ipv4.values[i].updateAddress ||
126067a1cd1Sbeccabroek                $scope.interface.ipv4.values[i].updateGateway ||
127067a1cd1Sbeccabroek                $scope.interface.ipv4.values[i].updatePrefix) {
1281a0e7d06Sbeccabroek              // If IPV4 has an id it means it already exists in the back end,
1291a0e7d06Sbeccabroek              // and in order to update it is required to remove previous IPV4
1301a0e7d06Sbeccabroek              // address and add new one. See openbmc/openbmc/issues/2163.
1311a0e7d06Sbeccabroek              // TODO: update to use PUT once issue 2163 is resolved.
1321a0e7d06Sbeccabroek              if ($scope.interface.ipv4.values[i].id) {
1331a0e7d06Sbeccabroek                promises.push(updateIPV4(i));
1341a0e7d06Sbeccabroek              } else {
1351a0e7d06Sbeccabroek                promises.push(addIPV4(i));
1361a0e7d06Sbeccabroek              }
137a45c3852SGunnar Mills            }
138a45c3852SGunnar Mills          }
139a45c3852SGunnar Mills        }
140a45c3852SGunnar Mills
1410af165b9SGunnar Mills        if (promises.length) {
1429a3b5422Sbeccabroek          $q.all(promises).then(
1439a3b5422Sbeccabroek              function(response) {
1449a3b5422Sbeccabroek                // Since an IPV4 interface (e.g. IP address, gateway, or
1459a3b5422Sbeccabroek                // netmask) edit is a delete then an add and the GUI can't
1469a3b5422Sbeccabroek                // calculate the interface id (e.g. 5c083707) beforehand and it
1479a3b5422Sbeccabroek                // is not returned by the REST call, openbmc#3227, reload the
1489a3b5422Sbeccabroek                // page after an edit, which makes a 2nd REST call. Do this for
1499a3b5422Sbeccabroek                // all network changes due to the possibility of a set network
1509a3b5422Sbeccabroek                // failing even though it returned success, openbmc#1641, and to
1519a3b5422Sbeccabroek                // update dataService and oldInterface to know which data has
1529a3b5422Sbeccabroek                // changed if the user continues to edit network settings.
1530af165b9SGunnar Mills                // TODO: The reload is not ideal. Revisit this.
1540af165b9SGunnar Mills                $timeout(function() {
155a3f75320SGunnar Mills                  loadNetworkInfo();
1569a3b5422Sbeccabroek                  $scope.loading = false;
15727ce84d2Sbeccabroek                  toastService.success('Network settings saved');
1580af165b9SGunnar Mills                }, 4000);
1599a3b5422Sbeccabroek              },
1609a3b5422Sbeccabroek              function(error) {
1619a3b5422Sbeccabroek                $scope.loading = false;
16227ce84d2Sbeccabroek                toastService.error('Network settings could not be saved');
1639a3b5422Sbeccabroek              })
1640af165b9SGunnar Mills        } else {
1650af165b9SGunnar Mills          $scope.loading = false;
1660af165b9SGunnar Mills        }
167dca79d73SGunnar Mills      };
168dca79d73SGunnar Mills
169dca79d73SGunnar Mills      function setMACAddress() {
170dca79d73SGunnar Mills        return APIUtils
1717ddc7274SGunnar Mills            .setMACAddress(
1727ddc7274SGunnar Mills                $scope.selectedInterface, $scope.interface.MACAddress)
1737ddc7274SGunnar Mills            .then(
174dca79d73SGunnar Mills                function(data) {},
1757ddc7274SGunnar Mills                function(error) {
176dca79d73SGunnar Mills                  console.log(JSON.stringify(error));
1779a3b5422Sbeccabroek                  return $q.reject();
1787ddc7274SGunnar Mills                });
179dca79d73SGunnar Mills      }
180dca79d73SGunnar Mills
181dca79d73SGunnar Mills      function setDefaultGateway() {
182067a1cd1Sbeccabroek        return APIUtils.setDefaultGateway($scope.defaultGateway)
183dca79d73SGunnar Mills            .then(
184dca79d73SGunnar Mills                function(data) {},
185dca79d73SGunnar Mills                function(error) {
186dca79d73SGunnar Mills                  console.log(JSON.stringify(error));
1879a3b5422Sbeccabroek                  return $q.reject();
188dca79d73SGunnar Mills                });
189dca79d73SGunnar Mills      }
190309e06abSGunnar Mills
191309e06abSGunnar Mills      function setHostname() {
192309e06abSGunnar Mills        return APIUtils.setHostname($scope.hostname)
193309e06abSGunnar Mills            .then(
194309e06abSGunnar Mills                function(data) {},
195309e06abSGunnar Mills                function(error) {
196309e06abSGunnar Mills                  console.log(JSON.stringify(error));
1979a3b5422Sbeccabroek                  return $q.reject();
198309e06abSGunnar Mills                });
199309e06abSGunnar Mills      }
200309e06abSGunnar Mills
201cb2c3060SGunnar Mills      function setDHCPEnabled() {
202cb2c3060SGunnar Mills        return APIUtils
203cb2c3060SGunnar Mills            .setDHCPEnabled(
204cb2c3060SGunnar Mills                $scope.selectedInterface, $scope.interface.DHCPEnabled)
205cb2c3060SGunnar Mills            .then(
206cb2c3060SGunnar Mills                function(data) {},
207cb2c3060SGunnar Mills                function(error) {
208cb2c3060SGunnar Mills                  console.log(JSON.stringify(error));
2099a3b5422Sbeccabroek                  return $q.reject();
210cb2c3060SGunnar Mills                });
211cb2c3060SGunnar Mills      }
212cb2c3060SGunnar Mills
2130646782dSGunnar Mills      function setNameservers() {
2140646782dSGunnar Mills        return APIUtils
2150646782dSGunnar Mills            .setNameservers(
2160646782dSGunnar Mills                $scope.selectedInterface, $scope.interface.Nameservers)
2170646782dSGunnar Mills            .then(
2180646782dSGunnar Mills                function(data) {},
2190646782dSGunnar Mills                function(error) {
2200646782dSGunnar Mills                  console.log(JSON.stringify(error));
2219a3b5422Sbeccabroek                  return $q.reject();
2220646782dSGunnar Mills                });
2230646782dSGunnar Mills      }
2240646782dSGunnar Mills
225971ac1aaSbeccabroek      function removeIPV4s() {
226067a1cd1Sbeccabroek        return $scope.ipv4sToDelete.map(function(ipv4) {
227971ac1aaSbeccabroek          return APIUtils.deleteIPV4($scope.selectedInterface, ipv4.id)
228971ac1aaSbeccabroek              .then(
229971ac1aaSbeccabroek                  function(data) {},
230971ac1aaSbeccabroek                  function(error) {
231971ac1aaSbeccabroek                    console.log(JSON.stringify(error));
2329a3b5422Sbeccabroek                    return $q.reject();
233971ac1aaSbeccabroek                  })
234971ac1aaSbeccabroek        });
235971ac1aaSbeccabroek      }
236971ac1aaSbeccabroek
2371a0e7d06Sbeccabroek      function addIPV4(index) {
2381a0e7d06Sbeccabroek        return APIUtils
2391a0e7d06Sbeccabroek            .addIPV4(
2401a0e7d06Sbeccabroek                $scope.selectedInterface,
2411a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].Address,
2421a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].PrefixLength,
2431a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].Gateway)
2441a0e7d06Sbeccabroek            .then(
2451a0e7d06Sbeccabroek                function(data) {},
2461a0e7d06Sbeccabroek                function(error) {
2471a0e7d06Sbeccabroek                  console.log(JSON.stringify(error));
2489a3b5422Sbeccabroek                  return $q.reject();
2491a0e7d06Sbeccabroek                })
2501a0e7d06Sbeccabroek      }
2511a0e7d06Sbeccabroek
2521a0e7d06Sbeccabroek      function updateIPV4(index) {
253a45c3852SGunnar Mills        // The correct way to edit an IPV4 interface is to remove it and then
254a45c3852SGunnar Mills        // add a new one
255a45c3852SGunnar Mills        return APIUtils
256a45c3852SGunnar Mills            .deleteIPV4(
2571a0e7d06Sbeccabroek                $scope.selectedInterface,
2581a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].id)
259a45c3852SGunnar Mills            .then(
260a45c3852SGunnar Mills                function(data) {
261a45c3852SGunnar Mills                  return APIUtils
262a45c3852SGunnar Mills                      .addIPV4(
263a45c3852SGunnar Mills                          $scope.selectedInterface,
264a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].Address,
265a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].PrefixLength,
266a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].Gateway)
267a45c3852SGunnar Mills                      .then(
268a45c3852SGunnar Mills                          function(data) {},
269a45c3852SGunnar Mills                          function(error) {
270a45c3852SGunnar Mills                            console.log(JSON.stringify(error));
2719a3b5422Sbeccabroek                            return $q.reject();
272a45c3852SGunnar Mills                          });
273a45c3852SGunnar Mills                },
274a45c3852SGunnar Mills                function(error) {
275a45c3852SGunnar Mills                  console.log(JSON.stringify(error));
2769a3b5422Sbeccabroek                  return $q.reject();
277a45c3852SGunnar Mills                });
278a45c3852SGunnar Mills      }
279a45c3852SGunnar Mills
2809a0094dcSGunnar Mills      $scope.refresh = function() {
281a3f75320SGunnar Mills        loadNetworkInfo();
2829a0094dcSGunnar Mills      };
283a3f75320SGunnar Mills
284a3f75320SGunnar Mills      function loadNetworkInfo() {
2852a489554SIftekharul Islam        APIUtils.getNetworkInfo().then(function(data) {
286659651e8SGunnar Mills          dataService.setNetworkInfo(data);
2872a489554SIftekharul Islam          $scope.network = data.formatted_data;
2882a489554SIftekharul Islam          $scope.hostname = data.hostname;
289067a1cd1Sbeccabroek          $scope.defaultGateway = data.defaultgateway;
2902a489554SIftekharul Islam          if ($scope.network.interface_ids.length) {
291ffdef96dSRebecca Shaw            // Use the first network interface if the user hasn't chosen one
292a3f75320SGunnar Mills            if (!$scope.selectedInterface ||
293a3f75320SGunnar Mills                !$scope.network.interfaces[$scope.selectedInterface]) {
2942a489554SIftekharul Islam              $scope.selectedInterface = $scope.network.interface_ids[0];
295a3f75320SGunnar Mills            }
296d27bb135SAndrew Geissler            $scope.interface =
297d27bb135SAndrew Geissler                $scope.network.interfaces[$scope.selectedInterface];
298a45c3852SGunnar Mills            // Copy the interface so we know later if changes were made to the
299a45c3852SGunnar Mills            // page
300067a1cd1Sbeccabroek            $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface));
3012a489554SIftekharul Islam          }
3021a0e7d06Sbeccabroek          // Add id values and update flags to corresponding IPV4 objects
303971ac1aaSbeccabroek          for (var i = 0; i < $scope.interface.ipv4.values.length; i++) {
304971ac1aaSbeccabroek            $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i];
305067a1cd1Sbeccabroek            $scope.interface.ipv4.values[i].updateAddress = false;
306067a1cd1Sbeccabroek            $scope.interface.ipv4.values[i].updateGateway = false;
307067a1cd1Sbeccabroek            $scope.interface.ipv4.values[i].updatePrefix = false;
308971ac1aaSbeccabroek          }
3092a489554SIftekharul Islam        });
310cd789508SIftekharul Islam      }
311a3f75320SGunnar Mills    }
312ba5e3f34SAndrew Geissler  ]);
313cd789508SIftekharul Islam})(angular);
314