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
12        .module('app.common.services')
13        .factory('APIUtils', ['$http', 'Constants', '$q', 'dataService',function($http, Constants, $q, DataService){
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() + "/xyz/openbmc_project/state/chassis0/attr/CurrentPowerState",
40                  headers: {
41                      'Accept': 'application/json',
42                      'Content-Type': 'application/json'
43                  },
44                  withCredentials: true
45                }).then(function(response){
46                      var json = JSON.stringify(response.data);
47                      var content = JSON.parse(json);
48                      deferred.resolve(content.data);
49                }, function(error){
50                  console.log(error);
51                  deferred.reject(error);
52                });
53                return deferred.promise;
54              },
55              getHostState: function(){
56                var deferred = $q.defer();
57                $http({
58                  method: 'GET',
59                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/CurrentHostState",
60                  headers: {
61                      'Accept': 'application/json',
62                      'Content-Type': 'application/json'
63                  },
64                  withCredentials: true
65                }).then(function(response){
66                      var json = JSON.stringify(response.data);
67                      var content = JSON.parse(json);
68                      deferred.resolve(content.data);
69                }, function(error){
70                  console.log(error);
71                  deferred.reject(error);
72                });
73                return deferred.promise;
74              },
75              getNetworkInfo: function(){
76                var deferred = $q.defer();
77                $http({
78                  method: 'GET',
79                  url: DataService.getHost() + "/xyz/openbmc_project/network/enumerate",
80                  headers: {
81                      'Accept': 'application/json',
82                      'Content-Type': 'application/json'
83                  },
84                  withCredentials: true
85                }).then(function(response){
86                    var json = JSON.stringify(response.data);
87                    var content = JSON.parse(json);
88                    var hostname = "";
89                    var macAddress = "";
90
91                    function parseNetworkData(content){
92                      var data = {
93                        interface_ids: [],
94                        interfaces: {
95                        }
96                      };
97                      var interfaceId = '', keyParts = [], interfaceHash = '', interfaceType = '';
98                      for(var key in content.data){
99                        if(key.match(/network\/eth\d+$/ig)){
100                          interfaceId = key.split("/").pop();
101                          if(data.interface_ids.indexOf(interfaceId) == -1){
102                            data.interface_ids.push(interfaceId);
103                            data.interfaces[interfaceId] = {
104                              interfaceIname: '',
105                              DomainName:'',
106                              MACAddress:'',
107                              Nameservers: [],
108                              DHCPEnabled: 0,
109                              ipv4:
110                                {
111                                 ids: [],
112                                 values: []
113                                },
114                              ipv6:
115                                {
116                                 ids: [],
117                                 values: []
118                                }
119                            };
120                            data.interfaces[interfaceId].MACAddress = content.data[key].MACAddress;
121                            data.interfaces[interfaceId].DomainName = content.data[key].DomainName.join(" ");
122                            data.interfaces[interfaceId].Nameservers = content.data[key].Nameservers;
123                            data.interfaces[interfaceId].DHCPEnabled = content.data[key].DHCPEnabled;
124                          }
125                        }else if(key.match(/network\/eth\d+\/ipv[4|6]\/[a-z0-9]+$/ig)){
126                          keyParts = key.split("/");
127                          interfaceHash = keyParts.pop();
128                          interfaceType = keyParts.pop();
129                          interfaceId = keyParts.pop();
130
131                          if(data.interfaces[interfaceId][interfaceType].ids.indexOf(interfaceHash) == -1){
132                            data.interfaces[interfaceId][interfaceType].ids.push(interfaceHash);
133                            data.interfaces[interfaceId][interfaceType].values.push(content.data[key]);
134                          }
135                        }
136                      }
137                      return data;
138                    }
139
140                    if(content.data.hasOwnProperty('/xyz/openbmc_project/network/config') &&
141                      content.data['/xyz/openbmc_project/network/config'].hasOwnProperty('HostName')
142                      ){
143                      hostname = content.data['/xyz/openbmc_project/network/config'].HostName;
144                    }
145
146                    if(content.data.hasOwnProperty('/xyz/openbmc_project/network/eth0') &&
147                      content.data['/xyz/openbmc_project/network/eth0'].hasOwnProperty('MACAddress')
148                      ){
149                      macAddress = content.data['/xyz/openbmc_project/network/eth0'].MACAddress;
150                    }
151
152                    deferred.resolve({
153                      data: content.data,
154                      hostname: hostname,
155                      mac_address: macAddress,
156                      formatted_data: parseNetworkData(content)
157                    });
158                }, function(error){
159                  console.log(error);
160                  deferred.reject(error);
161                });
162                return deferred.promise;
163              },
164              getLEDState: function(){
165                var deferred = $q.defer();
166                $http({
167                  method: 'GET',
168                  url: DataService.getHost() + "/xyz/openbmc_project/led/groups/enclosure_identify",
169                  headers: {
170                      'Accept': 'application/json',
171                      'Content-Type': 'application/json'
172                  },
173                  withCredentials: true
174                }).then(function(response){
175                    var json = JSON.stringify(response.data);
176                    var content = JSON.parse(json);
177                    deferred.resolve(content.data.Asserted);
178                }, function(error){
179                  console.log(error);
180                  deferred.reject(error);
181                });
182                return deferred.promise;
183              },
184              login: function(username, password, callback){
185                $http({
186                  method: 'POST',
187                  url: DataService.getHost() + "/login",
188                  headers: {
189                      'Accept': 'application/json',
190                      'Content-Type': 'application/json'
191                  },
192                  withCredentials: true,
193                  data: JSON.stringify({"data": [username, password]})
194                }).then(function(response){
195                  if(callback){
196                      callback(response.data);
197                  }
198                }, function(error){
199                  if(callback){
200                      if(error && error.status && error.status == 'error'){
201                        callback(error);
202                      }else{
203                        callback(error, true);
204                      }
205                  }
206                  console.log(error);
207                });
208              },
209              testPassword: function(username, password){
210                // Calls /login without the current session to verify the given password is correct
211                // ignore the interceptor logout on a bad password
212                DataService.ignoreHttpError = true;
213                return $http({
214                  method: 'POST',
215                  url: DataService.getHost() + "/login",
216                  headers: {
217                    'Accept': 'application/json',
218                    'Content-Type': 'application/json'
219                  },
220                  withCredentials: false,
221                  data: JSON.stringify({"data": [username, password]})
222                }).then(function(response){
223                  return response.data;
224                });
225              },
226              logout: function(callback){
227                $http({
228                  method: 'POST',
229                  url: DataService.getHost() + "/logout",
230                  headers: {
231                      'Accept': 'application/json',
232                      'Content-Type': 'application/json'
233                  },
234                  withCredentials: true,
235                  data: JSON.stringify({"data": []})
236                }).then(function(response){
237                  if(callback){
238                      callback(response.data);
239                  }
240                }, function(error){
241                  if(callback){
242                      callback(null, error);
243                  }
244                  console.log(error);
245                });
246              },
247              changePassword: function(user, newPassword){
248                var deferred = $q.defer();
249                $http({
250                  method: 'POST',
251                  url: DataService.getHost() + "/xyz/openbmc_project/user/" + user + "/action/SetPassword",
252                  headers: {
253                    'Accept': 'application/json',
254                    'Content-Type': 'application/json'
255                  },
256                  withCredentials: true,
257                  data: JSON.stringify({"data": [newPassword]}),
258                  responseType: 'arraybuffer'
259                }).then(function(response, status, headers){
260                  deferred.resolve({
261                    data: response,
262                    status: status,
263                    headers: headers
264                  });
265                }, function(error){
266                  console.log(error);
267                  deferred.reject(error);
268                });
269                return deferred.promise;
270              },
271              chassisPowerOn: function(callback){
272                $http({
273                  method: 'POST',
274                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0",
275                  headers: {
276                      'Accept': 'application/json',
277                      'Content-Type': 'application/json'
278                  },
279                  withCredentials: true,
280                  data: JSON.stringify({"data": []})
281                }).then(function(response){
282                      var json = JSON.stringify(response.data);
283                      var content = JSON.parse(json);
284                      if(callback){
285                          return callback(content.data.CurrentPowerState);
286                      }
287                }, function(error){
288                  if(callback){
289                      callback(error);
290                  }else{
291                      console.log(error);
292                  }
293                });
294              },
295              chassisPowerOff: function(){
296                var deferred = $q.defer();
297                $http({
298                  method: 'PUT',
299                  url: DataService.getHost() + "/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition",
300                  headers: {
301                      'Accept': 'application/json',
302                      'Content-Type': 'application/json'
303                  },
304                  withCredentials: true,
305                  data: JSON.stringify({"data": "xyz.openbmc_project.State.Chassis.Transition.Off"})
306                }).then(function(response){
307                      var json = JSON.stringify(response.data);
308                      var content = JSON.parse(json);
309                      deferred.resolve(content.status);
310                }, function(error){
311                  console.log(error);
312                  deferred.reject(error);
313                });
314                return deferred.promise;
315              },
316              setLEDState: function(state, callback){
317                $http({
318                  method: 'PUT',
319                  url: DataService.getHost() + "/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted",
320                  headers: {
321                      'Accept': 'application/json',
322                      'Content-Type': 'application/json'
323                  },
324                  withCredentials: true,
325                  data: JSON.stringify({"data": state})
326                }).then(function(response){
327                      var json = JSON.stringify(response.data);
328                      var content = JSON.parse(json);
329                      if(callback){
330                          return callback(content.status);
331                      }
332                }, function(error){
333                  if(callback){
334                      callback(error);
335                  }else{
336                      console.log(error);
337                  }
338                });
339              },
340              bmcReboot: function(callback){
341                $http({
342                  method: 'PUT',
343                  url: DataService.getHost() + "/xyz/openbmc_project/state/bmc0/attr/RequestedBmcTransition",
344                  headers: {
345                      'Accept': 'application/json',
346                      'Content-Type': 'application/json'
347                  },
348                  withCredentials: true,
349                  data: JSON.stringify({"data": "xyz.openbmc_project.State.BMC.Transition.Reboot"})
350                }).then(function(response){
351                      var json = JSON.stringify(response.data);
352                      var content = JSON.parse(json);
353                      if(callback){
354                          return callback(content.status);
355                      }
356                }, function(error){
357                  if(callback){
358                      callback(error);
359                  }else{
360                      console.log(error);
361                  }
362                });
363              },
364              hostPowerOn: function(){
365                var deferred = $q.defer();
366                $http({
367                  method: 'PUT',
368                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition",
369                  headers: {
370                      'Accept': 'application/json',
371                      'Content-Type': 'application/json'
372                  },
373                  withCredentials: true,
374                  data: JSON.stringify({"data": "xyz.openbmc_project.State.Host.Transition.On"})
375                }).then(function(response){
376                      var json = JSON.stringify(response.data);
377                      var content = JSON.parse(json);
378                      deferred.resolve(content.status);
379                }, function(error){
380                  console.log(error);
381                  deferred.reject(error);
382                });
383                return deferred.promise;
384              },
385              hostPowerOff: function(){
386                var deferred = $q.defer();
387                $http({
388                  method: 'PUT',
389                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition",
390                  headers: {
391                      'Accept': 'application/json',
392                      'Content-Type': 'application/json'
393                  },
394                  withCredentials: true,
395                  data: JSON.stringify({"data": "xyz.openbmc_project.State.Host.Transition.Off"})
396                }).then(function(response){
397                      var json = JSON.stringify(response.data);
398                      var content = JSON.parse(json);
399                      deferred.resolve(content.status);
400                }, function(error){
401                  console.log(error);
402                  deferred.reject(error);
403                });
404                return deferred.promise;
405              },
406              hostReboot: function(){
407                var deferred = $q.defer();
408                $http({
409                  method: 'PUT',
410                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition",
411                  headers: {
412                      'Accept': 'application/json',
413                      'Content-Type': 'application/json'
414                  },
415                  withCredentials: true,
416                  data: JSON.stringify({"data": "xyz.openbmc_project.State.Host.Transition.Reboot"})
417                }).then(function(response){
418                      var json = JSON.stringify(response.data);
419                      var content = JSON.parse(json);
420                      deferred.resolve(content.status);
421                }, function(error){
422                  console.log(error);
423                  deferred.reject(error);
424                });
425
426                return deferred.promise;
427              },
428              hostShutdown: function(callback){
429                $http({
430                  method: 'POST',
431                  url: DataService.getHost() + "/xyz/openbmc_project/state/host0",
432                  headers: {
433                      'Accept': 'application/json',
434                      'Content-Type': 'application/json'
435                  },
436                  withCredentials: true,
437                  data: JSON.stringify({"data": []})
438                }).then(function(response){
439                      var json = JSON.stringify(response.data);
440                      var content = JSON.parse(json);
441                      if(callback){
442                          return callback(content);
443                      }
444                }, function(error){
445                  if(callback){
446                      callback(error);
447                  }else{
448                      console.log(error);
449                  }
450                });
451              },
452              getLogs: function(){
453                var deferred = $q.defer();
454                $http({
455                  method: 'GET',
456                  url: DataService.getHost() + "/xyz/openbmc_project/logging/enumerate",
457                  headers: {
458                      'Accept': 'application/json',
459                      'Content-Type': 'application/json'
460                  },
461                  withCredentials: true
462                }).then(function(response){
463                      var json = JSON.stringify(response.data);
464                      var content = JSON.parse(json);
465                      var dataClone = JSON.parse(JSON.stringify(content.data));
466                      var data = [];
467                      var severityCode = '';
468                      var priority = '';
469                      var health = '';
470                      var relatedItems = [];
471
472                      for(var key in content.data){
473                        if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Id')){
474                          var severityFlags = {low: false, medium: false, high: false};
475                          var healthFlags = {critical: false, warning: false, good: false};
476                          severityCode = content.data[key].Severity.split(".").pop();
477                          priority = Constants.SEVERITY_TO_PRIORITY_MAP[severityCode];
478                          severityFlags[priority.toLowerCase()] = true;
479                          health = Constants.SEVERITY_TO_HEALTH_MAP[severityCode];
480                          healthFlags[health.toLowerCase()] = true;
481                          relatedItems = [];
482                          content.data[key].associations.forEach(function(item){
483                            relatedItems.push(item[2]);
484                          });
485
486                          data.push(Object.assign({
487                            path: key,
488                            copied: false,
489                            priority: priority,
490                            severity_code: severityCode,
491                            severity_flags: severityFlags,
492                            health_flags: healthFlags,
493                            additional_data: content.data[key].AdditionalData.join("\n"),
494                            type: content.data[key].Message,
495                            selected: false,
496                            search_text: ("#" + content.data[key].Id + " " + severityCode + " " + content.data[key].Severity + " " + content.data[key].AdditionalData.join(" ")).toLowerCase(),
497                            meta: false,
498                            confirm: false,
499                            related_items: relatedItems,
500                            data: {key: key, value: content.data[key]}
501                          }, content.data[key]));
502                        }
503                      }
504                      deferred.resolve({data: data, original: dataClone});
505                }, function(error){
506                  console.log(error);
507                  deferred.reject(error);
508                });
509
510                return deferred.promise;
511              },
512              getAllSensorStatus: function(callback){
513                $http({
514                  method: 'GET',
515                  url: DataService.getHost() + "/xyz/openbmc_project/sensors/enumerate",
516                  headers: {
517                      'Accept': 'application/json',
518                      'Content-Type': 'application/json'
519                  },
520                  withCredentials: true
521                }).then(function(response){
522                      var json = JSON.stringify(response.data);
523                      var content = JSON.parse(json);
524                      var dataClone = JSON.parse(JSON.stringify(content.data));
525                      var sensorData = [];
526                      var severity = {};
527                      var title = "";
528                      var tempKeyParts = [];
529                      var order = 0;
530                      var customOrder = 0;
531
532                      function getSensorStatus(reading){
533                        var severityFlags = {critical: false, warning: false, normal: false}, severityText = '', order = 0;
534
535                        if(reading.hasOwnProperty('CriticalLow') &&
536                          reading.Value < reading.CriticalLow
537                          ){
538                          severityFlags.critical = true;
539                          severityText = 'critical';
540                          order = 2;
541                        }else if(reading.hasOwnProperty('CriticalHigh') &&
542                          reading.Value > reading.CriticalHigh
543                          ){
544                          severityFlags.critical = true;
545                          severityText = 'critical';
546                          order = 2;
547                        }else if(reading.hasOwnProperty('CriticalLow') &&
548                          reading.hasOwnProperty('WarningLow') &&
549                          reading.Value >= reading.CriticalLow && reading.Value <= reading.WarningLow){
550                          severityFlags.warning = true;
551                          severityText = 'warning';
552                          order = 1;
553                        }else if(reading.hasOwnProperty('WarningHigh') &&
554                          reading.hasOwnProperty('CriticalHigh') &&
555                          reading.Value >= reading.WarningHigh && reading.Value <= reading.CriticalHigh){
556                          severityFlags.warning = true;
557                          severityText = 'warning';
558                          order = 1;
559                        }else{
560                          severityFlags.normal = true;
561                          severityText = 'normal';
562                        }
563                        return { flags: severityFlags, severityText: severityText, order: order};
564                      }
565
566                      for(var key in content.data){
567                        if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Unit')){
568
569                          severity = getSensorStatus(content.data[key]);
570
571                          if(!content.data[key].hasOwnProperty('CriticalLow')){
572                            content.data[key].CriticalLow = "--";
573                            content.data[key].CriticalHigh = "--";
574                          }
575
576                          if(!content.data[key].hasOwnProperty('WarningLow')){
577                            content.data[key].WarningLow = "--";
578                            content.data[key].WarningHigh = "--";
579                          }
580
581                          tempKeyParts = key.split("/");
582                          title = tempKeyParts.pop();
583                          title = tempKeyParts.pop() + '_' + title;
584                          title = title.split("_").map(function(item){
585                             return item.toLowerCase().charAt(0).toUpperCase() + item.slice(1);
586                          }).reduce(function(prev, el){
587                            return prev + " " + el;
588                          });
589
590                          content.data[key].Value = getScaledValue(content.data[key].Value, content.data[key].Scale);
591                          content.data[key].CriticalLow = getScaledValue(content.data[key].CriticalLow, content.data[key].Scale);
592                          content.data[key].CriticalHigh = getScaledValue(content.data[key].CriticalHigh, content.data[key].Scale);
593                          content.data[key].WarningLow = getScaledValue(content.data[key].WarningLow, content.data[key].Scale);
594                          content.data[key].WarningHigh = getScaledValue(content.data[key].WarningHigh, content.data[key].Scale);
595                          if(Constants.SENSOR_SORT_ORDER.indexOf(content.data[key].Unit) > -1){
596                            customOrder = Constants.SENSOR_SORT_ORDER.indexOf(content.data[key].Unit);
597                          }else{
598                            customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT;
599                          }
600
601                          sensorData.push(Object.assign({
602                            path: key,
603                            selected: false,
604                            confirm: false,
605                            copied: false,
606                            title: title,
607                            unit: Constants.SENSOR_UNIT_MAP[content.data[key].Unit],
608                            severity_flags: severity.flags,
609                            status: severity.severityText,
610                            order: severity.order,
611                            custom_order: customOrder,
612                            search_text: (title + " " + content.data[key].Value + " " +
613                               Constants.SENSOR_UNIT_MAP[content.data[key].Unit] + " " +
614                               severity.severityText + " " +
615                               content.data[key].CriticalLow + " " +
616                               content.data[key].CriticalHigh + " " +
617                               content.data[key].WarningLow + " " +
618                               content.data[key].WarningHigh + " "
619                               ).toLowerCase(),
620                            original_data: {key: key, value: content.data[key]}
621                          }, content.data[key]));
622                        }
623                      }
624
625                      callback(sensorData, dataClone);
626                }, function(error){
627                  console.log(error);
628                });
629              },
630              getActivation: function(imageId){
631                return $http({
632                  method: 'GET',
633                  url: DataService.getHost() + "/xyz/openbmc_project/software/" + imageId + "/attr/Activation",
634                  headers: {
635                    'Accept': 'application/json',
636                    'Content-Type': 'application/json'
637                  },
638                  withCredentials: true
639                }).then(function(response){
640                  return response.data;
641                });
642              },
643              getFirmwares: function(){
644                var deferred = $q.defer();
645                $http({
646                  method: 'GET',
647                  url: DataService.getHost() + "/xyz/openbmc_project/software/enumerate",
648                  headers: {
649                      'Accept': 'application/json',
650                      'Content-Type': 'application/json'
651                  },
652                  withCredentials: true
653                }).then(function(response){
654                      var json = JSON.stringify(response.data);
655                      var content = JSON.parse(json);
656                      var data = [];
657                      var activationStatus = "";
658                      var isExtended = false;
659                      var bmcActiveVersion = "";
660                      var hostActiveVersion = "";
661                      var imageType = "";
662                      var extendedVersions = [];
663                      var functionalImages = [];
664
665                      function getFormatedExtendedVersions(extendedVersion){
666                        var versions = [];
667                        extendedVersion = extendedVersion.split(",");
668
669                        extendedVersion.forEach(function(item){
670                          var parts = item.split("-");
671                          var numberIndex = 0;
672                          for(var i = 0; i < parts.length; i++){
673                            if(/[0-9]/.test(parts[i])){
674                              numberIndex = i;
675                              break;
676                            }
677                          }
678                          var titlePart = parts.splice(0, numberIndex);
679                          titlePart = titlePart.join("");
680                          titlePart = titlePart[0].toUpperCase() + titlePart.substr(1, titlePart.length);
681                          var versionPart = parts.join("-");
682                          versions.push({
683                            title: titlePart,
684                            version: versionPart
685                          });
686                        });
687
688                        return versions;
689                      }
690
691                      // Get the list of functional images so we can compare
692                      // later if an image is functional
693                      if (content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH])
694                      {
695                        functionalImages = content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH].endpoints;
696                      }
697                      for(var key in content.data){
698                        if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Version')){
699                          // If the image is "Functional" use that for the
700                          // activation status, else use the value of "Activation"
701                          // github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml
702                          activationStatus = content.data[key].Activation.split(".").pop();
703                          if (functionalImages.includes(key))
704                          {
705                            activationStatus = "Functional";
706                          }
707
708                          imageType = content.data[key].Purpose.split(".").pop();
709                          isExtended = content.data[key].hasOwnProperty('ExtendedVersion') && content.data[key].ExtendedVersion != "";
710                          if(isExtended){
711                            extendedVersions = getFormatedExtendedVersions(content.data[key].ExtendedVersion);
712                          }
713                          data.push(Object.assign({
714                            path: key,
715                            activationStatus: activationStatus,
716                            imageId: key.split("/").pop(),
717                            imageType: imageType,
718                            isExtended: isExtended,
719                            extended: {
720                              show: false,
721                              versions: extendedVersions
722                            },
723                            data: {key: key, value: content.data[key]}
724                          }, content.data[key]));
725
726                          if(activationStatus == 'Functional' && imageType == 'BMC'){
727                            bmcActiveVersion = content.data[key].Version;
728                          }
729
730                          if(activationStatus == 'Functional' && imageType == 'Host'){
731                            hostActiveVersion = content.data[key].Version;
732                          }
733                        }
734                      }
735
736                      deferred.resolve({
737                          data: data,
738                          bmcActiveVersion: bmcActiveVersion,
739                          hostActiveVersion: hostActiveVersion
740                      });
741                }, function(error){
742                  console.log(error);
743                  deferred.reject(error);
744                });
745
746                return deferred.promise;
747              },
748              changePriority: function(imageId, priority){
749                var deferred = $q.defer();
750                $http({
751                  method: 'PUT',
752                  url: DataService.getHost() + "/xyz/openbmc_project/software/" + imageId + "/attr/Priority",
753                  headers: {
754                      'Accept': 'application/json',
755                      'Content-Type': 'application/json'
756                  },
757                  withCredentials: true,
758                  data: JSON.stringify({"data": priority})
759                }).then(function(response){
760                      var json = JSON.stringify(response.data);
761                      var content = JSON.parse(json);
762                      deferred.resolve(content);
763                }, function(error){
764                  console.log(error);
765                  deferred.reject(error);
766                });
767
768                return deferred.promise;
769              },
770              deleteImage: function(imageId){
771                var deferred = $q.defer();
772                $http({
773                  method: 'POST',
774                  url: DataService.getHost() + "/xyz/openbmc_project/software/" + imageId + "/action/Delete",
775                  headers: {
776                      'Accept': 'application/json',
777                      'Content-Type': 'application/json'
778                  },
779                  withCredentials: true,
780                  data: JSON.stringify({"data": []})
781                }).then(function(response){
782                      var json = JSON.stringify(response.data);
783                      var content = JSON.parse(json);
784                      deferred.resolve(content);
785                }, function(error){
786                  console.log(error);
787                  deferred.reject(error);
788                });
789
790                return deferred.promise;
791              },
792              activateImage: function(imageId){
793                var deferred = $q.defer();
794                $http({
795                  method: 'PUT',
796                  url: DataService.getHost() + "/xyz/openbmc_project/software/" + imageId + "/attr/RequestedActivation",
797                  headers: {
798                      'Accept': 'application/json',
799                      'Content-Type': 'application/json'
800                  },
801                  withCredentials: true,
802                  data: JSON.stringify({"data": Constants.FIRMWARE.ACTIVATE_FIRMWARE})
803                }).then(function(response){
804                      var json = JSON.stringify(response.data);
805                      var content = JSON.parse(json);
806                      deferred.resolve(content);
807                }, function(error){
808                  console.log(error);
809                  deferred.reject(error);
810                });
811
812                return deferred.promise;
813              },
814              uploadImage: function(file){
815                return $http({
816                  method: 'POST',
817                  timeout: 5 * 60 * 1000,
818                  url: DataService.getHost() + "/upload/image",
819                  headers: {
820                    'Content-Type': 'application/octet-stream'
821                  },
822                  withCredentials: true,
823                  data: file
824                }).then(function(response){
825                  return response.data;
826                });
827              },
828              downloadImage: function(host, filename){
829                return $http({
830                  method: 'POST',
831                  url: DataService.getHost() + "/xyz/openbmc_project/software/action/DownloadViaTFTP",
832                  headers: {
833                    'Accept': 'application/json',
834                    'Content-Type': 'application/json'
835                  },
836                  withCredentials: true,
837                  data: JSON.stringify({"data": [filename, host]}),
838                  responseType: 'arraybuffer'
839                }).then(function(response){
840                  return response.data;
841                });
842              },
843              getBMCEthernetInfo: function(){
844                var deferred = $q.defer();
845                $http({
846                  method: 'GET',
847                  url: DataService.getHost() + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc/ethernet",
848                  headers: {
849                      'Accept': 'application/json',
850                      'Content-Type': 'application/json'
851                  },
852                  withCredentials: true
853                }).then(function(response){
854                    var json = JSON.stringify(response.data);
855                    var content = JSON.parse(json);
856                    deferred.resolve(content.data);
857                }, function(error){
858                  console.log(error);
859                  deferred.reject(error);
860                });
861
862                return deferred.promise;
863              },
864              getBMCInfo: function(callback){
865                var deferred = $q.defer();
866                $http({
867                  method: 'GET',
868                  url: DataService.getHost() + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc",
869                  headers: {
870                      'Accept': 'application/json',
871                      'Content-Type': 'application/json'
872                  },
873                  withCredentials: true
874                }).then(function(response){
875                    var json = JSON.stringify(response.data);
876                    var content = JSON.parse(json);
877                    deferred.resolve(content.data);
878                }, function(error){
879                  console.log(error);
880                  deferred.reject(error);
881                });
882                return deferred.promise;
883              },
884              getServerInfo: function(){
885                // TODO: openbmc/openbmc#3117 Need a way via REST to get
886                // interfaces so we can get the system object(s) by the looking
887                // for the system interface.
888                return $http({
889                  method: 'GET',
890                  url: DataService.getHost() + "/xyz/openbmc_project/inventory/system",
891                  headers: {
892                    'Accept': 'application/json',
893                    'Content-Type': 'application/json'
894                  },
895                  withCredentials: true
896                }).then(function(response){
897                  return response.data;
898                });
899              },
900              getHardwares: function(callback){
901                $http({
902                  method: 'GET',
903                  url: DataService.getHost() + "/xyz/openbmc_project/inventory/enumerate",
904                  headers: {
905                      'Accept': 'application/json',
906                      'Content-Type': 'application/json'
907                  },
908                  withCredentials: true
909                }).then(function(response){
910                      var json = JSON.stringify(response.data);
911                      var content = JSON.parse(json);
912                      var hardwareData = [];
913                      var keyIndexMap = {};
914                      var title = "";
915                      var data = [];
916                      var searchText = "";
917                      var componentIndex = -1;
918                      var tempParts = [];
919
920
921                      function isSubComponent(key){
922
923                        for(var i = 0; i < Constants.HARDWARE.parent_components.length; i++){
924                          if(key.split(Constants.HARDWARE.parent_components[i]).length == 2) return true;
925                        }
926
927                        return false;
928                      }
929
930                      function titlelize(title){
931                        title = title.replace(/([A-Z0-9]+)/g, " $1").replace(/^\s+/, "");
932                        for(var i = 0; i < Constants.HARDWARE.uppercase_titles.length; i++){
933                          if(title.toLowerCase().indexOf((Constants.HARDWARE.uppercase_titles[i] + " ")) > -1){
934                            return title.toUpperCase();
935                          }
936                        }
937
938                        return title;
939                      }
940
941                      function camelcaseToLabel(obj){
942                        var transformed = [], label = "", value = "";
943                        for(var key in obj){
944                          label = key.replace(/([A-Z0-9]+)/g, " $1").replace(/^\s+/, "");
945                          if(obj[key] !== ""){
946                            value = obj[key];
947                            if(value == 1 || value == 0){
948                              value = (value == 1) ? 'Yes' : 'No';
949                            }
950                            transformed.push({key:label, value: value});
951                          }
952                        }
953
954                        return transformed;
955                      }
956
957                      function getSearchText(data){
958                        var searchText = "";
959                        for(var i = 0; i < data.length; i++){
960                          searchText += " " + data[i].key + " " + data[i].value;
961                        }
962
963                        return searchText;
964                      }
965
966                      for(var key in content.data){
967                        if(content.data.hasOwnProperty(key) &&
968                           key.indexOf(Constants.HARDWARE.component_key_filter) == 0){
969
970                          data = camelcaseToLabel(content.data[key]);
971                          searchText = getSearchText(data);
972                          title = key.split("/").pop();
973
974                          title = titlelize(title);
975
976                          if(!isSubComponent(key)){
977                              hardwareData.push(Object.assign({
978                                path: key,
979                                title: title,
980                                selected: false,
981                                expanded: false,
982                                search_text: title.toLowerCase() + " " + searchText.toLowerCase(),
983                                sub_components: [],
984                                original_data: {key: key, value: content.data[key]}
985                              }, {items: data}));
986
987                              keyIndexMap[key] = hardwareData.length - 1;
988                          }else{
989                            var tempParts = key.split("/");
990                            tempParts.pop();
991                            tempParts = tempParts.join("/");
992                            componentIndex = keyIndexMap[tempParts];
993                            data = content.data[key];
994                            data.title = title;
995                            hardwareData[componentIndex].sub_components.push(data);
996                            hardwareData[componentIndex].search_text += " " + title.toLowerCase();
997
998                            // Sort the subcomponents alphanumeric so they are displayed on the
999                            // inventory page in order (e.g. core 0, core 1, core 2, ... core 12, core 13)
1000                            hardwareData[componentIndex].sub_components.sort(function (a, b) {
1001                                return a.title.localeCompare(b.title, 'en', { numeric: true });
1002                            });
1003                          }
1004                      }
1005                    }
1006
1007                    if(callback){
1008                       callback(hardwareData, content.data);
1009                    }else{
1010                       return { data: hardwareData, original_data: content.data};
1011                    }
1012                });
1013              },
1014              deleteLogs: function(logs) {
1015                  var defer = $q.defer();
1016                  var promises = [];
1017
1018                  function finished(){
1019                      defer.resolve();
1020                  }
1021
1022                  logs.forEach(function(item){
1023                    promises.push($http({
1024                                      method: 'POST',
1025                                      url: DataService.getHost() + "/xyz/openbmc_project/logging/entry/"+item.Id+"/action/Delete",
1026                                      headers: {
1027                                          'Accept': 'application/json',
1028                                          'Content-Type': 'application/json'
1029                                      },
1030                                      withCredentials: true,
1031                                      data: JSON.stringify({"data": []})
1032                                 }));
1033                  });
1034
1035                  $q.all(promises).then(finished);
1036
1037                  return defer.promise;
1038              },
1039              resolveLogs: function(logs) {
1040                  var defer = $q.defer();
1041                  var promises = [];
1042
1043                  function finished(){
1044                      defer.resolve();
1045                  }
1046
1047                  logs.forEach(function(item){
1048                    promises.push($http({
1049                                      method: 'PUT',
1050                                      url: DataService.getHost() + "/xyz/openbmc_project/logging/entry/"+item.Id+"/attr/Resolved",
1051                                      headers: {
1052                                          'Accept': 'application/json',
1053                                          'Content-Type': 'application/json'
1054                                      },
1055                                      withCredentials: true,
1056                                      data: JSON.stringify({"data": "1"})
1057                                 }));
1058                  });
1059
1060                  $q.all(promises).then(finished);
1061
1062                  return defer.promise;
1063              },
1064              getPowerConsumption: function(){
1065                return $http({
1066                  method: 'GET',
1067                  url: DataService.getHost() + "/xyz/openbmc_project/sensors/power/total_power",
1068                  headers: {
1069                      'Accept': 'application/json',
1070                      'Content-Type': 'application/json'
1071                  },
1072                  withCredentials: true
1073                }).then(function(response){
1074                    var json = JSON.stringify(response.data);
1075                    var content = JSON.parse(json);
1076
1077                    return getScaledValue(content.data.Value,
1078                                          content.data.Scale) + ' ' +
1079                      Constants.POWER_CONSUMPTION_TEXT[content.data.Unit];
1080                }, function(error){
1081                  if ('Not Found' == error.statusText) {
1082                    return Constants.POWER_CONSUMPTION_TEXT.notavailable;
1083                  } else {
1084                    console.log(error);
1085                  }
1086                });
1087              },
1088              getPowerCap: function(){
1089                return $http({
1090                  method: 'GET',
1091                  url: DataService.getHost() + "/xyz/openbmc_project/control/host0/power_cap",
1092                  headers: {
1093                      'Accept': 'application/json',
1094                      'Content-Type': 'application/json'
1095                  },
1096                  withCredentials: true
1097                }).then(function(response){
1098                    var json = JSON.stringify(response.data);
1099                    var content = JSON.parse(json);
1100
1101                    return (false == content.data.PowerCapEnable) ?
1102                        Constants.POWER_CAP_TEXT.disabled :
1103                        content.data.PowerCap + ' ' + Constants.POWER_CAP_TEXT.unit;
1104                }, function(error){
1105                  console.log(error);
1106                });
1107              },
1108          };
1109          return SERVICE;
1110        }]);
1111
1112        })(window.angular);
1113