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