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