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