xref: /openbmc/phosphor-webui/app/configuration/controllers/network-controller.js (revision 067a1cd156808a2053a678945c8fc419464e1bf0)
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 = {};
17*067a1cd1Sbeccabroek      $scope.oldInterface = {};
182a489554SIftekharul Islam      $scope.interface = {};
192a489554SIftekharul Islam      $scope.networkDevice = false;
20ba5e3f34SAndrew Geissler      $scope.hostname = '';
21*067a1cd1Sbeccabroek      $scope.defaultGateway = '';
22*067a1cd1Sbeccabroek      $scope.setNetworkError = '';
23*067a1cd1Sbeccabroek      $scope.setNetworkSuccess = false;
247ddc7274SGunnar Mills      $scope.selectedInterface = '';
25*067a1cd1Sbeccabroek      $scope.confirmSettings = false;
2684981f0aSGunnar Mills      $scope.loading = false;
27*067a1cd1Sbeccabroek      $scope.ipv4sToDelete = [];
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
34*067a1cd1Sbeccabroek        $scope.oldInterface = 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
471a0e7d06Sbeccabroek      $scope.addIpv4Field = function() {
481a0e7d06Sbeccabroek        $scope.interface.ipv4.values.push(
491a0e7d06Sbeccabroek            {Address: '', PrefixLength: '', Gateway: ''});
501a0e7d06Sbeccabroek      };
511a0e7d06Sbeccabroek
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) {
56*067a1cd1Sbeccabroek          $scope.ipv4sToDelete.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
63*067a1cd1Sbeccabroek        $scope.confirmSettings = false;
64*067a1cd1Sbeccabroek        $scope.setNetworkError = '';
65*067a1cd1Sbeccabroek        $scope.setNetworkSuccess = 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        }
74*067a1cd1Sbeccabroek        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        }
80*067a1cd1Sbeccabroek        if ($scope.interface.DHCPEnabled != $scope.oldInterface.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() !=
91*067a1cd1Sbeccabroek            $scope.oldInterface.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());
991a0e7d06Sbeccabroek          // 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)) {
103*067a1cd1Sbeccabroek              $scope.setNetworkError = $scope.interface.ipv4.values[i].Address +
1046549114eSGunnar Mills                  ' invalid IP parameter';
1056549114eSGunnar Mills              $scope.loading = false;
1066549114eSGunnar Mills              return;
1076549114eSGunnar Mills            }
1086549114eSGunnar Mills            if (!APIUtils.validIPV4IP(
1096549114eSGunnar Mills                    $scope.interface.ipv4.values[i].Gateway)) {
110*067a1cd1Sbeccabroek              $scope.setNetworkError = $scope.interface.ipv4.values[i].Address +
1116549114eSGunnar Mills                  ' invalid gateway parameter';
1126549114eSGunnar Mills              $scope.loading = false;
1136549114eSGunnar Mills              return;
1146549114eSGunnar Mills            }
1156549114eSGunnar Mills            // The netmask prefix length will be undefined if outside range
1166549114eSGunnar Mills            if (!$scope.interface.ipv4.values[i].PrefixLength) {
117*067a1cd1Sbeccabroek              $scope.setNetworkError = $scope.interface.ipv4.values[i].Address +
1186549114eSGunnar Mills                  ' invalid Prefix Length parameter';
1196549114eSGunnar Mills              $scope.loading = false;
1206549114eSGunnar Mills              return;
1216549114eSGunnar Mills            }
122*067a1cd1Sbeccabroek            if ($scope.interface.ipv4.values[i].updateAddress ||
123*067a1cd1Sbeccabroek                $scope.interface.ipv4.values[i].updateGateway ||
124*067a1cd1Sbeccabroek                $scope.interface.ipv4.values[i].updatePrefix) {
1251a0e7d06Sbeccabroek              // If IPV4 has an id it means it already exists in the back end,
1261a0e7d06Sbeccabroek              // and in order to update it is required to remove previous IPV4
1271a0e7d06Sbeccabroek              // address and add new one. See openbmc/openbmc/issues/2163.
1281a0e7d06Sbeccabroek              // TODO: update to use PUT once issue 2163 is resolved.
1291a0e7d06Sbeccabroek              if ($scope.interface.ipv4.values[i].id) {
1301a0e7d06Sbeccabroek                promises.push(updateIPV4(i));
1311a0e7d06Sbeccabroek              } else {
1321a0e7d06Sbeccabroek                promises.push(addIPV4(i));
1331a0e7d06Sbeccabroek              }
134a45c3852SGunnar Mills            }
135a45c3852SGunnar Mills          }
136a45c3852SGunnar Mills        }
137a45c3852SGunnar Mills
1380af165b9SGunnar Mills        if (promises.length) {
139dca79d73SGunnar Mills          $q.all(promises).finally(function() {
14084981f0aSGunnar Mills            $scope.loading = false;
141*067a1cd1Sbeccabroek            if (!$scope.setNetworkError) {
142*067a1cd1Sbeccabroek              $scope.setNetworkSuccess = true;
1430af165b9SGunnar Mills              // Since an IPV4 interface (e.g. IP address, gateway, or netmask)
1440af165b9SGunnar Mills              // edit is a delete then an add and the GUI can't calculate the
1450af165b9SGunnar Mills              // interface id (e.g. 5c083707) beforehand and it is not returned
1460af165b9SGunnar Mills              // by the REST call, openbmc#3227, reload the page after an edit,
1470af165b9SGunnar Mills              // which makes a 2nd REST call.
1480af165b9SGunnar Mills              // Do this for all network changes due to the possibility of a set
1490af165b9SGunnar Mills              // network failing even though it returned success, openbmc#1641,
150*067a1cd1Sbeccabroek              // and to update dataService and oldInterface to know which
1510af165b9SGunnar Mills              // data has changed if the user continues to edit network
1520af165b9SGunnar Mills              // settings.
1530af165b9SGunnar Mills              // TODO: The reload is not ideal. Revisit this.
1540af165b9SGunnar Mills              $timeout(function() {
155a3f75320SGunnar Mills                loadNetworkInfo();
1560af165b9SGunnar Mills              }, 4000);
157dca79d73SGunnar Mills            }
158dca79d73SGunnar Mills          });
1590af165b9SGunnar Mills        } else {
1600af165b9SGunnar Mills          $scope.loading = false;
1610af165b9SGunnar Mills        }
162dca79d73SGunnar Mills      };
163dca79d73SGunnar Mills
164dca79d73SGunnar Mills      function setMACAddress() {
165dca79d73SGunnar Mills        return APIUtils
1667ddc7274SGunnar Mills            .setMACAddress(
1677ddc7274SGunnar Mills                $scope.selectedInterface, $scope.interface.MACAddress)
1687ddc7274SGunnar Mills            .then(
169dca79d73SGunnar Mills                function(data) {},
1707ddc7274SGunnar Mills                function(error) {
171dca79d73SGunnar Mills                  console.log(JSON.stringify(error));
172*067a1cd1Sbeccabroek                  $scope.setNetworkError = 'MAC Address';
1737ddc7274SGunnar Mills                });
174dca79d73SGunnar Mills      }
175dca79d73SGunnar Mills
176dca79d73SGunnar Mills      function setDefaultGateway() {
177*067a1cd1Sbeccabroek        return APIUtils.setDefaultGateway($scope.defaultGateway)
178dca79d73SGunnar Mills            .then(
179dca79d73SGunnar Mills                function(data) {},
180dca79d73SGunnar Mills                function(error) {
181dca79d73SGunnar Mills                  console.log(JSON.stringify(error));
182*067a1cd1Sbeccabroek                  $scope.setNetworkError = 'Default Gateway';
183dca79d73SGunnar Mills                });
184dca79d73SGunnar Mills      }
185309e06abSGunnar Mills
186309e06abSGunnar Mills      function setHostname() {
187309e06abSGunnar Mills        return APIUtils.setHostname($scope.hostname)
188309e06abSGunnar Mills            .then(
189309e06abSGunnar Mills                function(data) {},
190309e06abSGunnar Mills                function(error) {
191309e06abSGunnar Mills                  console.log(JSON.stringify(error));
192*067a1cd1Sbeccabroek                  $scope.setNetworkError = 'Hostname';
193309e06abSGunnar Mills                });
194309e06abSGunnar Mills      }
195309e06abSGunnar Mills
196cb2c3060SGunnar Mills      function setDHCPEnabled() {
197cb2c3060SGunnar Mills        return APIUtils
198cb2c3060SGunnar Mills            .setDHCPEnabled(
199cb2c3060SGunnar Mills                $scope.selectedInterface, $scope.interface.DHCPEnabled)
200cb2c3060SGunnar Mills            .then(
201cb2c3060SGunnar Mills                function(data) {},
202cb2c3060SGunnar Mills                function(error) {
203cb2c3060SGunnar Mills                  console.log(JSON.stringify(error));
204*067a1cd1Sbeccabroek                  $scope.setNetworkError = 'DHCP';
205cb2c3060SGunnar Mills                });
206cb2c3060SGunnar Mills      }
207cb2c3060SGunnar Mills
2080646782dSGunnar Mills      function setNameservers() {
20982658298SGunnar Mills        // Nameservers does not allow an empty array, since we remove all empty
2109863d121SGunnar Mills        // strings above, could have an empty array. TODO: openbmc/openbmc#3240
21182658298SGunnar Mills        if ($scope.interface.Nameservers.length == 0) {
21282658298SGunnar Mills          $scope.interface.Nameservers.push('');
21382658298SGunnar Mills        }
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));
221*067a1cd1Sbeccabroek                  $scope.setNetworkError = 'DNS Servers';
2220646782dSGunnar Mills                });
2230646782dSGunnar Mills      }
2240646782dSGunnar Mills
225971ac1aaSbeccabroek      function removeIPV4s() {
226*067a1cd1Sbeccabroek        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));
232*067a1cd1Sbeccabroek                    $scope.setNetworkError = ipv4.Address;
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));
248*067a1cd1Sbeccabroek                  $scope.setNetworkError =
2491a0e7d06Sbeccabroek                      $scope.interface.ipv4.values[index].Address;
2501a0e7d06Sbeccabroek                })
2511a0e7d06Sbeccabroek      }
2521a0e7d06Sbeccabroek
2531a0e7d06Sbeccabroek      function updateIPV4(index) {
254a45c3852SGunnar Mills        // The correct way to edit an IPV4 interface is to remove it and then
255a45c3852SGunnar Mills        // add a new one
256a45c3852SGunnar Mills        return APIUtils
257a45c3852SGunnar Mills            .deleteIPV4(
2581a0e7d06Sbeccabroek                $scope.selectedInterface,
2591a0e7d06Sbeccabroek                $scope.interface.ipv4.values[index].id)
260a45c3852SGunnar Mills            .then(
261a45c3852SGunnar Mills                function(data) {
262a45c3852SGunnar Mills                  return APIUtils
263a45c3852SGunnar Mills                      .addIPV4(
264a45c3852SGunnar Mills                          $scope.selectedInterface,
265a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].Address,
266a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].PrefixLength,
267a45c3852SGunnar Mills                          $scope.interface.ipv4.values[index].Gateway)
268a45c3852SGunnar Mills                      .then(
269a45c3852SGunnar Mills                          function(data) {},
270a45c3852SGunnar Mills                          function(error) {
271a45c3852SGunnar Mills                            console.log(JSON.stringify(error));
272*067a1cd1Sbeccabroek                            $scope.setNetworkError =
273a45c3852SGunnar Mills                                $scope.interface.ipv4.values[index].Address;
274a45c3852SGunnar Mills                          });
275a45c3852SGunnar Mills                },
276a45c3852SGunnar Mills                function(error) {
277a45c3852SGunnar Mills                  console.log(JSON.stringify(error));
278*067a1cd1Sbeccabroek                  $scope.setNetworkError =
279a45c3852SGunnar Mills                      $scope.interface.ipv4.values[index].Address;
280a45c3852SGunnar Mills                });
281a45c3852SGunnar Mills      }
282a45c3852SGunnar Mills
2839a0094dcSGunnar Mills      $scope.refresh = function() {
284a3f75320SGunnar Mills        loadNetworkInfo();
2859a0094dcSGunnar Mills      };
286a3f75320SGunnar Mills
287a3f75320SGunnar Mills      function loadNetworkInfo() {
2882a489554SIftekharul Islam        APIUtils.getNetworkInfo().then(function(data) {
289659651e8SGunnar Mills          dataService.setNetworkInfo(data);
2902a489554SIftekharul Islam          $scope.network = data.formatted_data;
2912a489554SIftekharul Islam          $scope.hostname = data.hostname;
292*067a1cd1Sbeccabroek          $scope.defaultGateway = data.defaultgateway;
2932a489554SIftekharul Islam          if ($scope.network.interface_ids.length) {
294ffdef96dSRebecca Shaw            // Use the first network interface if the user hasn't chosen one
295a3f75320SGunnar Mills            if (!$scope.selectedInterface ||
296a3f75320SGunnar Mills                !$scope.network.interfaces[$scope.selectedInterface]) {
2972a489554SIftekharul Islam              $scope.selectedInterface = $scope.network.interface_ids[0];
298a3f75320SGunnar Mills            }
299d27bb135SAndrew Geissler            $scope.interface =
300d27bb135SAndrew Geissler                $scope.network.interfaces[$scope.selectedInterface];
301a45c3852SGunnar Mills            // Copy the interface so we know later if changes were made to the
302a45c3852SGunnar Mills            // page
303*067a1cd1Sbeccabroek            $scope.oldInterface = JSON.parse(JSON.stringify($scope.interface));
3042a489554SIftekharul Islam          }
3051a0e7d06Sbeccabroek          // Add id values and update flags to corresponding IPV4 objects
306971ac1aaSbeccabroek          for (var i = 0; i < $scope.interface.ipv4.values.length; i++) {
307971ac1aaSbeccabroek            $scope.interface.ipv4.values[i].id = $scope.interface.ipv4.ids[i];
308*067a1cd1Sbeccabroek            $scope.interface.ipv4.values[i].updateAddress = false;
309*067a1cd1Sbeccabroek            $scope.interface.ipv4.values[i].updateGateway = false;
310*067a1cd1Sbeccabroek            $scope.interface.ipv4.values[i].updatePrefix = false;
311971ac1aaSbeccabroek          }
3122a489554SIftekharul Islam        });
313cd789508SIftekharul Islam      }
314a3f75320SGunnar Mills    }
315ba5e3f34SAndrew Geissler  ]);
316cd789508SIftekharul Islam})(angular);
317