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