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