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