1/**
2 * API utilities service
3 *
4 * @module app/common/services/api-utils
5 * @exports APIUtils
6 * @name APIUtils
7 */
8
9window.angular && (function(angular) {
10  'use strict';
11  angular.module('app.common.services').factory('APIUtils', [
12    '$http', 'Constants', '$q', 'dataService', '$interval',
13    function($http, Constants, $q, DataService, $interval) {
14      var getScaledValue = function(value, scale) {
15        scale = scale + '';
16        scale = parseInt(scale, 10);
17        var power = Math.abs(parseInt(scale, 10));
18
19        if (scale > 0) {
20          value = value * Math.pow(10, power);
21        } else if (scale < 0) {
22          value = value / Math.pow(10, power);
23        }
24        return value;
25      };
26      var SERVICE = {
27        API_CREDENTIALS: Constants.API_CREDENTIALS,
28        API_RESPONSE: Constants.API_RESPONSE,
29        CHASSIS_POWER_STATE: Constants.CHASSIS_POWER_STATE,
30        HOST_STATE_TEXT: Constants.HOST_STATE,
31        HOST_STATE: Constants.HOST_STATE,
32        LED_STATE: Constants.LED_STATE,
33        LED_STATE_TEXT: Constants.LED_STATE_TEXT,
34        HOST_SESSION_STORAGE_KEY: Constants.API_CREDENTIALS.host_storage_key,
35        getChassisState: function() {
36          var deferred = $q.defer();
37          $http({
38            method: 'GET',
39            url: DataService.getHost() +
40                '/xyz/openbmc_project/state/chassis0/attr/CurrentPowerState',
41            withCredentials: true
42          })
43              .then(
44                  function(response) {
45                    var json = JSON.stringify(response.data);
46                    var content = JSON.parse(json);
47                    deferred.resolve(content.data);
48                  },
49                  function(error) {
50                    console.log(error);
51                    deferred.reject(error);
52                  });
53          return deferred.promise;
54        },
55        validIPV4IP: function(ip) {
56          // Checks for [0-255].[0-255].[0-255].[0-255]
57          return ip.match(
58              /\b(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\b/);
59        },
60        getRedfishSysName: function() {
61          return $http({
62                   method: 'GET',
63                   url: DataService.getHost() + '/redfish/v1/Systems',
64                   withCredentials: true
65                 })
66              .then(
67                  function(response) {
68                    var sysUrl = response.data['Members'][0]['@odata.id'];
69                    return sysUrl.split('/').pop(-1);
70                  },
71                  function(error) {
72                    console.log(JSON.stringify(error));
73                  });
74        },
75        getSystemLogs: function(recordType) {
76          var uri = '/redfish/v1/Systems/' + DataService.systemName +
77              '/LogServices/EventLog/Entries';
78          return $http({
79                   method: 'GET',
80                   url: DataService.getHost() + uri,
81                   withCredentials: true
82                 })
83              .then(
84                  function(response) {
85                    var logEntries = [];
86                    angular.forEach(response.data['Members'], function(log) {
87                      if (log.hasOwnProperty('EntryType')) {
88                        if (log['EntryType'] == recordType) {
89                          logEntries.push(log);
90                        }
91                      }
92                    });
93                    return logEntries;
94                  },
95                  function(error) {
96                    console.log(JSON.stringify(error));
97                  });
98        },
99        clearSystemLogs: function() {
100          var uri = '/redfish/v1/Systems/' + DataService.systemName +
101              '/LogServices/EventLog/Actions/LogService.ClearLog';
102          return $http({
103            method: 'POST',
104            url: DataService.getHost() + uri,
105            withCredentials: true
106          });
107        },
108        deleteObject: function(path) {
109          return $http({
110                   method: 'POST',
111                   url: DataService.getHost() + path + '/action/Delete',
112                   withCredentials: true,
113                   data: JSON.stringify({'data': []})
114                 })
115              .then(function(response) {
116                return response.data;
117              });
118        },
119        getHostState: function() {
120          var deferred = $q.defer();
121          $http({
122            method: 'GET',
123            url: DataService.getHost() +
124                '/xyz/openbmc_project/state/host0/attr/CurrentHostState',
125            withCredentials: true
126          })
127              .then(
128                  function(response) {
129                    var json = JSON.stringify(response.data);
130                    var content = JSON.parse(json);
131                    deferred.resolve(content.data);
132                  },
133                  function(error) {
134                    console.log(error);
135                    deferred.reject(error);
136                  });
137          return deferred.promise;
138        },
139        getSNMPManagers: function() {
140          return $http({
141                   method: 'GET',
142                   url: DataService.getHost() +
143                       '/xyz/openbmc_project/network/snmp/manager/enumerate',
144                   withCredentials: true
145                 })
146              .then(function(response) {
147                return response.data;
148              });
149        },
150        pollHostStatusTillOn: function() {
151          var deferred = $q.defer();
152          var hostOnTimeout = setTimeout(function() {
153            ws.close();
154            deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_ON_TIMEOUT));
155          }, Constants.TIMEOUT.HOST_ON);
156
157          var ws =
158              new WebSocket('wss://' + DataService.server_id + '/subscribe');
159          var data = JSON.stringify({
160            'paths': ['/xyz/openbmc_project/state/host0'],
161            'interfaces': ['xyz.openbmc_project.State.Host']
162          });
163          ws.onopen = function() {
164            ws.send(data);
165          };
166          ws.onmessage = function(evt) {
167            var content = JSON.parse(evt.data);
168            var hostState = content.properties.CurrentHostState;
169            if (hostState === Constants.HOST_STATE_TEXT.on_code) {
170              clearTimeout(hostOnTimeout);
171              ws.close();
172              deferred.resolve();
173            } else if (hostState === Constants.HOST_STATE_TEXT.error_code) {
174              clearTimeout(hostOnTimeout);
175              ws.close();
176              deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_QUIESCED));
177            }
178          };
179        },
180
181        pollHostStatusTilReboot: function() {
182          var deferred = $q.defer();
183          var onState = Constants.HOST_STATE_TEXT.on_code;
184          var offState = Constants.HOST_STATE_TEXT.on_code;
185          var hostTimeout;
186          var setHostTimeout = function(message, timeout) {
187            hostTimeout = setTimeout(function() {
188              ws.close();
189              deferred.reject(new Error(message));
190            }, timeout);
191          };
192          var ws =
193              new WebSocket('wss://' + DataService.server_id + '/subscribe');
194          var data = JSON.stringify({
195            'paths': ['/xyz/openbmc_project/state/host0'],
196            'interfaces': ['xyz.openbmc_project.State.Host']
197          });
198          ws.onopen = function() {
199            ws.send(data);
200          };
201          setHostTimeout(
202              Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT,
203              Constants.TIMEOUT.HOST_OFF);
204          var pollState = offState;
205          ws.onmessage = function(evt) {
206            var content = JSON.parse(evt.data);
207            var hostState = content.properties.CurrentHostState;
208            if (hostState === pollState) {
209              if (pollState === offState) {
210                clearTimeout(hostTimeout);
211                pollState = onState;
212                setHostTimeout(
213                    Constants.MESSAGES.POLL.HOST_ON_TIMEOUT,
214                    Constants.TIMEOUT.HOST_ON);
215              }
216              if (pollState === onState) {
217                clearTimeout(hostTimeout);
218                ws.close();
219                deferred.resolve();
220              }
221            } else if (hostState === Constants.HOST_STATE_TEXT.error_code) {
222              clearTimeout(hostTimeout);
223              ws.close();
224              deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_QUIESCED));
225            }
226          };
227        },
228
229        pollHostStatusTillOff: function() {
230          var deferred = $q.defer();
231          var hostOffTimeout = setTimeout(function() {
232            ws.close();
233            deferred.reject(
234                new Error(Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT));
235          }, Constants.TIMEOUT.HOST_OFF);
236
237          var ws =
238              new WebSocket('wss://' + DataService.server_id + '/subscribe');
239          var data = JSON.stringify({
240            'paths': ['/xyz/openbmc_project/state/host0'],
241            'interfaces': ['xyz.openbmc_project.State.Host']
242          });
243          ws.onopen = function() {
244            ws.send(data);
245          };
246          ws.onmessage = function(evt) {
247            var content = JSON.parse(evt.data);
248            var hostState = content.properties.CurrentHostState;
249            if (hostState === Constants.HOST_STATE_TEXT.off_code) {
250              clearTimeout(hostOffTimeout);
251              ws.close();
252              deferred.resolve();
253            }
254          };
255        },
256        addSNMPManager: function(address, port) {
257          return $http({
258                   method: 'POST',
259                   url: DataService.getHost() +
260                       '/xyz/openbmc_project/network/snmp/manager/action/Client',
261                   withCredentials: true,
262                   data: JSON.stringify({'data': [address, +port]})
263                 })
264              .then(function(response) {
265                return response.data;
266              });
267        },
268        setSNMPManagerPort: function(snmpManagerPath, port) {
269          return $http({
270                   method: 'PUT',
271                   url: DataService.getHost() + snmpManagerPath + '/attr/Port',
272                   withCredentials: true,
273                   data: JSON.stringify({'data': +port})
274                 })
275              .then(function(response) {
276                return response.data;
277              });
278        },
279        setSNMPManagerAddress: function(snmpManagerPath, address) {
280          return $http({
281                   method: 'PUT',
282                   url: DataService.getHost() + snmpManagerPath +
283                       '/attr/Address',
284                   withCredentials: true,
285                   data: JSON.stringify({'data': address})
286                 })
287              .then(function(response) {
288                return response.data;
289              });
290        },
291        getNetworkInfo: function() {
292          var deferred = $q.defer();
293          $http({
294            method: 'GET',
295            url: DataService.getHost() +
296                '/xyz/openbmc_project/network/enumerate',
297            withCredentials: true
298          })
299              .then(
300                  function(response) {
301                    var json = JSON.stringify(response.data);
302                    var content = JSON.parse(json);
303                    var hostname = '';
304                    var defaultgateway = '';
305                    var macAddress = '';
306
307                    function parseNetworkData(content) {
308                      var data = {
309                        interface_ids: [],
310                        interfaces: {},
311                        ip_addresses: {ipv4: [], ipv6: []},
312                      };
313                      var interfaceId = '', keyParts = [], interfaceHash = '',
314                          interfaceType = '';
315                      for (var key in content.data) {
316                        if (key.match(/network\/eth\d+(_\d+)?$/ig)) {
317                          interfaceId = key.split('/').pop();
318                          if (data.interface_ids.indexOf(interfaceId) == -1) {
319                            data.interface_ids.push(interfaceId);
320                            data.interfaces[interfaceId] = {
321                              interfaceIname: '',
322                              DomainName: '',
323                              MACAddress: '',
324                              Nameservers: [],
325                              DHCPEnabled: 0,
326                              ipv4: {ids: [], values: []},
327                              ipv6: {ids: [], values: []}
328                            };
329                            data.interfaces[interfaceId].MACAddress =
330                                content.data[key].MACAddress;
331                            data.interfaces[interfaceId].DomainName =
332                                content.data[key].DomainName.join(' ');
333                            data.interfaces[interfaceId].Nameservers =
334                                content.data[key].Nameservers;
335                            data.interfaces[interfaceId].DHCPEnabled =
336                                content.data[key].DHCPEnabled;
337                          }
338                        } else if (
339                            key.match(
340                                /network\/eth\d+(_\d+)?\/ipv[4|6]\/[a-z0-9]+$/ig)) {
341                          keyParts = key.split('/');
342                          interfaceHash = keyParts.pop();
343                          interfaceType = keyParts.pop();
344                          interfaceId = keyParts.pop();
345
346                          if (data.interfaces[interfaceId][interfaceType]
347                                  .ids.indexOf(interfaceHash) == -1) {
348                            data.interfaces[interfaceId][interfaceType]
349                                .ids.push(interfaceHash);
350                            data.interfaces[interfaceId][interfaceType]
351                                .values.push(content.data[key]);
352                            data.ip_addresses[interfaceType].push(
353                                content.data[key]['Address']);
354                          }
355                        }
356                      }
357                      return data;
358                    }
359
360                    if (content.data.hasOwnProperty(
361                            '/xyz/openbmc_project/network/config')) {
362                      if (content.data['/xyz/openbmc_project/network/config']
363                              .hasOwnProperty('HostName')) {
364                        hostname =
365                            content.data['/xyz/openbmc_project/network/config']
366                                .HostName;
367                      }
368                      if (content.data['/xyz/openbmc_project/network/config']
369                              .hasOwnProperty('DefaultGateway')) {
370                        defaultgateway =
371                            content.data['/xyz/openbmc_project/network/config']
372                                .DefaultGateway;
373                      }
374                    }
375
376                    if (content.data.hasOwnProperty(
377                            '/xyz/openbmc_project/network/eth0') &&
378                        content.data['/xyz/openbmc_project/network/eth0']
379                            .hasOwnProperty('MACAddress')) {
380                      macAddress =
381                          content.data['/xyz/openbmc_project/network/eth0']
382                              .MACAddress;
383                    }
384
385                    deferred.resolve({
386                      data: content.data,
387                      hostname: hostname,
388                      defaultgateway: defaultgateway,
389                      mac_address: macAddress,
390                      formatted_data: parseNetworkData(content)
391                    });
392                  },
393                  function(error) {
394                    console.log(error);
395                    deferred.reject(error);
396                  });
397          return deferred.promise;
398        },
399        setMACAddress: function(interface_name, mac_address) {
400          return $http({
401                   method: 'PUT',
402                   url: DataService.getHost() +
403                       '/xyz/openbmc_project/network/' + interface_name +
404                       '/attr/MACAddress',
405                   withCredentials: true,
406                   data: JSON.stringify({'data': mac_address})
407                 })
408              .then(function(response) {
409                return response.data;
410              });
411        },
412        setDefaultGateway: function(defaultGateway) {
413          return $http({
414                   method: 'PUT',
415                   url: DataService.getHost() +
416                       '/xyz/openbmc_project/network/config/attr/DefaultGateway',
417                   withCredentials: true,
418                   data: JSON.stringify({'data': defaultGateway})
419                 })
420              .then(function(response) {
421                return response.data;
422              });
423        },
424        setDHCPEnabled: function(interfaceName, dhcpEnabled) {
425          return $http({
426                   method: 'PUT',
427                   url: DataService.getHost() +
428                       '/xyz/openbmc_project/network/' + interfaceName +
429                       '/attr/DHCPEnabled',
430                   withCredentials: true,
431                   data: JSON.stringify({'data': dhcpEnabled})
432                 })
433              .then(function(response) {
434                return response.data;
435              });
436        },
437        setNameservers: function(interfaceName, dnsServers) {
438          return $http({
439                   method: 'PUT',
440                   url: DataService.getHost() +
441                       '/xyz/openbmc_project/network/' + interfaceName +
442                       '/attr/Nameservers',
443                   withCredentials: true,
444                   data: JSON.stringify({'data': dnsServers})
445                 })
446              .then(function(response) {
447                return response.data;
448              });
449        },
450        deleteIPV4: function(interfaceName, networkID) {
451          return $http({
452                   method: 'POST',
453                   url: DataService.getHost() +
454                       '/xyz/openbmc_project/network/' + interfaceName +
455                       '/ipv4/' + networkID + '/action/Delete',
456                   withCredentials: true,
457                   data: JSON.stringify({'data': []})
458                 })
459              .then(function(response) {
460                return response.data;
461              });
462        },
463        addIPV4: function(
464            interfaceName, ipAddress, netmaskPrefixLength, gateway) {
465          return $http({
466                   method: 'POST',
467                   url: DataService.getHost() +
468                       '/xyz/openbmc_project/network/' + interfaceName +
469                       '/action/IP',
470                   withCredentials: true,
471                   data: JSON.stringify({
472                     'data': [
473                       'xyz.openbmc_project.Network.IP.Protocol.IPv4',
474                       ipAddress, +netmaskPrefixLength, gateway
475                     ]
476                   })
477                 })
478              .then(function(response) {
479                return response.data;
480              });
481        },
482        getLEDState: function() {
483          var deferred = $q.defer();
484          $http({
485            method: 'GET',
486            url: DataService.getHost() +
487                '/xyz/openbmc_project/led/groups/enclosure_identify',
488            withCredentials: true
489          })
490              .then(
491                  function(response) {
492                    var json = JSON.stringify(response.data);
493                    var content = JSON.parse(json);
494                    deferred.resolve(content.data.Asserted);
495                  },
496                  function(error) {
497                    console.log(error);
498                    deferred.reject(error);
499                  });
500          return deferred.promise;
501        },
502        login: function(username, password, callback) {
503          $http({
504            method: 'POST',
505            url: DataService.getHost() + '/login',
506            withCredentials: true,
507            data: JSON.stringify({'data': [username, password]})
508          })
509              .then(
510                  function(response) {
511                    if (callback) {
512                      callback(response.data);
513                    }
514                  },
515                  function(error) {
516                    if (callback) {
517                      if (error && error.status && error.status == 'error') {
518                        callback(error);
519                      } else {
520                        callback(error, true);
521                      }
522                    }
523                    console.log(error);
524                  });
525        },
526        logout: function(callback) {
527          $http({
528            method: 'POST',
529            url: DataService.getHost() + '/logout',
530            withCredentials: true,
531            data: JSON.stringify({'data': []})
532          })
533              .then(
534                  function(response) {
535                    if (callback) {
536                      callback(response.data);
537                    }
538                  },
539                  function(error) {
540                    if (callback) {
541                      callback(null, error);
542                    }
543                    console.log(error);
544                  });
545        },
546        getAccountServiceRoles: function() {
547          var roles = [];
548
549          if (DataService.configJson.redfishSupportEnabled == true) {
550            return $http({
551                     method: 'GET',
552                     url: DataService.getHost() +
553                         '/redfish/v1/AccountService/Roles',
554                     withCredentials: true
555                   })
556                .then(
557                    function(response) {
558                      var members = response.data['Members'];
559                      angular.forEach(members, function(member) {
560                        roles.push(member['@odata.id'].split('/').pop());
561                      });
562                      return roles;
563                    },
564                    function(error) {
565                      console.log(error);
566                    });
567          } else {
568            return $http({
569                     method: 'GET',
570                     url: DataService.getHost() + '/xyz/openbmc_project/user',
571                     withCredentials: true
572                   })
573                .then(
574                    function(response) {
575                      var json = JSON.stringify(response.data);
576                      var content = JSON.parse(json);
577                      var privList = content.data['AllPrivileges'];
578
579                      function convertPrivToRoleId(priv) {
580                        if (priv == 'priv-admin') {
581                          return 'Administrator';
582                        } else if (priv == 'priv-user') {
583                          return 'User';
584                        } else if (priv == 'priv-operator') {
585                          return 'Operator';
586                        } else if (priv == 'priv-callback') {
587                          return 'Callback';
588                        }
589                        return '';
590                      }
591                      for (var i = 0; i < privList.length; i++) {
592                        roles.push(convertPrivToRoleId(privList[i]));
593                      }
594                      return roles;
595                    },
596                    function(error) {
597                      console.log(error);
598                    });
599          }
600        },
601        getAllUserAccounts: function() {
602          var deferred = $q.defer();
603          var promises = [];
604          var users = [];
605
606          if (DataService.configJson.redfishSupportEnabled == true) {
607            $http({
608              method: 'GET',
609              url:
610                  DataService.getHost() + '/redfish/v1/AccountService/Accounts',
611              withCredentials: true
612            })
613                .then(
614                    function(response) {
615                      var members = response.data['Members'];
616                      angular.forEach(members, function(member) {
617                        promises.push(
618                            $http({
619                              method: 'GET',
620                              url: DataService.getHost() + member['@odata.id'],
621                              withCredentials: true
622                            }).then(function(res) {
623                              return res.data;
624                            }));
625                      });
626
627                      $q.all(promises).then(
628                          function(results) {
629                            deferred.resolve(results);
630                          },
631                          function(errors) {
632                            deferred.reject(errors);
633                          });
634                    },
635                    function(error) {
636                      console.log(error);
637                      deferred.reject(error);
638                    });
639          } else {
640            $http({
641              method: 'GET',
642              url:
643                  DataService.getHost() + '/xyz/openbmc_project/user/enumerate',
644              withCredentials: true
645            })
646                .then(
647                    function(response) {
648                      var json = JSON.stringify(response.data);
649                      var content = JSON.parse(json);
650
651                      function convertPrivToRoleId(priv) {
652                        if (priv == 'priv-admin') {
653                          return 'Administrator';
654                        } else if (priv == 'priv-user') {
655                          return 'User';
656                        } else if (priv == 'priv-operator') {
657                          return 'Operator';
658                        } else if (priv == 'priv-callback') {
659                          return 'Callback';
660                        }
661                        return '';
662                      }
663
664                      for (var key in content.data) {
665                        var username = key.split('/').pop();
666                        if (content.data.hasOwnProperty(key) &&
667                            content.data[key].hasOwnProperty('UserPrivilege')) {
668                          var val = content.data[key];
669                          users.push(Object.assign({
670                            Id: username,
671                            UserName: username,
672                            Locked: val['UserLockedForFailedAttempt'],
673                            RoleId: convertPrivToRoleId(val['UserPrivilege']),
674                            Enabled: val['UserEnabled'],
675                            Password: null
676                          }));
677                        }
678                      }
679                      deferred.resolve(users);
680                    },
681                    function(error) {
682                      console.log(error);
683                      deferred.reject(error);
684                    });
685          }
686          return deferred.promise;
687        },
688
689        getAllUserAccountProperties: function(callback) {
690          return $http({
691                   method: 'GET',
692                   url: DataService.getHost() + '/redfish/v1/AccountService',
693                   withCredentials: true
694                 })
695              .then(
696                  function(response) {
697                    return response.data;
698                  },
699                  function(error) {
700                    console.log(error);
701                  });
702        },
703
704        saveUserAccountProperties: function(lockoutduration, lockoutthreshold) {
705          var data = {};
706          if (lockoutduration != undefined) {
707            data['AccountLockoutDuration'] = lockoutduration;
708          }
709          if (lockoutthreshold != undefined) {
710            data['AccountLockoutThreshold'] = lockoutthreshold;
711          }
712
713          return $http({
714            method: 'PATCH',
715            url: DataService.getHost() + '/redfish/v1/AccountService',
716            withCredentials: true,
717            data: data
718          });
719        },
720
721        createUser: function(user, passwd, role, enabled) {
722          if (DataService.configJson.redfishSupportEnabled == true) {
723            var data = {};
724            data['UserName'] = user;
725            data['Password'] = passwd;
726            data['RoleId'] = role;
727            data['Enabled'] = enabled;
728
729            return $http({
730              method: 'POST',
731              url:
732                  DataService.getHost() + '/redfish/v1/AccountService/Accounts',
733              withCredentials: true,
734              data: data
735            });
736          } else {
737            function convertRoleIdToPriv(roleId) {
738              if (roleId == 'Administrator') {
739                return 'priv-admin';
740              } else if (roleId == 'User') {
741                return 'priv-user';
742              } else if (roleId == 'Operator') {
743                return 'priv-operator';
744              } else if (roleId == 'Callback') {
745                return 'priv-callback';
746              }
747              return '';
748            }
749            function setUserPassword(user, passwd) {
750              return $http({
751                       method: 'POST',
752                       url: DataService.getHost() +
753                           '/xyz/openbmc_project/user/' + user +
754                           '/action/SetPassword',
755                       withCredentials: true,
756                       data: JSON.stringify({'data': [passwd]}),
757                       responseType: 'arraybuffer'
758                     })
759                  .then(function(response) {
760                    return response.data;
761                  });
762            }
763            var priv = convertRoleIdToPriv(role);
764            return $http({
765                     method: 'POST',
766                     url: DataService.getHost() +
767                         '/xyz/openbmc_project/user/action/CreateUser',
768                     withCredentials: true,
769                     data: JSON.stringify({
770                       'data':
771                           [user, ['web', 'redfish', 'ssh'], priv, enabled]
772                     }),
773                     responseType: 'arraybuffer'
774                   })
775                .then(function(response) {
776                  return setUserPassword(user, passwd);
777                });
778          }
779        },
780        updateUser: function(user, newUser, passwd, role, enabled) {
781          if (DataService.configJson.redfishSupportEnabled == true) {
782            var data = {};
783            if ((newUser !== undefined) && (newUser != null)) {
784              data['UserName'] = newUser;
785            }
786            if ((role !== undefined) && (role != null)) {
787              data['RoleId'] = role;
788            }
789            if ((enabled !== undefined) && (enabled != null)) {
790              data['Enabled'] = enabled;
791            }
792            if ((passwd !== undefined) && (passwd != null)) {
793              data['Password'] = passwd;
794            }
795            return $http({
796              method: 'PATCH',
797              url: DataService.getHost() +
798                  '/redfish/v1/AccountService/Accounts/' + user,
799              withCredentials: true,
800              data: data
801            });
802          } else {
803            var deferred = $q.defer();
804            var promises = [];
805            function convertRoleIdToPriv(roleId) {
806              if (roleId == 'Administrator') {
807                return 'priv-admin';
808              } else if (roleId == 'User') {
809                return 'priv-user';
810              } else if (roleId == 'Operator') {
811                return 'priv-operator';
812              } else if (roleId == 'Callback') {
813                return 'priv-callback';
814              }
815              return '';
816            }
817            function setUserProperty(user, propKey, propVal) {
818              return $http({
819                       method: 'PUT',
820                       url: DataService.getHost() +
821                           '/xyz/openbmc_project/user/' + user + '/attr/' +
822                           propKey,
823                       withCredentials: true,
824                       data: JSON.stringify({'data': propVal})
825                     })
826                  .then(function(response) {
827                    return response.data;
828                  });
829            }
830            function setUserPassword(user, passwd) {
831              return $http({
832                       method: 'POST',
833                       url: DataService.getHost() +
834                           '/xyz/openbmc_project/user/' + user +
835                           '/action/SetPassword',
836                       withCredentials: true,
837                       data: JSON.stringify({'data': [passwd]}),
838                       responseType: 'arraybuffer'
839                     })
840                  .then(function(response) {
841                    return response.data;
842                  });
843            }
844            function renameUser(user, newUser) {
845              return $http({
846                       method: 'POST',
847                       url: DataService.getHost() +
848                           '/xyz/openbmc_project/user/action/RenameUser',
849                       withCredentials: true,
850                       data: JSON.stringify({'data': [user, newUser]})
851                     })
852                  .then(function(response) {
853                    return response.data;
854                  });
855            }
856            if ((role !== undefined) && (role != null)) {
857              var priv = convertRoleIdToPriv(role);
858              promises.push(setUserProperty(user, 'UserPrivilege', priv));
859            }
860            if ((enabled !== undefined) && (enabled != null)) {
861              promises.push(setUserProperty(user, 'UserEnabled', enabled));
862            }
863            if ((passwd !== undefined) && (passwd != null)) {
864              promises.push(setUserPassword(user, passwd));
865            }
866            if ((newUser !== undefined) && (newUser != null)) {
867              promises.push(renameUser(user, newUser));
868            }
869            $q.all(promises).then(
870                function(results) {
871                  deferred.resolve(results);
872                },
873                function(errors) {
874                  deferred.reject(errors);
875                });
876            return deferred.promise;
877          }
878        },
879        deleteUser: function(user) {
880          if (DataService.configJson.redfishSupportEnabled == true) {
881            return $http({
882              method: 'DELETE',
883              url: DataService.getHost() +
884                  '/redfish/v1/AccountService/Accounts/' + user,
885              withCredentials: true,
886            });
887          } else {
888            return $http({
889                     method: 'POST',
890                     url: DataService.getHost() + '/xyz/openbmc_project/user/' +
891                         user + '/action/Delete',
892                     withCredentials: true,
893                     data: JSON.stringify({'data': []})
894                   })
895                .then(function(response) {
896                  return response.data;
897                });
898          }
899        },
900        chassisPowerOff: function() {
901          var deferred = $q.defer();
902          $http({
903            method: 'PUT',
904            url: DataService.getHost() +
905                '/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition',
906            withCredentials: true,
907            data: JSON.stringify(
908                {'data': 'xyz.openbmc_project.State.Chassis.Transition.Off'})
909          })
910              .then(
911                  function(response) {
912                    var json = JSON.stringify(response.data);
913                    var content = JSON.parse(json);
914                    deferred.resolve(content.status);
915                  },
916                  function(error) {
917                    console.log(error);
918                    deferred.reject(error);
919                  });
920          return deferred.promise;
921        },
922        setLEDState: function(state) {
923          return $http({
924            method: 'PUT',
925            url: DataService.getHost() +
926                '/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted',
927            withCredentials: true,
928            data: JSON.stringify({'data': state})
929          })
930        },
931        bmcReboot: function(callback) {
932          $http({
933            method: 'PUT',
934            url: DataService.getHost() +
935                '/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition',
936            withCredentials: true,
937            data: JSON.stringify(
938                {'data': 'xyz.openbmc_project.State.BMC.Transition.Reboot'})
939          })
940              .then(
941                  function(response) {
942                    var json = JSON.stringify(response.data);
943                    var content = JSON.parse(json);
944                    if (callback) {
945                      return callback(content.status);
946                    }
947                  },
948                  function(error) {
949                    if (callback) {
950                      callback(error);
951                    } else {
952                      console.log(error);
953                    }
954                  });
955        },
956        getLastRebootTime: function() {
957          return $http({
958                   method: 'GET',
959                   url: DataService.getHost() +
960                       '/xyz/openbmc_project/state/bmc0/attr/LastRebootTime',
961                   withCredentials: true
962                 })
963              .then(function(response) {
964                return response.data;
965              });
966        },
967        hostPowerOn: function() {
968          var deferred = $q.defer();
969          $http({
970            method: 'PUT',
971            url: DataService.getHost() +
972                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
973            withCredentials: true,
974            data: JSON.stringify(
975                {'data': 'xyz.openbmc_project.State.Host.Transition.On'})
976          })
977              .then(
978                  function(response) {
979                    var json = JSON.stringify(response.data);
980                    var content = JSON.parse(json);
981                    deferred.resolve(content.status);
982                  },
983                  function(error) {
984                    console.log(error);
985                    deferred.reject(error);
986                  });
987          return deferred.promise;
988        },
989        hostPowerOff: function() {
990          var deferred = $q.defer();
991          $http({
992            method: 'PUT',
993            url: DataService.getHost() +
994                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
995            withCredentials: true,
996            data: JSON.stringify(
997                {'data': 'xyz.openbmc_project.State.Host.Transition.Off'})
998          })
999              .then(
1000                  function(response) {
1001                    var json = JSON.stringify(response.data);
1002                    var content = JSON.parse(json);
1003                    deferred.resolve(content.status);
1004                  },
1005                  function(error) {
1006                    console.log(error);
1007                    deferred.reject(error);
1008                  });
1009          return deferred.promise;
1010        },
1011        hostReboot: function() {
1012          var deferred = $q.defer();
1013          $http({
1014            method: 'PUT',
1015            url: DataService.getHost() +
1016                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
1017            withCredentials: true,
1018            data: JSON.stringify(
1019                {'data': 'xyz.openbmc_project.State.Host.Transition.Reboot'})
1020          })
1021              .then(
1022                  function(response) {
1023                    var json = JSON.stringify(response.data);
1024                    var content = JSON.parse(json);
1025                    deferred.resolve(content.status);
1026                  },
1027                  function(error) {
1028                    console.log(error);
1029                    deferred.reject(error);
1030                  });
1031
1032          return deferred.promise;
1033        },
1034        hostShutdown: function(callback) {
1035          $http({
1036            method: 'POST',
1037            url: DataService.getHost() + '/xyz/openbmc_project/state/host0',
1038            withCredentials: true,
1039            data: JSON.stringify({'data': []})
1040          })
1041              .then(
1042                  function(response) {
1043                    var json = JSON.stringify(response.data);
1044                    var content = JSON.parse(json);
1045                    if (callback) {
1046                      return callback(content);
1047                    }
1048                  },
1049                  function(error) {
1050                    if (callback) {
1051                      callback(error);
1052                    } else {
1053                      console.log(error);
1054                    }
1055                  });
1056        },
1057        getLastPowerTime: function() {
1058          return $http({
1059                   method: 'GET',
1060                   url: DataService.getHost() +
1061                       '/xyz/openbmc_project/state/chassis0/attr/LastStateChangeTime',
1062                   withCredentials: true
1063                 })
1064              .then(function(response) {
1065                return response.data;
1066              });
1067        },
1068        getLogs: function() {
1069          var deferred = $q.defer();
1070          $http({
1071            method: 'GET',
1072            url: DataService.getHost() +
1073                '/xyz/openbmc_project/logging/enumerate',
1074            withCredentials: true
1075          })
1076              .then(
1077                  function(response) {
1078                    var json = JSON.stringify(response.data);
1079                    var content = JSON.parse(json);
1080                    var dataClone = JSON.parse(JSON.stringify(content.data));
1081                    var data = [];
1082                    var severityCode = '';
1083                    var priority = '';
1084                    var health = '';
1085                    var relatedItems = [];
1086                    var eventID = 'None';
1087                    var description = 'None';
1088
1089                    for (var key in content.data) {
1090                      if (content.data.hasOwnProperty(key) &&
1091                          content.data[key].hasOwnProperty('Id')) {
1092                        var severityFlags = {
1093                          low: false,
1094                          medium: false,
1095                          high: false
1096                        };
1097                        severityCode =
1098                            content.data[key].Severity.split('.').pop();
1099                        priority =
1100                            Constants.SEVERITY_TO_PRIORITY_MAP[severityCode];
1101                        severityFlags[priority.toLowerCase()] = true;
1102                        relatedItems = [];
1103                        content.data[key].associations.forEach(function(item) {
1104                          relatedItems.push(item[2]);
1105                        });
1106
1107                        if (content.data[key].hasOwnProperty(['EventID'])) {
1108                          eventID = content.data[key].EventID;
1109                        }
1110
1111                        if (content.data[key].hasOwnProperty(['Description'])) {
1112                          description = content.data[key].Description;
1113                        }
1114
1115                        data.push(Object.assign(
1116                            {
1117                              path: key,
1118                              copied: false,
1119                              priority: priority,
1120                              severity_code: severityCode,
1121                              severity_flags: severityFlags,
1122                              additional_data:
1123                                  content.data[key].AdditionalData.join('\n'),
1124                              type: content.data[key].Message,
1125                              selected: false,
1126                              search_text:
1127                                  ('#' + content.data[key].Id + ' ' +
1128                                   severityCode + ' ' +
1129                                   content.data[key].Message + ' ' +
1130                                   content.data[key].Severity + ' ' +
1131                                   content.data[key].AdditionalData.join(' '))
1132                                      .toLowerCase(),
1133                              meta: false,
1134                              confirm: false,
1135                              related_items: relatedItems,
1136                              eventID: eventID,
1137                              description: description,
1138                              data: {key: key, value: content.data[key]}
1139                            },
1140                            content.data[key]));
1141                      }
1142                    }
1143                    deferred.resolve({data: data, original: dataClone});
1144                  },
1145                  function(error) {
1146                    console.log(error);
1147                    deferred.reject(error);
1148                  });
1149
1150          return deferred.promise;
1151        },
1152        getAllSensorStatus: function(callback) {
1153          $http({
1154            method: 'GET',
1155            url: DataService.getHost() +
1156                '/xyz/openbmc_project/sensors/enumerate',
1157            withCredentials: true
1158          })
1159              .then(
1160                  function(response) {
1161                    var json = JSON.stringify(response.data);
1162                    var content = JSON.parse(json);
1163                    var dataClone = JSON.parse(JSON.stringify(content.data));
1164                    var sensorData = [];
1165                    var severity = {};
1166                    var title = '';
1167                    var tempKeyParts = [];
1168                    var order = 0;
1169                    var customOrder = 0;
1170
1171                    function getSensorStatus(reading) {
1172                      var severityFlags = {
1173                        critical: false,
1174                        warning: false,
1175                        normal: false
1176                      },
1177                          severityText = '', order = 0;
1178
1179                      if (reading.hasOwnProperty('CriticalLow') &&
1180                          reading.Value < reading.CriticalLow) {
1181                        severityFlags.critical = true;
1182                        severityText = 'critical';
1183                        order = 2;
1184                      } else if (
1185                          reading.hasOwnProperty('CriticalHigh') &&
1186                          reading.Value > reading.CriticalHigh) {
1187                        severityFlags.critical = true;
1188                        severityText = 'critical';
1189                        order = 2;
1190                      } else if (
1191                          reading.hasOwnProperty('CriticalLow') &&
1192                          reading.hasOwnProperty('WarningLow') &&
1193                          reading.Value >= reading.CriticalLow &&
1194                          reading.Value <= reading.WarningLow) {
1195                        severityFlags.warning = true;
1196                        severityText = 'warning';
1197                        order = 1;
1198                      } else if (
1199                          reading.hasOwnProperty('WarningHigh') &&
1200                          reading.hasOwnProperty('CriticalHigh') &&
1201                          reading.Value >= reading.WarningHigh &&
1202                          reading.Value <= reading.CriticalHigh) {
1203                        severityFlags.warning = true;
1204                        severityText = 'warning';
1205                        order = 1;
1206                      } else {
1207                        severityFlags.normal = true;
1208                        severityText = 'normal';
1209                      }
1210                      return {
1211                        flags: severityFlags,
1212                        severityText: severityText,
1213                        order: order
1214                      };
1215                    }
1216
1217                    for (var key in content.data) {
1218                      if (content.data.hasOwnProperty(key) &&
1219                          content.data[key].hasOwnProperty('Unit')) {
1220                        severity = getSensorStatus(content.data[key]);
1221
1222                        if (!content.data[key].hasOwnProperty('CriticalLow')) {
1223                          content.data[key].CriticalLow = '--';
1224                          content.data[key].CriticalHigh = '--';
1225                        }
1226
1227                        if (!content.data[key].hasOwnProperty('WarningLow')) {
1228                          content.data[key].WarningLow = '--';
1229                          content.data[key].WarningHigh = '--';
1230                        }
1231
1232                        tempKeyParts = key.split('/');
1233                        title = tempKeyParts.pop();
1234                        title = tempKeyParts.pop() + '_' + title;
1235                        title = title.split('_')
1236                                    .map(function(item) {
1237                                      return item.toLowerCase()
1238                                                 .charAt(0)
1239                                                 .toUpperCase() +
1240                                          item.slice(1);
1241                                    })
1242                                    .reduce(function(prev, el) {
1243                                      return prev + ' ' + el;
1244                                    });
1245
1246                        content.data[key].Value = getScaledValue(
1247                            content.data[key].Value, content.data[key].Scale);
1248                        content.data[key].CriticalLow = getScaledValue(
1249                            content.data[key].CriticalLow,
1250                            content.data[key].Scale);
1251                        content.data[key].CriticalHigh = getScaledValue(
1252                            content.data[key].CriticalHigh,
1253                            content.data[key].Scale);
1254                        content.data[key].WarningLow = getScaledValue(
1255                            content.data[key].WarningLow,
1256                            content.data[key].Scale);
1257                        content.data[key].WarningHigh = getScaledValue(
1258                            content.data[key].WarningHigh,
1259                            content.data[key].Scale);
1260                        if (Constants.SENSOR_SORT_ORDER.indexOf(
1261                                content.data[key].Unit) > -1) {
1262                          customOrder = Constants.SENSOR_SORT_ORDER.indexOf(
1263                              content.data[key].Unit);
1264                        } else {
1265                          customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT;
1266                        }
1267
1268                        sensorData.push(Object.assign(
1269                            {
1270                              path: key,
1271                              selected: false,
1272                              confirm: false,
1273                              copied: false,
1274                              title: title,
1275                              unit:
1276                                  Constants
1277                                      .SENSOR_UNIT_MAP[content.data[key].Unit],
1278                              severity_flags: severity.flags,
1279                              status: severity.severityText,
1280                              order: severity.order,
1281                              custom_order: customOrder,
1282                              search_text:
1283                                  (title + ' ' + content.data[key].Value + ' ' +
1284                                   Constants.SENSOR_UNIT_MAP[content.data[key]
1285                                                                 .Unit] +
1286                                   ' ' + severity.severityText + ' ' +
1287                                   content.data[key].CriticalLow + ' ' +
1288                                   content.data[key].CriticalHigh + ' ' +
1289                                   content.data[key].WarningLow + ' ' +
1290                                   content.data[key].WarningHigh + ' ')
1291                                      .toLowerCase(),
1292                              original_data:
1293                                  {key: key, value: content.data[key]}
1294                            },
1295                            content.data[key]));
1296                      }
1297                    }
1298
1299                    callback(sensorData, dataClone);
1300                  },
1301                  function(error) {
1302                    console.log(error);
1303                  });
1304        },
1305        getActivation: function(imageId) {
1306          return $http({
1307                   method: 'GET',
1308                   url: DataService.getHost() +
1309                       '/xyz/openbmc_project/software/' + imageId +
1310                       '/attr/Activation',
1311                   withCredentials: true
1312                 })
1313              .then(function(response) {
1314                return response.data;
1315              });
1316        },
1317        getFirmwares: function() {
1318          var deferred = $q.defer();
1319          $http({
1320            method: 'GET',
1321            url: DataService.getHost() +
1322                '/xyz/openbmc_project/software/enumerate',
1323            withCredentials: true
1324          })
1325              .then(
1326                  function(response) {
1327                    var json = JSON.stringify(response.data);
1328                    var content = JSON.parse(json);
1329                    var data = [];
1330                    var isExtended = false;
1331                    var bmcActiveVersion = '';
1332                    var hostActiveVersion = '';
1333                    var imageType = '';
1334                    var extendedVersions = [];
1335                    var functionalImages = [];
1336
1337                    function getFormatedExtendedVersions(extendedVersion) {
1338                      var versions = [];
1339                      extendedVersion = extendedVersion.split(',');
1340
1341                      extendedVersion.forEach(function(item) {
1342                        var parts = item.split('-');
1343                        var numberIndex = 0;
1344                        for (var i = 0; i < parts.length; i++) {
1345                          if (/[0-9]/.test(parts[i])) {
1346                            numberIndex = i;
1347                            break;
1348                          }
1349                        }
1350                        var titlePart = parts.splice(0, numberIndex);
1351                        titlePart = titlePart.join('');
1352                        titlePart = titlePart[0].toUpperCase() +
1353                            titlePart.substr(1, titlePart.length);
1354                        var versionPart = parts.join('-');
1355                        versions.push({title: titlePart, version: versionPart});
1356                      });
1357
1358                      return versions;
1359                    }
1360
1361                    // Get the list of functional images so we can compare
1362                    // later if an image is functional
1363                    if (content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]) {
1364                      functionalImages =
1365                          content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]
1366                              .endpoints;
1367                    }
1368                    for (var key in content.data) {
1369                      if (content.data.hasOwnProperty(key) &&
1370                          content.data[key].hasOwnProperty('Version')) {
1371                        var activationStatus = '';
1372
1373                        // If the image is "Functional" use that for the
1374                        // activation status, else use the value of
1375                        // "Activation"
1376                        // github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml
1377                        if (content.data[key].Activation) {
1378                          activationStatus =
1379                              content.data[key].Activation.split('.').pop();
1380                        }
1381
1382                        if (functionalImages.includes(key)) {
1383                          activationStatus = 'Functional';
1384                        }
1385
1386                        imageType = content.data[key].Purpose.split('.').pop();
1387                        isExtended = content.data[key].hasOwnProperty(
1388                                         'ExtendedVersion') &&
1389                            content.data[key].ExtendedVersion != '';
1390                        if (isExtended) {
1391                          extendedVersions = getFormatedExtendedVersions(
1392                              content.data[key].ExtendedVersion);
1393                        }
1394                        data.push(Object.assign(
1395                            {
1396                              path: key,
1397                              activationStatus: activationStatus,
1398                              imageId: key.split('/').pop(),
1399                              imageType: imageType,
1400                              isExtended: isExtended,
1401                              extended:
1402                                  {show: false, versions: extendedVersions},
1403                              data: {key: key, value: content.data[key]}
1404                            },
1405                            content.data[key]));
1406
1407                        if (activationStatus == 'Functional' &&
1408                            imageType == 'BMC') {
1409                          bmcActiveVersion = content.data[key].Version;
1410                        }
1411
1412                        if (activationStatus == 'Functional' &&
1413                            imageType == 'Host') {
1414                          hostActiveVersion = content.data[key].Version;
1415                        }
1416                      }
1417                    }
1418
1419                    deferred.resolve({
1420                      data: data,
1421                      bmcActiveVersion: bmcActiveVersion,
1422                      hostActiveVersion: hostActiveVersion
1423                    });
1424                  },
1425                  function(error) {
1426                    console.log(error);
1427                    deferred.reject(error);
1428                  });
1429
1430          return deferred.promise;
1431        },
1432        changePriority: function(imageId, priority) {
1433          return $http({
1434                   method: 'PUT',
1435                   url: DataService.getHost() +
1436                       '/xyz/openbmc_project/software/' + imageId +
1437                       '/attr/Priority',
1438                   withCredentials: true,
1439                   data: JSON.stringify({'data': priority})
1440                 })
1441              .then(function(response) {
1442                return response.data;
1443              });
1444        },
1445        deleteImage: function(imageId) {
1446          return $http({
1447                   method: 'POST',
1448                   url: DataService.getHost() +
1449                       '/xyz/openbmc_project/software/' + imageId +
1450                       '/action/Delete',
1451                   withCredentials: true,
1452                   data: JSON.stringify({'data': []})
1453                 })
1454              .then(function(response) {
1455                return response.data;
1456              });
1457        },
1458        activateImage: function(imageId) {
1459          return $http({
1460                   method: 'PUT',
1461                   url: DataService.getHost() +
1462                       '/xyz/openbmc_project/software/' + imageId +
1463                       '/attr/RequestedActivation',
1464                   withCredentials: true,
1465                   data: JSON.stringify(
1466                       {'data': Constants.FIRMWARE.ACTIVATE_FIRMWARE})
1467                 })
1468              .then(function(response) {
1469                return response.data;
1470              });
1471        },
1472        uploadImage: function(file) {
1473          return $http({
1474                   method: 'POST',
1475                   timeout: 5 * 60 * 1000,
1476                   url: DataService.getHost() + '/upload/image',
1477                   // Overwrite the default 'application/json' Content-Type
1478                   headers: {'Content-Type': 'application/octet-stream'},
1479                   withCredentials: true,
1480                   data: file
1481                 })
1482              .then(function(response) {
1483                return response.data;
1484              });
1485        },
1486        downloadImage: function(host, filename) {
1487          return $http({
1488                   method: 'POST',
1489                   url: DataService.getHost() +
1490                       '/xyz/openbmc_project/software/action/DownloadViaTFTP',
1491                   withCredentials: true,
1492                   data: JSON.stringify({'data': [filename, host]}),
1493                   responseType: 'arraybuffer'
1494                 })
1495              .then(function(response) {
1496                return response.data;
1497              });
1498        },
1499        getServerInfo: function() {
1500          // TODO: openbmc/openbmc#3117 Need a way via REST to get
1501          // interfaces so we can get the system object(s) by the looking
1502          // for the system interface.
1503          return $http({
1504                   method: 'GET',
1505                   url: DataService.getHost() +
1506                       '/xyz/openbmc_project/inventory/system',
1507                   withCredentials: true
1508                 })
1509              .then(function(response) {
1510                return response.data;
1511              });
1512        },
1513        getBMCTime: function() {
1514          return $http({
1515                   method: 'GET',
1516                   url: DataService.getHost() + '/xyz/openbmc_project/time/bmc',
1517                   withCredentials: true
1518                 })
1519              .then(function(response) {
1520                return response.data;
1521              });
1522        },
1523        getTime: function() {
1524          return $http({
1525                   method: 'GET',
1526                   url: DataService.getHost() +
1527                       '/xyz/openbmc_project/time/enumerate',
1528                   withCredentials: true
1529                 })
1530              .then(function(response) {
1531                return response.data;
1532              });
1533        },
1534        // Even though NTPServers is a network interface specific path
1535        // (e.g. /xyz/openbmc_project/network/eth0/attr/NTPServers) it acts
1536        // like a global setting. Just use eth0 for setting and getting the
1537        // NTP Servers until it is moved to a non-network interface specific
1538        // path like it is in Redfish. TODO: openbmc/phosphor-time-manager#4
1539        getNTPServers: function() {
1540          return $http({
1541                   method: 'GET',
1542                   url: DataService.getHost() +
1543                       '/xyz/openbmc_project/network/eth0/attr/NTPServers',
1544                   withCredentials: true
1545                 })
1546              .then(function(response) {
1547                return response.data;
1548              });
1549        },
1550        setNTPServers: function(ntpServers) {
1551          return $http({
1552                   method: 'PUT',
1553                   url: DataService.getHost() +
1554                       '/xyz/openbmc_project/network/eth0/attr/NTPServers',
1555                   withCredentials: true,
1556                   data: JSON.stringify({'data': ntpServers})
1557                 })
1558              .then(function(response) {
1559                return response.data;
1560              });
1561        },
1562        setTimeMode: function(timeMode) {
1563          return $http({
1564                   method: 'PUT',
1565                   url: DataService.getHost() +
1566                       '/xyz/openbmc_project/time/sync_method/attr/TimeSyncMethod',
1567                   withCredentials: true,
1568                   data: JSON.stringify({'data': timeMode})
1569                 })
1570              .then(function(response) {
1571                return response.data;
1572              });
1573        },
1574        setTimeOwner: function(timeOwner) {
1575          return $http({
1576                   method: 'PUT',
1577                   url: DataService.getHost() +
1578                       '/xyz/openbmc_project/time/owner/attr/TimeOwner',
1579                   withCredentials: true,
1580                   data: JSON.stringify({'data': timeOwner})
1581                 })
1582              .then(function(response) {
1583                return response.data;
1584              });
1585        },
1586        setBMCTime: function(time) {
1587          return $http({
1588                   method: 'PUT',
1589                   url: DataService.getHost() +
1590                       '/xyz/openbmc_project/time/bmc/attr/Elapsed',
1591                   withCredentials: true,
1592                   data: JSON.stringify({'data': time})
1593                 })
1594              .then(function(response) {
1595                return response.data;
1596              });
1597        },
1598        setHostTime: function(time) {
1599          return $http({
1600                   method: 'PUT',
1601                   url: DataService.getHost() +
1602                       '/xyz/openbmc_project/time/host/attr/Elapsed',
1603                   withCredentials: true,
1604                   data: JSON.stringify({'data': time})
1605                 })
1606              .then(function(response) {
1607                return response.data;
1608              });
1609        },
1610        getHardwares: function(callback) {
1611          $http({
1612            method: 'GET',
1613            url: DataService.getHost() +
1614                '/xyz/openbmc_project/inventory/enumerate',
1615            withCredentials: true
1616          }).then(function(response) {
1617            var json = JSON.stringify(response.data);
1618            var content = JSON.parse(json);
1619            var hardwareData = [];
1620            var keyIndexMap = {};
1621            var title = '';
1622            var depth = '';
1623            var data = [];
1624            var searchText = '';
1625            var componentIndex = -1;
1626            var parent = '';
1627
1628            function isSubComponent(key) {
1629              for (var i = 0; i < Constants.HARDWARE.parent_components.length;
1630                   i++) {
1631                if (key.split(Constants.HARDWARE.parent_components[i]).length ==
1632                    2)
1633                  return true;
1634              }
1635
1636              return false;
1637            }
1638
1639            function titlelize(title) {
1640              title = title.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, '');
1641              for (var i = 0; i < Constants.HARDWARE.uppercase_titles.length;
1642                   i++) {
1643                if (title.toLowerCase().indexOf(
1644                        (Constants.HARDWARE.uppercase_titles[i] + ' ')) > -1) {
1645                  return title.toUpperCase();
1646                }
1647              }
1648
1649              return title;
1650            }
1651
1652            function camelcaseToLabel(obj) {
1653              var transformed = [], label = '', value = '';
1654              for (var key in obj) {
1655                label = key.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, '');
1656                if (obj[key] !== '') {
1657                  value = obj[key];
1658                  if (value == 1 || value == 0) {
1659                    value = (value == 1) ? 'Yes' : 'No';
1660                  }
1661                  transformed.push({key: label, value: value});
1662                }
1663              }
1664
1665              return transformed;
1666            }
1667
1668            function determineParent(key) {
1669              var levels = key.split('/');
1670              levels.pop();
1671              return levels.join('/');
1672            }
1673
1674            function getSearchText(data) {
1675              var searchText = '';
1676              for (var i = 0; i < data.length; i++) {
1677                searchText += ' ' + data[i].key + ' ' + data[i].value;
1678              }
1679
1680              return searchText;
1681            }
1682
1683            for (var key in content.data) {
1684              if (content.data.hasOwnProperty(key) &&
1685                  key.indexOf(Constants.HARDWARE.component_key_filter) == 0) {
1686                data = camelcaseToLabel(content.data[key]);
1687                searchText = getSearchText(data);
1688                title = key.split('/').pop();
1689                // All and only associations have the property "endpoints".
1690                // We don't want to show associations on the hardware page.
1691                // Example: An association from the BMC inventory item to the
1692                // BMC firmware images.
1693                if (content.data[key].hasOwnProperty('endpoints')) {
1694                  continue;
1695                }
1696
1697                title = titlelize(title);
1698                // e.g. /xyz/openbmc_project/inventory/system and
1699                // /xyz/openbmc_project/inventory/system/chassis are depths of 5
1700                // and 6.
1701                depth = key.split('/').length;
1702                parent = determineParent(key);
1703
1704                if (!isSubComponent(key)) {
1705                  hardwareData.push(Object.assign(
1706                      {
1707                        path: key,
1708                        title: title,
1709                        depth: depth,
1710                        parent: parent,
1711                        selected: false,
1712                        expanded: false,
1713                        search_text: title.toLowerCase() + ' ' +
1714                            searchText.toLowerCase(),
1715                        sub_components: [],
1716                        original_data: {key: key, value: content.data[key]}
1717                      },
1718                      {items: data}));
1719
1720                  keyIndexMap[key] = hardwareData.length - 1;
1721                } else {
1722                  parent = determineParent(key)
1723                  componentIndex = keyIndexMap[parent];
1724                  data = content.data[key];
1725                  data.title = title;
1726                  hardwareData[componentIndex].sub_components.push(data);
1727                  hardwareData[componentIndex].search_text +=
1728                      ' ' + title.toLowerCase();
1729
1730                  // Sort the subcomponents alphanumeric so they are displayed
1731                  // on the inventory page in order (e.g. core 0, core 1, core
1732                  // 2, ... core 12, core 13)
1733                  hardwareData[componentIndex].sub_components.sort(function(
1734                      a, b) {
1735                    return a.title.localeCompare(
1736                        b.title, 'en', {numeric: true});
1737                  });
1738                }
1739              }
1740            }
1741            // First, order the components by depth and then place the child
1742            // components beneath their parent component alphanumerically. Can
1743            // be removed with completion of
1744            // https://github.com/openbmc/openbmc/issues/3401
1745            // TODO: Remove this once implemented in back end
1746            hardwareData.sort(function(a, b) {
1747              if (a.depth < b.depth) return -1;
1748              if (a.depth > b.depth) return 1;
1749              return b.title.localeCompare(a.title, 'en', {numeric: true});
1750            });
1751
1752            var orderedComponents = [];
1753
1754            for (var i = 0; i < hardwareData.length; i++) {
1755              if (!keyIndexMap[hardwareData[i].parent]) {
1756                orderedComponents.push(hardwareData[i]);
1757              } else {
1758                for (var j = 0; j < orderedComponents.length; j++) {
1759                  if (orderedComponents[j].path === hardwareData[i].parent) {
1760                    var child = hardwareData[i];
1761                    orderedComponents.splice(j + 1, 0, child);
1762                  }
1763                }
1764              }
1765            }
1766
1767            if (callback) {
1768              callback(orderedComponents, content.data);
1769            } else {
1770              return {data: orderedComponents, original_data: content.data};
1771            }
1772          });
1773        },
1774        deleteLogs: function(logs) {
1775          var defer = $q.defer();
1776          var promises = [];
1777
1778          function finished() {
1779            defer.resolve();
1780          }
1781
1782          logs.forEach(function(item) {
1783            promises.push($http({
1784              method: 'POST',
1785              url: DataService.getHost() +
1786                  '/xyz/openbmc_project/logging/entry/' + item.Id +
1787                  '/action/Delete',
1788              withCredentials: true,
1789              data: JSON.stringify({'data': []})
1790            }));
1791          });
1792
1793          $q.all(promises).then(finished);
1794
1795          return defer.promise;
1796        },
1797        resolveLogs: function(logs) {
1798          var promises = [];
1799
1800          logs.forEach(function(item) {
1801            promises.push($http({
1802              method: 'PUT',
1803              url: DataService.getHost() +
1804                  '/xyz/openbmc_project/logging/entry/' + item.Id +
1805                  '/attr/Resolved',
1806              withCredentials: true,
1807              data: JSON.stringify({'data': true})
1808            }));
1809          });
1810          return $q.all(promises);
1811        },
1812        getPowerConsumption: function() {
1813          return $http({
1814                   method: 'GET',
1815                   url: DataService.getHost() +
1816                       '/xyz/openbmc_project/sensors/power/total_power',
1817                   withCredentials: true
1818                 })
1819              .then(
1820                  function(response) {
1821                    var json = JSON.stringify(response.data);
1822                    var content = JSON.parse(json);
1823
1824                    return getScaledValue(
1825                               content.data.Value, content.data.Scale) +
1826                        ' ' +
1827                        Constants.POWER_CONSUMPTION_TEXT[content.data.Unit];
1828                  },
1829                  function(error) {
1830                    if ('Not Found' == error.statusText) {
1831                      return Constants.POWER_CONSUMPTION_TEXT.notavailable;
1832                    } else {
1833                      throw error;
1834                    }
1835                  });
1836        },
1837        getPowerCap: function() {
1838          return $http({
1839                   method: 'GET',
1840                   url: DataService.getHost() +
1841                       '/xyz/openbmc_project/control/host0/power_cap',
1842                   withCredentials: true
1843                 })
1844              .then(function(response) {
1845                return response.data;
1846              });
1847        },
1848        setPowerCapEnable: function(powerCapEnable) {
1849          return $http({
1850                   method: 'PUT',
1851                   url: DataService.getHost() +
1852                       '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCapEnable',
1853                   withCredentials: true,
1854                   data: JSON.stringify({'data': powerCapEnable})
1855                 })
1856              .then(function(response) {
1857                return response.data;
1858              });
1859        },
1860        setPowerCap: function(powerCap) {
1861          return $http({
1862                   method: 'PUT',
1863                   url: DataService.getHost() +
1864                       '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCap',
1865                   withCredentials: true,
1866                   data: JSON.stringify({'data': powerCap})
1867                 })
1868              .then(function(response) {
1869                return response.data;
1870              });
1871        },
1872        setHostname: function(hostname) {
1873          return $http({
1874                   method: 'PUT',
1875                   url: DataService.getHost() +
1876                       '/xyz/openbmc_project/network/config/attr/HostName',
1877                   withCredentials: true,
1878                   data: JSON.stringify({'data': hostname})
1879                 })
1880              .then(function(response) {
1881                return response.data;
1882              });
1883        },
1884      };
1885      return SERVICE;
1886    }
1887  ]);
1888})(window.angular);
1889