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