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