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          return $http({
550                   method: 'GET',
551                   url: DataService.getHost() +
552                       '/redfish/v1/AccountService/Roles',
553                   withCredentials: true
554                 })
555              .then(
556                  function(response) {
557                    var members = response.data['Members'];
558                    angular.forEach(members, function(member) {
559                      roles.push(member['@odata.id'].split('/').pop());
560                    });
561                    return roles;
562                  },
563                  function(error) {
564                    console.log(error);
565                  });
566        },
567        getAllUserAccounts: function() {
568          var deferred = $q.defer();
569          var promises = [];
570          var users = [];
571
572          $http({
573            method: 'GET',
574            url: DataService.getHost() + '/redfish/v1/AccountService/Accounts',
575            withCredentials: true
576          })
577              .then(
578                  function(response) {
579                    var members = response.data['Members'];
580                    angular.forEach(members, function(member) {
581                      promises.push(
582                          $http({
583                            method: 'GET',
584                            url: DataService.getHost() + member['@odata.id'],
585                            withCredentials: true
586                          }).then(function(res) {
587                            return res.data;
588                          }));
589                    });
590
591                    $q.all(promises).then(
592                        function(results) {
593                          deferred.resolve(results);
594                        },
595                        function(errors) {
596                          deferred.reject(errors);
597                        });
598                  },
599                  function(error) {
600                    console.log(error);
601                    deferred.reject(error);
602                  });
603          return deferred.promise;
604        },
605
606        getAllUserAccountProperties: function(callback) {
607          return $http({
608                   method: 'GET',
609                   url: DataService.getHost() + '/redfish/v1/AccountService',
610                   withCredentials: true
611                 })
612              .then(
613                  function(response) {
614                    return response.data;
615                  },
616                  function(error) {
617                    console.log(error);
618                  });
619        },
620
621        saveUserAccountProperties: function(lockoutduration, lockoutthreshold) {
622          var data = {};
623          if (lockoutduration != undefined) {
624            data['AccountLockoutDuration'] = lockoutduration;
625          }
626          if (lockoutthreshold != undefined) {
627            data['AccountLockoutThreshold'] = lockoutthreshold;
628          }
629
630          return $http({
631            method: 'PATCH',
632            url: DataService.getHost() + '/redfish/v1/AccountService',
633            withCredentials: true,
634            data: data
635          });
636        },
637
638        createUser: function(user, passwd, role, enabled) {
639          var data = {};
640          data['UserName'] = user;
641          data['Password'] = passwd;
642          data['RoleId'] = role;
643          data['Enabled'] = enabled;
644
645          return $http({
646            method: 'POST',
647            url: DataService.getHost() + '/redfish/v1/AccountService/Accounts',
648            withCredentials: true,
649            data: data
650          });
651        },
652        updateUser: function(user, newUser, passwd, role, enabled) {
653          var data = {};
654          if ((newUser !== undefined) && (newUser != null)) {
655            data['UserName'] = newUser;
656          }
657          if ((role !== undefined) && (role != null)) {
658            data['RoleId'] = role;
659          }
660          if ((enabled !== undefined) && (enabled != null)) {
661            data['Enabled'] = enabled;
662          }
663          if ((passwd !== undefined) && (passwd != null)) {
664            data['Password'] = passwd;
665          }
666          return $http({
667            method: 'PATCH',
668            url: DataService.getHost() +
669                '/redfish/v1/AccountService/Accounts/' + user,
670            withCredentials: true,
671            data: data
672          });
673        },
674        deleteUser: function(user) {
675          return $http({
676            method: 'DELETE',
677            url: DataService.getHost() +
678                '/redfish/v1/AccountService/Accounts/' + user,
679            withCredentials: true,
680          });
681        },
682        chassisPowerOff: function() {
683          var deferred = $q.defer();
684          $http({
685            method: 'PUT',
686            url: DataService.getHost() +
687                '/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition',
688            withCredentials: true,
689            data: JSON.stringify(
690                {'data': 'xyz.openbmc_project.State.Chassis.Transition.Off'})
691          })
692              .then(
693                  function(response) {
694                    var json = JSON.stringify(response.data);
695                    var content = JSON.parse(json);
696                    deferred.resolve(content.status);
697                  },
698                  function(error) {
699                    console.log(error);
700                    deferred.reject(error);
701                  });
702          return deferred.promise;
703        },
704        setLEDState: function(state) {
705          return $http({
706            method: 'PUT',
707            url: DataService.getHost() +
708                '/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted',
709            withCredentials: true,
710            data: JSON.stringify({'data': state})
711          })
712        },
713        bmcReboot: function(callback) {
714          $http({
715            method: 'PUT',
716            url: DataService.getHost() +
717                '/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition',
718            withCredentials: true,
719            data: JSON.stringify(
720                {'data': 'xyz.openbmc_project.State.BMC.Transition.Reboot'})
721          })
722              .then(
723                  function(response) {
724                    var json = JSON.stringify(response.data);
725                    var content = JSON.parse(json);
726                    if (callback) {
727                      return callback(content.status);
728                    }
729                  },
730                  function(error) {
731                    if (callback) {
732                      callback(error);
733                    } else {
734                      console.log(error);
735                    }
736                  });
737        },
738        getLastRebootTime: function() {
739          return $http({
740                   method: 'GET',
741                   url: DataService.getHost() +
742                       '/xyz/openbmc_project/state/bmc0/attr/LastRebootTime',
743                   withCredentials: true
744                 })
745              .then(function(response) {
746                return response.data;
747              });
748        },
749        hostPowerOn: function() {
750          var deferred = $q.defer();
751          $http({
752            method: 'PUT',
753            url: DataService.getHost() +
754                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
755            withCredentials: true,
756            data: JSON.stringify(
757                {'data': 'xyz.openbmc_project.State.Host.Transition.On'})
758          })
759              .then(
760                  function(response) {
761                    var json = JSON.stringify(response.data);
762                    var content = JSON.parse(json);
763                    deferred.resolve(content.status);
764                  },
765                  function(error) {
766                    console.log(error);
767                    deferred.reject(error);
768                  });
769          return deferred.promise;
770        },
771        hostPowerOff: function() {
772          var deferred = $q.defer();
773          $http({
774            method: 'PUT',
775            url: DataService.getHost() +
776                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
777            withCredentials: true,
778            data: JSON.stringify(
779                {'data': 'xyz.openbmc_project.State.Host.Transition.Off'})
780          })
781              .then(
782                  function(response) {
783                    var json = JSON.stringify(response.data);
784                    var content = JSON.parse(json);
785                    deferred.resolve(content.status);
786                  },
787                  function(error) {
788                    console.log(error);
789                    deferred.reject(error);
790                  });
791          return deferred.promise;
792        },
793        hostReboot: function() {
794          var deferred = $q.defer();
795          $http({
796            method: 'PUT',
797            url: DataService.getHost() +
798                '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition',
799            withCredentials: true,
800            data: JSON.stringify(
801                {'data': 'xyz.openbmc_project.State.Host.Transition.Reboot'})
802          })
803              .then(
804                  function(response) {
805                    var json = JSON.stringify(response.data);
806                    var content = JSON.parse(json);
807                    deferred.resolve(content.status);
808                  },
809                  function(error) {
810                    console.log(error);
811                    deferred.reject(error);
812                  });
813
814          return deferred.promise;
815        },
816        hostShutdown: function(callback) {
817          $http({
818            method: 'POST',
819            url: DataService.getHost() + '/xyz/openbmc_project/state/host0',
820            withCredentials: true,
821            data: JSON.stringify({'data': []})
822          })
823              .then(
824                  function(response) {
825                    var json = JSON.stringify(response.data);
826                    var content = JSON.parse(json);
827                    if (callback) {
828                      return callback(content);
829                    }
830                  },
831                  function(error) {
832                    if (callback) {
833                      callback(error);
834                    } else {
835                      console.log(error);
836                    }
837                  });
838        },
839        getLastPowerTime: function() {
840          return $http({
841                   method: 'GET',
842                   url: DataService.getHost() +
843                       '/xyz/openbmc_project/state/chassis0/attr/LastStateChangeTime',
844                   withCredentials: true
845                 })
846              .then(function(response) {
847                return response.data;
848              });
849        },
850        getLogs: function() {
851          var deferred = $q.defer();
852          $http({
853            method: 'GET',
854            url: DataService.getHost() +
855                '/xyz/openbmc_project/logging/enumerate',
856            withCredentials: true
857          })
858              .then(
859                  function(response) {
860                    var json = JSON.stringify(response.data);
861                    var content = JSON.parse(json);
862                    var dataClone = JSON.parse(JSON.stringify(content.data));
863                    var data = [];
864                    var severityCode = '';
865                    var priority = '';
866                    var health = '';
867                    var relatedItems = [];
868                    var eventID = 'None';
869                    var description = 'None';
870
871                    for (var key in content.data) {
872                      if (content.data.hasOwnProperty(key) &&
873                          content.data[key].hasOwnProperty('Id')) {
874                        var severityFlags = {
875                          low: false,
876                          medium: false,
877                          high: false
878                        };
879                        severityCode =
880                            content.data[key].Severity.split('.').pop();
881                        priority =
882                            Constants.SEVERITY_TO_PRIORITY_MAP[severityCode];
883                        severityFlags[priority.toLowerCase()] = true;
884                        relatedItems = [];
885                        content.data[key].associations.forEach(function(item) {
886                          relatedItems.push(item[2]);
887                        });
888
889                        if (content.data[key].hasOwnProperty(['EventID'])) {
890                          eventID = content.data[key].EventID;
891                        }
892
893                        if (content.data[key].hasOwnProperty(['Description'])) {
894                          description = content.data[key].Description;
895                        }
896
897                        data.push(Object.assign(
898                            {
899                              path: key,
900                              copied: false,
901                              priority: priority,
902                              severity_code: severityCode,
903                              severity_flags: severityFlags,
904                              additional_data:
905                                  content.data[key].AdditionalData.join('\n'),
906                              type: content.data[key].Message,
907                              selected: false,
908                              search_text:
909                                  ('#' + content.data[key].Id + ' ' +
910                                   severityCode + ' ' +
911                                   content.data[key].Message + ' ' +
912                                   content.data[key].Severity + ' ' +
913                                   content.data[key].AdditionalData.join(' '))
914                                      .toLowerCase(),
915                              meta: false,
916                              confirm: false,
917                              related_items: relatedItems,
918                              eventID: eventID,
919                              description: description,
920                              data: {key: key, value: content.data[key]}
921                            },
922                            content.data[key]));
923                      }
924                    }
925                    deferred.resolve({data: data, original: dataClone});
926                  },
927                  function(error) {
928                    console.log(error);
929                    deferred.reject(error);
930                  });
931
932          return deferred.promise;
933        },
934        getAllSensorStatus: function(callback) {
935          $http({
936            method: 'GET',
937            url: DataService.getHost() +
938                '/xyz/openbmc_project/sensors/enumerate',
939            withCredentials: true
940          })
941              .then(
942                  function(response) {
943                    var json = JSON.stringify(response.data);
944                    var content = JSON.parse(json);
945                    var dataClone = JSON.parse(JSON.stringify(content.data));
946                    var sensorData = [];
947                    var severity = {};
948                    var title = '';
949                    var tempKeyParts = [];
950                    var order = 0;
951                    var customOrder = 0;
952
953                    function getSensorStatus(reading) {
954                      var severityFlags = {
955                        critical: false,
956                        warning: false,
957                        normal: false
958                      },
959                          severityText = '', order = 0;
960
961                      if (reading.hasOwnProperty('CriticalLow') &&
962                          reading.Value < reading.CriticalLow) {
963                        severityFlags.critical = true;
964                        severityText = 'critical';
965                        order = 2;
966                      } else if (
967                          reading.hasOwnProperty('CriticalHigh') &&
968                          reading.Value > reading.CriticalHigh) {
969                        severityFlags.critical = true;
970                        severityText = 'critical';
971                        order = 2;
972                      } else if (
973                          reading.hasOwnProperty('CriticalLow') &&
974                          reading.hasOwnProperty('WarningLow') &&
975                          reading.Value >= reading.CriticalLow &&
976                          reading.Value <= reading.WarningLow) {
977                        severityFlags.warning = true;
978                        severityText = 'warning';
979                        order = 1;
980                      } else if (
981                          reading.hasOwnProperty('WarningHigh') &&
982                          reading.hasOwnProperty('CriticalHigh') &&
983                          reading.Value >= reading.WarningHigh &&
984                          reading.Value <= reading.CriticalHigh) {
985                        severityFlags.warning = true;
986                        severityText = 'warning';
987                        order = 1;
988                      } else {
989                        severityFlags.normal = true;
990                        severityText = 'normal';
991                      }
992                      return {
993                        flags: severityFlags,
994                        severityText: severityText,
995                        order: order
996                      };
997                    }
998
999                    for (var key in content.data) {
1000                      if (content.data.hasOwnProperty(key) &&
1001                          content.data[key].hasOwnProperty('Unit')) {
1002                        severity = getSensorStatus(content.data[key]);
1003
1004                        if (!content.data[key].hasOwnProperty('CriticalLow')) {
1005                          content.data[key].CriticalLow = '--';
1006                          content.data[key].CriticalHigh = '--';
1007                        }
1008
1009                        if (!content.data[key].hasOwnProperty('WarningLow')) {
1010                          content.data[key].WarningLow = '--';
1011                          content.data[key].WarningHigh = '--';
1012                        }
1013
1014                        tempKeyParts = key.split('/');
1015                        title = tempKeyParts.pop();
1016                        title = tempKeyParts.pop() + '_' + title;
1017                        title = title.split('_')
1018                                    .map(function(item) {
1019                                      return item.toLowerCase()
1020                                                 .charAt(0)
1021                                                 .toUpperCase() +
1022                                          item.slice(1);
1023                                    })
1024                                    .reduce(function(prev, el) {
1025                                      return prev + ' ' + el;
1026                                    });
1027
1028                        content.data[key].Value = getScaledValue(
1029                            content.data[key].Value, content.data[key].Scale);
1030                        content.data[key].CriticalLow = getScaledValue(
1031                            content.data[key].CriticalLow,
1032                            content.data[key].Scale);
1033                        content.data[key].CriticalHigh = getScaledValue(
1034                            content.data[key].CriticalHigh,
1035                            content.data[key].Scale);
1036                        content.data[key].WarningLow = getScaledValue(
1037                            content.data[key].WarningLow,
1038                            content.data[key].Scale);
1039                        content.data[key].WarningHigh = getScaledValue(
1040                            content.data[key].WarningHigh,
1041                            content.data[key].Scale);
1042                        if (Constants.SENSOR_SORT_ORDER.indexOf(
1043                                content.data[key].Unit) > -1) {
1044                          customOrder = Constants.SENSOR_SORT_ORDER.indexOf(
1045                              content.data[key].Unit);
1046                        } else {
1047                          customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT;
1048                        }
1049
1050                        sensorData.push(Object.assign(
1051                            {
1052                              path: key,
1053                              selected: false,
1054                              confirm: false,
1055                              copied: false,
1056                              title: title,
1057                              unit:
1058                                  Constants
1059                                      .SENSOR_UNIT_MAP[content.data[key].Unit],
1060                              severity_flags: severity.flags,
1061                              status: severity.severityText,
1062                              order: severity.order,
1063                              custom_order: customOrder,
1064                              search_text:
1065                                  (title + ' ' + content.data[key].Value + ' ' +
1066                                   Constants.SENSOR_UNIT_MAP[content.data[key]
1067                                                                 .Unit] +
1068                                   ' ' + severity.severityText + ' ' +
1069                                   content.data[key].CriticalLow + ' ' +
1070                                   content.data[key].CriticalHigh + ' ' +
1071                                   content.data[key].WarningLow + ' ' +
1072                                   content.data[key].WarningHigh + ' ')
1073                                      .toLowerCase(),
1074                              original_data:
1075                                  {key: key, value: content.data[key]}
1076                            },
1077                            content.data[key]));
1078                      }
1079                    }
1080
1081                    callback(sensorData, dataClone);
1082                  },
1083                  function(error) {
1084                    console.log(error);
1085                  });
1086        },
1087        getActivation: function(imageId) {
1088          return $http({
1089                   method: 'GET',
1090                   url: DataService.getHost() +
1091                       '/xyz/openbmc_project/software/' + imageId +
1092                       '/attr/Activation',
1093                   withCredentials: true
1094                 })
1095              .then(function(response) {
1096                return response.data;
1097              });
1098        },
1099        getFirmwares: function() {
1100          var deferred = $q.defer();
1101          $http({
1102            method: 'GET',
1103            url: DataService.getHost() +
1104                '/xyz/openbmc_project/software/enumerate',
1105            withCredentials: true
1106          })
1107              .then(
1108                  function(response) {
1109                    var json = JSON.stringify(response.data);
1110                    var content = JSON.parse(json);
1111                    var data = [];
1112                    var isExtended = false;
1113                    var bmcActiveVersion = '';
1114                    var hostActiveVersion = '';
1115                    var imageType = '';
1116                    var extendedVersions = [];
1117                    var functionalImages = [];
1118
1119                    function getFormatedExtendedVersions(extendedVersion) {
1120                      var versions = [];
1121                      extendedVersion = extendedVersion.split(',');
1122
1123                      extendedVersion.forEach(function(item) {
1124                        var parts = item.split('-');
1125                        var numberIndex = 0;
1126                        for (var i = 0; i < parts.length; i++) {
1127                          if (/[0-9]/.test(parts[i])) {
1128                            numberIndex = i;
1129                            break;
1130                          }
1131                        }
1132                        var titlePart = parts.splice(0, numberIndex);
1133                        titlePart = titlePart.join('');
1134                        titlePart = titlePart[0].toUpperCase() +
1135                            titlePart.substr(1, titlePart.length);
1136                        var versionPart = parts.join('-');
1137                        versions.push({title: titlePart, version: versionPart});
1138                      });
1139
1140                      return versions;
1141                    }
1142
1143                    // Get the list of functional images so we can compare
1144                    // later if an image is functional
1145                    if (content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]) {
1146                      functionalImages =
1147                          content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]
1148                              .endpoints;
1149                    }
1150                    for (var key in content.data) {
1151                      if (content.data.hasOwnProperty(key) &&
1152                          content.data[key].hasOwnProperty('Version')) {
1153                        var activationStatus = '';
1154
1155                        // If the image is "Functional" use that for the
1156                        // activation status, else use the value of
1157                        // "Activation"
1158                        // github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml
1159                        if (content.data[key].Activation) {
1160                          activationStatus =
1161                              content.data[key].Activation.split('.').pop();
1162                        }
1163
1164                        if (functionalImages.includes(key)) {
1165                          activationStatus = 'Functional';
1166                        }
1167
1168                        imageType = content.data[key].Purpose.split('.').pop();
1169                        isExtended = content.data[key].hasOwnProperty(
1170                                         'ExtendedVersion') &&
1171                            content.data[key].ExtendedVersion != '';
1172                        if (isExtended) {
1173                          extendedVersions = getFormatedExtendedVersions(
1174                              content.data[key].ExtendedVersion);
1175                        }
1176                        data.push(Object.assign(
1177                            {
1178                              path: key,
1179                              activationStatus: activationStatus,
1180                              imageId: key.split('/').pop(),
1181                              imageType: imageType,
1182                              isExtended: isExtended,
1183                              extended:
1184                                  {show: false, versions: extendedVersions},
1185                              data: {key: key, value: content.data[key]}
1186                            },
1187                            content.data[key]));
1188
1189                        if (activationStatus == 'Functional' &&
1190                            imageType == 'BMC') {
1191                          bmcActiveVersion = content.data[key].Version;
1192                        }
1193
1194                        if (activationStatus == 'Functional' &&
1195                            imageType == 'Host') {
1196                          hostActiveVersion = content.data[key].Version;
1197                        }
1198                      }
1199                    }
1200
1201                    deferred.resolve({
1202                      data: data,
1203                      bmcActiveVersion: bmcActiveVersion,
1204                      hostActiveVersion: hostActiveVersion
1205                    });
1206                  },
1207                  function(error) {
1208                    console.log(error);
1209                    deferred.reject(error);
1210                  });
1211
1212          return deferred.promise;
1213        },
1214        changePriority: function(imageId, priority) {
1215          return $http({
1216                   method: 'PUT',
1217                   url: DataService.getHost() +
1218                       '/xyz/openbmc_project/software/' + imageId +
1219                       '/attr/Priority',
1220                   withCredentials: true,
1221                   data: JSON.stringify({'data': priority})
1222                 })
1223              .then(function(response) {
1224                return response.data;
1225              });
1226        },
1227        deleteImage: function(imageId) {
1228          return $http({
1229                   method: 'POST',
1230                   url: DataService.getHost() +
1231                       '/xyz/openbmc_project/software/' + imageId +
1232                       '/action/Delete',
1233                   withCredentials: true,
1234                   data: JSON.stringify({'data': []})
1235                 })
1236              .then(function(response) {
1237                return response.data;
1238              });
1239        },
1240        activateImage: function(imageId) {
1241          return $http({
1242                   method: 'PUT',
1243                   url: DataService.getHost() +
1244                       '/xyz/openbmc_project/software/' + imageId +
1245                       '/attr/RequestedActivation',
1246                   withCredentials: true,
1247                   data: JSON.stringify(
1248                       {'data': Constants.FIRMWARE.ACTIVATE_FIRMWARE})
1249                 })
1250              .then(function(response) {
1251                return response.data;
1252              });
1253        },
1254        uploadImage: function(file) {
1255          return $http({
1256                   method: 'POST',
1257                   timeout: 5 * 60 * 1000,
1258                   url: DataService.getHost() + '/upload/image',
1259                   // Overwrite the default 'application/json' Content-Type
1260                   headers: {'Content-Type': 'application/octet-stream'},
1261                   withCredentials: true,
1262                   data: file
1263                 })
1264              .then(function(response) {
1265                return response.data;
1266              });
1267        },
1268        downloadImage: function(host, filename) {
1269          return $http({
1270                   method: 'POST',
1271                   url: DataService.getHost() +
1272                       '/xyz/openbmc_project/software/action/DownloadViaTFTP',
1273                   withCredentials: true,
1274                   data: JSON.stringify({'data': [filename, host]}),
1275                   responseType: 'arraybuffer'
1276                 })
1277              .then(function(response) {
1278                return response.data;
1279              });
1280        },
1281        getServerInfo: function() {
1282          // TODO: openbmc/openbmc#3117 Need a way via REST to get
1283          // interfaces so we can get the system object(s) by the looking
1284          // for the system interface.
1285          return $http({
1286                   method: 'GET',
1287                   url: DataService.getHost() +
1288                       '/xyz/openbmc_project/inventory/system',
1289                   withCredentials: true
1290                 })
1291              .then(function(response) {
1292                return response.data;
1293              });
1294        },
1295        getBMCTime: function() {
1296          return $http({
1297                   method: 'GET',
1298                   url: DataService.getHost() + '/xyz/openbmc_project/time/bmc',
1299                   withCredentials: true
1300                 })
1301              .then(function(response) {
1302                return response.data;
1303              });
1304        },
1305        getTime: function() {
1306          return $http({
1307                   method: 'GET',
1308                   url: DataService.getHost() +
1309                       '/xyz/openbmc_project/time/enumerate',
1310                   withCredentials: true
1311                 })
1312              .then(function(response) {
1313                return response.data;
1314              });
1315        },
1316        // Even though NTPServers is a network interface specific path
1317        // (e.g. /xyz/openbmc_project/network/eth0/attr/NTPServers) it acts
1318        // like a global setting. Just use eth0 for setting and getting the
1319        // NTP Servers until it is moved to a non-network interface specific
1320        // path like it is in Redfish. TODO: openbmc/phosphor-time-manager#4
1321        getNTPServers: function() {
1322          return $http({
1323                   method: 'GET',
1324                   url: DataService.getHost() +
1325                       '/xyz/openbmc_project/network/eth0/attr/NTPServers',
1326                   withCredentials: true
1327                 })
1328              .then(function(response) {
1329                return response.data;
1330              });
1331        },
1332        setNTPServers: function(ntpServers) {
1333          return $http({
1334                   method: 'PUT',
1335                   url: DataService.getHost() +
1336                       '/xyz/openbmc_project/network/eth0/attr/NTPServers',
1337                   withCredentials: true,
1338                   data: JSON.stringify({'data': ntpServers})
1339                 })
1340              .then(function(response) {
1341                return response.data;
1342              });
1343        },
1344        setTimeMode: function(timeMode) {
1345          return $http({
1346                   method: 'PUT',
1347                   url: DataService.getHost() +
1348                       '/xyz/openbmc_project/time/sync_method/attr/TimeSyncMethod',
1349                   withCredentials: true,
1350                   data: JSON.stringify({'data': timeMode})
1351                 })
1352              .then(function(response) {
1353                return response.data;
1354              });
1355        },
1356        setTimeOwner: function(timeOwner) {
1357          return $http({
1358                   method: 'PUT',
1359                   url: DataService.getHost() +
1360                       '/xyz/openbmc_project/time/owner/attr/TimeOwner',
1361                   withCredentials: true,
1362                   data: JSON.stringify({'data': timeOwner})
1363                 })
1364              .then(function(response) {
1365                return response.data;
1366              });
1367        },
1368        setBMCTime: function(time) {
1369          return $http({
1370                   method: 'PUT',
1371                   url: DataService.getHost() +
1372                       '/xyz/openbmc_project/time/bmc/attr/Elapsed',
1373                   withCredentials: true,
1374                   data: JSON.stringify({'data': time})
1375                 })
1376              .then(function(response) {
1377                return response.data;
1378              });
1379        },
1380        setHostTime: function(time) {
1381          return $http({
1382                   method: 'PUT',
1383                   url: DataService.getHost() +
1384                       '/xyz/openbmc_project/time/host/attr/Elapsed',
1385                   withCredentials: true,
1386                   data: JSON.stringify({'data': time})
1387                 })
1388              .then(function(response) {
1389                return response.data;
1390              });
1391        },
1392        getHardwares: function(callback) {
1393          $http({
1394            method: 'GET',
1395            url: DataService.getHost() +
1396                '/xyz/openbmc_project/inventory/enumerate',
1397            withCredentials: true
1398          }).then(function(response) {
1399            var json = JSON.stringify(response.data);
1400            var content = JSON.parse(json);
1401            var hardwareData = [];
1402            var keyIndexMap = {};
1403            var title = '';
1404            var depth = '';
1405            var data = [];
1406            var searchText = '';
1407            var componentIndex = -1;
1408            var parent = '';
1409
1410            function isSubComponent(key) {
1411              for (var i = 0; i < Constants.HARDWARE.parent_components.length;
1412                   i++) {
1413                if (key.split(Constants.HARDWARE.parent_components[i]).length ==
1414                    2)
1415                  return true;
1416              }
1417
1418              return false;
1419            }
1420
1421            function titlelize(title) {
1422              title = title.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, '');
1423              for (var i = 0; i < Constants.HARDWARE.uppercase_titles.length;
1424                   i++) {
1425                if (title.toLowerCase().indexOf(
1426                        (Constants.HARDWARE.uppercase_titles[i] + ' ')) > -1) {
1427                  return title.toUpperCase();
1428                }
1429              }
1430
1431              return title;
1432            }
1433
1434            function camelcaseToLabel(obj) {
1435              var transformed = [], label = '', value = '';
1436              for (var key in obj) {
1437                label = key.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, '');
1438                if (obj[key] !== '') {
1439                  value = obj[key];
1440                  if (value == 1 || value == 0) {
1441                    value = (value == 1) ? 'Yes' : 'No';
1442                  }
1443                  transformed.push({key: label, value: value});
1444                }
1445              }
1446
1447              return transformed;
1448            }
1449
1450            function determineParent(key) {
1451              var levels = key.split('/');
1452              levels.pop();
1453              return levels.join('/');
1454            }
1455
1456            function getSearchText(data) {
1457              var searchText = '';
1458              for (var i = 0; i < data.length; i++) {
1459                searchText += ' ' + data[i].key + ' ' + data[i].value;
1460              }
1461
1462              return searchText;
1463            }
1464
1465            for (var key in content.data) {
1466              if (content.data.hasOwnProperty(key) &&
1467                  key.indexOf(Constants.HARDWARE.component_key_filter) == 0) {
1468                data = camelcaseToLabel(content.data[key]);
1469                searchText = getSearchText(data);
1470                title = key.split('/').pop();
1471                // All and only associations have the property "endpoints".
1472                // We don't want to show associations on the hardware page.
1473                // Example: An association from the BMC inventory item to the
1474                // BMC firmware images.
1475                if (content.data[key].hasOwnProperty('endpoints')) {
1476                  continue;
1477                }
1478
1479                title = titlelize(title);
1480                // e.g. /xyz/openbmc_project/inventory/system and
1481                // /xyz/openbmc_project/inventory/system/chassis are depths of 5
1482                // and 6.
1483                depth = key.split('/').length;
1484                parent = determineParent(key);
1485
1486                if (!isSubComponent(key)) {
1487                  hardwareData.push(Object.assign(
1488                      {
1489                        path: key,
1490                        title: title,
1491                        depth: depth,
1492                        parent: parent,
1493                        selected: false,
1494                        expanded: false,
1495                        search_text: title.toLowerCase() + ' ' +
1496                            searchText.toLowerCase(),
1497                        sub_components: [],
1498                        original_data: {key: key, value: content.data[key]}
1499                      },
1500                      {items: data}));
1501
1502                  keyIndexMap[key] = hardwareData.length - 1;
1503                } else {
1504                  parent = determineParent(key)
1505                  componentIndex = keyIndexMap[parent];
1506                  data = content.data[key];
1507                  data.title = title;
1508                  hardwareData[componentIndex].sub_components.push(data);
1509                  hardwareData[componentIndex].search_text +=
1510                      ' ' + title.toLowerCase();
1511
1512                  // Sort the subcomponents alphanumeric so they are displayed
1513                  // on the inventory page in order (e.g. core 0, core 1, core
1514                  // 2, ... core 12, core 13)
1515                  hardwareData[componentIndex].sub_components.sort(function(
1516                      a, b) {
1517                    return a.title.localeCompare(
1518                        b.title, 'en', {numeric: true});
1519                  });
1520                }
1521              }
1522            }
1523            // First, order the components by depth and then place the child
1524            // components beneath their parent component alphanumerically. Can
1525            // be removed with completion of
1526            // https://github.com/openbmc/openbmc/issues/3401
1527            // TODO: Remove this once implemented in back end
1528            hardwareData.sort(function(a, b) {
1529              if (a.depth < b.depth) return -1;
1530              if (a.depth > b.depth) return 1;
1531              return b.title.localeCompare(a.title, 'en', {numeric: true});
1532            });
1533
1534            var orderedComponents = [];
1535
1536            for (var i = 0; i < hardwareData.length; i++) {
1537              if (!keyIndexMap[hardwareData[i].parent]) {
1538                orderedComponents.push(hardwareData[i]);
1539              } else {
1540                for (var j = 0; j < orderedComponents.length; j++) {
1541                  if (orderedComponents[j].path === hardwareData[i].parent) {
1542                    var child = hardwareData[i];
1543                    orderedComponents.splice(j + 1, 0, child);
1544                  }
1545                }
1546              }
1547            }
1548
1549            if (callback) {
1550              callback(orderedComponents, content.data);
1551            } else {
1552              return {data: orderedComponents, original_data: content.data};
1553            }
1554          });
1555        },
1556        deleteLogs: function(logs) {
1557          var defer = $q.defer();
1558          var promises = [];
1559
1560          function finished() {
1561            defer.resolve();
1562          }
1563
1564          logs.forEach(function(item) {
1565            promises.push($http({
1566              method: 'POST',
1567              url: DataService.getHost() +
1568                  '/xyz/openbmc_project/logging/entry/' + item.Id +
1569                  '/action/Delete',
1570              withCredentials: true,
1571              data: JSON.stringify({'data': []})
1572            }));
1573          });
1574
1575          $q.all(promises).then(finished);
1576
1577          return defer.promise;
1578        },
1579        resolveLogs: function(logs) {
1580          var promises = [];
1581
1582          logs.forEach(function(item) {
1583            promises.push($http({
1584              method: 'PUT',
1585              url: DataService.getHost() +
1586                  '/xyz/openbmc_project/logging/entry/' + item.Id +
1587                  '/attr/Resolved',
1588              withCredentials: true,
1589              data: JSON.stringify({'data': true})
1590            }));
1591          });
1592          return $q.all(promises);
1593        },
1594        getPowerConsumption: function() {
1595          return $http({
1596                   method: 'GET',
1597                   url: DataService.getHost() +
1598                       '/xyz/openbmc_project/sensors/power/total_power',
1599                   withCredentials: true
1600                 })
1601              .then(
1602                  function(response) {
1603                    var json = JSON.stringify(response.data);
1604                    var content = JSON.parse(json);
1605
1606                    return getScaledValue(
1607                               content.data.Value, content.data.Scale) +
1608                        ' ' +
1609                        Constants.POWER_CONSUMPTION_TEXT[content.data.Unit];
1610                  },
1611                  function(error) {
1612                    if ('Not Found' == error.statusText) {
1613                      return Constants.POWER_CONSUMPTION_TEXT.notavailable;
1614                    } else {
1615                      throw error;
1616                    }
1617                  });
1618        },
1619        getPowerCap: function() {
1620          return $http({
1621                   method: 'GET',
1622                   url: DataService.getHost() +
1623                       '/xyz/openbmc_project/control/host0/power_cap',
1624                   withCredentials: true
1625                 })
1626              .then(function(response) {
1627                return response.data;
1628              });
1629        },
1630        setPowerCapEnable: function(powerCapEnable) {
1631          return $http({
1632                   method: 'PUT',
1633                   url: DataService.getHost() +
1634                       '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCapEnable',
1635                   withCredentials: true,
1636                   data: JSON.stringify({'data': powerCapEnable})
1637                 })
1638              .then(function(response) {
1639                return response.data;
1640              });
1641        },
1642        setPowerCap: function(powerCap) {
1643          return $http({
1644                   method: 'PUT',
1645                   url: DataService.getHost() +
1646                       '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCap',
1647                   withCredentials: true,
1648                   data: JSON.stringify({'data': powerCap})
1649                 })
1650              .then(function(response) {
1651                return response.data;
1652              });
1653        },
1654        setHostname: function(hostname) {
1655          return $http({
1656                   method: 'PUT',
1657                   url: DataService.getHost() +
1658                       '/xyz/openbmc_project/network/config/attr/HostName',
1659                   withCredentials: true,
1660                   data: JSON.stringify({'data': hostname})
1661                 })
1662              .then(function(response) {
1663                return response.data;
1664              });
1665        },
1666      };
1667      return SERVICE;
1668    }
1669  ]);
1670})(window.angular);
1671