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