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