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 HOST_STATE_TEXT: Constants.HOST_STATE, 30 LED_STATE: Constants.LED_STATE, 31 LED_STATE_TEXT: Constants.LED_STATE_TEXT, 32 HOST_SESSION_STORAGE_KEY: Constants.API_CREDENTIALS.host_storage_key, 33 validIPV4IP: function(ip) { 34 // Checks for [0-255].[0-255].[0-255].[0-255] 35 return ip.match( 36 /\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/); 37 }, 38 getRedfishSysName: function() { 39 return $http({ 40 method: 'GET', 41 url: DataService.getHost() + '/redfish/v1/Systems', 42 withCredentials: true 43 }) 44 .then( 45 function(response) { 46 var sysUrl = response.data['Members'][0]['@odata.id']; 47 return sysUrl.split('/').pop(-1); 48 }, 49 function(error) { 50 console.log(JSON.stringify(error)); 51 }); 52 }, 53 getSystemLogs: function(recordType) { 54 var uri = '/redfish/v1/Systems/' + DataService.systemName + 55 '/LogServices/EventLog/Entries'; 56 return $http({ 57 method: 'GET', 58 url: DataService.getHost() + uri, 59 withCredentials: true 60 }) 61 .then( 62 function(response) { 63 var logEntries = []; 64 angular.forEach(response.data['Members'], function(log) { 65 if (log.hasOwnProperty('EntryType')) { 66 if (log['EntryType'] == recordType) { 67 logEntries.push(log); 68 } 69 } 70 }); 71 return logEntries; 72 }, 73 function(error) { 74 console.log(JSON.stringify(error)); 75 }); 76 }, 77 clearSystemLogs: function() { 78 var uri = '/redfish/v1/Systems/' + DataService.systemName + 79 '/LogServices/EventLog/Actions/LogService.ClearLog'; 80 return $http({ 81 method: 'POST', 82 url: DataService.getHost() + uri, 83 withCredentials: true 84 }); 85 }, 86 deleteObject: function(path) { 87 return $http({ 88 method: 'POST', 89 url: DataService.getHost() + path + '/action/Delete', 90 withCredentials: true, 91 data: JSON.stringify({'data': []}) 92 }) 93 .then(function(response) { 94 return response.data; 95 }); 96 }, 97 getHostState: function() { 98 var deferred = $q.defer(); 99 $http({ 100 method: 'GET', 101 url: DataService.getHost() + 102 '/xyz/openbmc_project/state/host0/attr/CurrentHostState', 103 withCredentials: true 104 }) 105 .then( 106 function(response) { 107 var json = JSON.stringify(response.data); 108 var content = JSON.parse(json); 109 deferred.resolve(content.data); 110 }, 111 function(error) { 112 console.log(error); 113 deferred.reject(error); 114 }); 115 return deferred.promise; 116 }, 117 getSNMPManagers: function() { 118 return $http({ 119 method: 'GET', 120 url: DataService.getHost() + 121 '/xyz/openbmc_project/network/snmp/manager/enumerate', 122 withCredentials: true 123 }) 124 .then(function(response) { 125 return response.data; 126 }); 127 }, 128 pollHostStatusTillOn: function() { 129 var deferred = $q.defer(); 130 var hostOnTimeout = setTimeout(function() { 131 ws.close(); 132 deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_ON_TIMEOUT)); 133 }, Constants.TIMEOUT.HOST_ON); 134 135 var ws = 136 new WebSocket('wss://' + DataService.server_id + '/subscribe'); 137 var data = JSON.stringify({ 138 'paths': ['/xyz/openbmc_project/state/host0'], 139 'interfaces': ['xyz.openbmc_project.State.Host'] 140 }); 141 ws.onopen = function() { 142 ws.send(data); 143 }; 144 ws.onmessage = function(evt) { 145 var content = JSON.parse(evt.data); 146 var hostState = content.properties.CurrentHostState; 147 if (hostState === Constants.HOST_STATE_TEXT.on_code) { 148 clearTimeout(hostOnTimeout); 149 ws.close(); 150 deferred.resolve(); 151 } else if (hostState === Constants.HOST_STATE_TEXT.error_code) { 152 clearTimeout(hostOnTimeout); 153 ws.close(); 154 deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_QUIESCED)); 155 } 156 }; 157 }, 158 159 pollHostStatusTilReboot: function() { 160 var deferred = $q.defer(); 161 var onState = Constants.HOST_STATE_TEXT.on_code; 162 var offState = Constants.HOST_STATE_TEXT.on_code; 163 var hostTimeout; 164 var setHostTimeout = function(message, timeout) { 165 hostTimeout = setTimeout(function() { 166 ws.close(); 167 deferred.reject(new Error(message)); 168 }, timeout); 169 }; 170 var ws = 171 new WebSocket('wss://' + DataService.server_id + '/subscribe'); 172 var data = JSON.stringify({ 173 'paths': ['/xyz/openbmc_project/state/host0'], 174 'interfaces': ['xyz.openbmc_project.State.Host'] 175 }); 176 ws.onopen = function() { 177 ws.send(data); 178 }; 179 setHostTimeout( 180 Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT, 181 Constants.TIMEOUT.HOST_OFF); 182 var pollState = offState; 183 ws.onmessage = function(evt) { 184 var content = JSON.parse(evt.data); 185 var hostState = content.properties.CurrentHostState; 186 if (hostState === pollState) { 187 if (pollState === offState) { 188 clearTimeout(hostTimeout); 189 pollState = onState; 190 setHostTimeout( 191 Constants.MESSAGES.POLL.HOST_ON_TIMEOUT, 192 Constants.TIMEOUT.HOST_ON); 193 } 194 if (pollState === onState) { 195 clearTimeout(hostTimeout); 196 ws.close(); 197 deferred.resolve(); 198 } 199 } else if (hostState === Constants.HOST_STATE_TEXT.error_code) { 200 clearTimeout(hostTimeout); 201 ws.close(); 202 deferred.reject(new Error(Constants.MESSAGES.POLL.HOST_QUIESCED)); 203 } 204 }; 205 }, 206 207 pollHostStatusTillOff: function() { 208 var deferred = $q.defer(); 209 var hostOffTimeout = setTimeout(function() { 210 ws.close(); 211 deferred.reject( 212 new Error(Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT)); 213 }, Constants.TIMEOUT.HOST_OFF); 214 215 var ws = 216 new WebSocket('wss://' + DataService.server_id + '/subscribe'); 217 var data = JSON.stringify({ 218 'paths': ['/xyz/openbmc_project/state/host0'], 219 'interfaces': ['xyz.openbmc_project.State.Host'] 220 }); 221 ws.onopen = function() { 222 ws.send(data); 223 }; 224 ws.onmessage = function(evt) { 225 var content = JSON.parse(evt.data); 226 var hostState = content.properties.CurrentHostState; 227 if (hostState === Constants.HOST_STATE_TEXT.off_code) { 228 clearTimeout(hostOffTimeout); 229 ws.close(); 230 deferred.resolve(); 231 } 232 }; 233 }, 234 addSNMPManager: function(address, port) { 235 return $http({ 236 method: 'POST', 237 url: DataService.getHost() + 238 '/xyz/openbmc_project/network/snmp/manager/action/Client', 239 withCredentials: true, 240 data: JSON.stringify({'data': [address, +port]}) 241 }) 242 .then(function(response) { 243 return response.data; 244 }); 245 }, 246 setSNMPManagerPort: function(snmpManagerPath, port) { 247 return $http({ 248 method: 'PUT', 249 url: DataService.getHost() + snmpManagerPath + '/attr/Port', 250 withCredentials: true, 251 data: JSON.stringify({'data': +port}) 252 }) 253 .then(function(response) { 254 return response.data; 255 }); 256 }, 257 setSNMPManagerAddress: function(snmpManagerPath, address) { 258 return $http({ 259 method: 'PUT', 260 url: DataService.getHost() + snmpManagerPath + 261 '/attr/Address', 262 withCredentials: true, 263 data: JSON.stringify({'data': address}) 264 }) 265 .then(function(response) { 266 return response.data; 267 }); 268 }, 269 getNetworkInfo: function() { 270 var deferred = $q.defer(); 271 $http({ 272 method: 'GET', 273 url: DataService.getHost() + 274 '/xyz/openbmc_project/network/enumerate', 275 withCredentials: true 276 }) 277 .then( 278 function(response) { 279 var json = JSON.stringify(response.data); 280 var content = JSON.parse(json); 281 var hostname = ''; 282 var defaultgateway = ''; 283 var macAddress = ''; 284 285 function parseNetworkData(content) { 286 var data = { 287 interface_ids: [], 288 interfaces: {}, 289 ip_addresses: {ipv4: [], ipv6: []}, 290 }; 291 var interfaceId = '', keyParts = [], interfaceHash = '', 292 interfaceType = ''; 293 for (var key in content.data) { 294 if (key.match(/network\/eth\d+(_\d+)?$/ig)) { 295 interfaceId = key.split('/').pop(); 296 if (data.interface_ids.indexOf(interfaceId) == -1) { 297 data.interface_ids.push(interfaceId); 298 data.interfaces[interfaceId] = { 299 interfaceIname: '', 300 DomainName: '', 301 MACAddress: '', 302 Nameservers: [], 303 DHCPEnabled: 0, 304 ipv4: {ids: [], values: []}, 305 ipv6: {ids: [], values: []} 306 }; 307 data.interfaces[interfaceId].MACAddress = 308 content.data[key].MACAddress; 309 data.interfaces[interfaceId].DomainName = 310 content.data[key].DomainName.join(' '); 311 data.interfaces[interfaceId].Nameservers = 312 content.data[key].Nameservers; 313 data.interfaces[interfaceId].DHCPEnabled = 314 content.data[key].DHCPEnabled; 315 } 316 } else if ( 317 key.match( 318 /network\/eth\d+(_\d+)?\/ipv[4|6]\/[a-z0-9]+$/ig)) { 319 keyParts = key.split('/'); 320 interfaceHash = keyParts.pop(); 321 interfaceType = keyParts.pop(); 322 interfaceId = keyParts.pop(); 323 324 if (data.interfaces[interfaceId][interfaceType] 325 .ids.indexOf(interfaceHash) == -1) { 326 data.interfaces[interfaceId][interfaceType] 327 .ids.push(interfaceHash); 328 data.interfaces[interfaceId][interfaceType] 329 .values.push(content.data[key]); 330 data.ip_addresses[interfaceType].push( 331 content.data[key]['Address']); 332 } 333 } 334 } 335 return data; 336 } 337 338 if (content.data.hasOwnProperty( 339 '/xyz/openbmc_project/network/config')) { 340 if (content.data['/xyz/openbmc_project/network/config'] 341 .hasOwnProperty('HostName')) { 342 hostname = 343 content.data['/xyz/openbmc_project/network/config'] 344 .HostName; 345 } 346 if (content.data['/xyz/openbmc_project/network/config'] 347 .hasOwnProperty('DefaultGateway')) { 348 defaultgateway = 349 content.data['/xyz/openbmc_project/network/config'] 350 .DefaultGateway; 351 } 352 } 353 354 if (content.data.hasOwnProperty( 355 '/xyz/openbmc_project/network/eth0') && 356 content.data['/xyz/openbmc_project/network/eth0'] 357 .hasOwnProperty('MACAddress')) { 358 macAddress = 359 content.data['/xyz/openbmc_project/network/eth0'] 360 .MACAddress; 361 } 362 363 deferred.resolve({ 364 data: content.data, 365 hostname: hostname, 366 defaultgateway: defaultgateway, 367 mac_address: macAddress, 368 formatted_data: parseNetworkData(content) 369 }); 370 }, 371 function(error) { 372 console.log(error); 373 deferred.reject(error); 374 }); 375 return deferred.promise; 376 }, 377 setMACAddress: function(interface_name, mac_address) { 378 return $http({ 379 method: 'PUT', 380 url: DataService.getHost() + 381 '/xyz/openbmc_project/network/' + interface_name + 382 '/attr/MACAddress', 383 withCredentials: true, 384 data: JSON.stringify({'data': mac_address}) 385 }) 386 .then(function(response) { 387 return response.data; 388 }); 389 }, 390 setDefaultGateway: function(defaultGateway) { 391 return $http({ 392 method: 'PUT', 393 url: DataService.getHost() + 394 '/xyz/openbmc_project/network/config/attr/DefaultGateway', 395 withCredentials: true, 396 data: JSON.stringify({'data': defaultGateway}) 397 }) 398 .then(function(response) { 399 return response.data; 400 }); 401 }, 402 setDHCPEnabled: function(interfaceName, dhcpEnabled) { 403 return $http({ 404 method: 'PUT', 405 url: DataService.getHost() + 406 '/xyz/openbmc_project/network/' + interfaceName + 407 '/attr/DHCPEnabled', 408 withCredentials: true, 409 data: JSON.stringify({'data': dhcpEnabled}) 410 }) 411 .then(function(response) { 412 return response.data; 413 }); 414 }, 415 setNameservers: function(interfaceName, dnsServers) { 416 return $http({ 417 method: 'PUT', 418 url: DataService.getHost() + 419 '/xyz/openbmc_project/network/' + interfaceName + 420 '/attr/Nameservers', 421 withCredentials: true, 422 data: JSON.stringify({'data': dnsServers}) 423 }) 424 .then(function(response) { 425 return response.data; 426 }); 427 }, 428 deleteIPV4: function(interfaceName, networkID) { 429 return $http({ 430 method: 'POST', 431 url: DataService.getHost() + 432 '/xyz/openbmc_project/network/' + interfaceName + 433 '/ipv4/' + networkID + '/action/Delete', 434 withCredentials: true, 435 data: JSON.stringify({'data': []}) 436 }) 437 .then(function(response) { 438 return response.data; 439 }); 440 }, 441 addIPV4: function( 442 interfaceName, ipAddress, netmaskPrefixLength, gateway) { 443 return $http({ 444 method: 'POST', 445 url: DataService.getHost() + 446 '/xyz/openbmc_project/network/' + interfaceName + 447 '/action/IP', 448 withCredentials: true, 449 data: JSON.stringify({ 450 'data': [ 451 'xyz.openbmc_project.Network.IP.Protocol.IPv4', 452 ipAddress, +netmaskPrefixLength, gateway 453 ] 454 }) 455 }) 456 .then(function(response) { 457 return response.data; 458 }); 459 }, 460 getLEDState: function() { 461 var deferred = $q.defer(); 462 $http({ 463 method: 'GET', 464 url: DataService.getHost() + 465 '/xyz/openbmc_project/led/groups/enclosure_identify', 466 withCredentials: true 467 }) 468 .then( 469 function(response) { 470 var json = JSON.stringify(response.data); 471 var content = JSON.parse(json); 472 deferred.resolve(content.data.Asserted); 473 }, 474 function(error) { 475 console.log(error); 476 deferred.reject(error); 477 }); 478 return deferred.promise; 479 }, 480 login: function(username, password, callback) { 481 $http({ 482 method: 'POST', 483 url: DataService.getHost() + '/login', 484 withCredentials: true, 485 data: JSON.stringify({'data': [username, password]}) 486 }) 487 .then( 488 function(response) { 489 if (callback) { 490 callback(response.data); 491 } 492 }, 493 function(error) { 494 if (callback) { 495 if (error && error.status && error.status == 'error') { 496 callback(error); 497 } else { 498 callback(error, true); 499 } 500 } 501 console.log(error); 502 }); 503 }, 504 logout: function(callback) { 505 $http({ 506 method: 'POST', 507 url: DataService.getHost() + '/logout', 508 withCredentials: true, 509 data: JSON.stringify({'data': []}) 510 }) 511 .then( 512 function(response) { 513 if (callback) { 514 callback(response.data); 515 } 516 }, 517 function(error) { 518 if (callback) { 519 callback(null, error); 520 } 521 console.log(error); 522 }); 523 }, 524 getAccountServiceRoles: function() { 525 var roles = []; 526 527 return $http({ 528 method: 'GET', 529 url: DataService.getHost() + 530 '/redfish/v1/AccountService/Roles', 531 withCredentials: true 532 }) 533 .then(function(response) { 534 var members = response.data['Members']; 535 angular.forEach(members, function(member) { 536 roles.push(member['@odata.id'].split('/').pop()); 537 }); 538 return roles; 539 }); 540 }, 541 getAllUserAccounts: function() { 542 var deferred = $q.defer(); 543 var promises = []; 544 545 $http({ 546 method: 'GET', 547 url: DataService.getHost() + '/redfish/v1/AccountService/Accounts', 548 withCredentials: true 549 }) 550 .then( 551 function(response) { 552 var members = response.data['Members']; 553 angular.forEach(members, function(member) { 554 promises.push( 555 $http({ 556 method: 'GET', 557 url: DataService.getHost() + member['@odata.id'], 558 withCredentials: true 559 }).then(function(res) { 560 return res.data; 561 })); 562 }); 563 564 $q.all(promises).then( 565 function(results) { 566 deferred.resolve(results); 567 }, 568 function(errors) { 569 deferred.reject(errors); 570 }); 571 }, 572 function(error) { 573 console.log(error); 574 deferred.reject(error); 575 }); 576 return deferred.promise; 577 }, 578 579 getAllUserAccountProperties: function() { 580 return $http({ 581 method: 'GET', 582 url: DataService.getHost() + '/redfish/v1/AccountService', 583 withCredentials: true 584 }) 585 .then(function(response) { 586 return response.data; 587 }); 588 }, 589 590 saveUserAccountProperties: function(lockoutduration, lockoutthreshold) { 591 var data = {}; 592 if (lockoutduration != undefined) { 593 data['AccountLockoutDuration'] = lockoutduration; 594 } 595 if (lockoutthreshold != undefined) { 596 data['AccountLockoutThreshold'] = lockoutthreshold; 597 } 598 599 return $http({ 600 method: 'PATCH', 601 url: DataService.getHost() + '/redfish/v1/AccountService', 602 withCredentials: true, 603 data: data 604 }); 605 }, 606 607 createUser: function(user, passwd, role, enabled) { 608 var data = {}; 609 data['UserName'] = user; 610 data['Password'] = passwd; 611 data['RoleId'] = role; 612 data['Enabled'] = enabled; 613 614 return $http({ 615 method: 'POST', 616 url: DataService.getHost() + '/redfish/v1/AccountService/Accounts', 617 withCredentials: true, 618 data: data 619 }); 620 }, 621 updateUser: function(user, newUser, passwd, role, enabled) { 622 var data = {}; 623 if ((newUser !== undefined) && (newUser != null)) { 624 data['UserName'] = newUser; 625 } 626 if ((role !== undefined) && (role != null)) { 627 data['RoleId'] = role; 628 } 629 if ((enabled !== undefined) && (enabled != null)) { 630 data['Enabled'] = enabled; 631 } 632 if ((passwd !== undefined) && (passwd != null)) { 633 data['Password'] = passwd; 634 } 635 return $http({ 636 method: 'PATCH', 637 url: DataService.getHost() + 638 '/redfish/v1/AccountService/Accounts/' + user, 639 withCredentials: true, 640 data: data 641 }); 642 }, 643 deleteUser: function(user) { 644 return $http({ 645 method: 'DELETE', 646 url: DataService.getHost() + 647 '/redfish/v1/AccountService/Accounts/' + user, 648 withCredentials: true, 649 }); 650 }, 651 chassisPowerOff: function() { 652 var deferred = $q.defer(); 653 $http({ 654 method: 'PUT', 655 url: DataService.getHost() + 656 '/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition', 657 withCredentials: true, 658 data: JSON.stringify( 659 {'data': 'xyz.openbmc_project.State.Chassis.Transition.Off'}) 660 }) 661 .then( 662 function(response) { 663 var json = JSON.stringify(response.data); 664 var content = JSON.parse(json); 665 deferred.resolve(content.status); 666 }, 667 function(error) { 668 console.log(error); 669 deferred.reject(error); 670 }); 671 return deferred.promise; 672 }, 673 setLEDState: function(state) { 674 return $http({ 675 method: 'PUT', 676 url: DataService.getHost() + 677 '/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted', 678 withCredentials: true, 679 data: JSON.stringify({'data': state}) 680 }) 681 }, 682 getBootOptions: function() { 683 return $http({ 684 method: 'GET', 685 url: DataService.getHost() + '/redfish/v1/Systems/system', 686 withCredentials: true 687 }) 688 .then(function(response) { 689 return response.data; 690 }); 691 }, 692 saveBootSettings: function(data) { 693 return $http({ 694 method: 'PATCH', 695 url: DataService.getHost() + '/redfish/v1/Systems/system', 696 withCredentials: true, 697 data: data 698 }); 699 }, 700 getTPMStatus: function() { 701 return $http({ 702 method: 'GET', 703 url: DataService.getHost() + 704 '/xyz/openbmc_project/control/host0/TPMEnable', 705 withCredentials: true 706 }) 707 .then(function(response) { 708 return response.data; 709 }); 710 }, 711 saveTPMEnable: function(data) { 712 return $http({ 713 method: 'PUT', 714 url: DataService.getHost() + 715 '/xyz/openbmc_project/control/host0/TPMEnable/attr/TPMEnable', 716 withCredentials: true, 717 data: JSON.stringify({'data': data}) 718 }) 719 }, 720 721 bmcReboot: function() { 722 return $http({ 723 method: 'PUT', 724 url: DataService.getHost() + 725 '/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition', 726 withCredentials: true, 727 data: JSON.stringify( 728 {'data': 'xyz.openbmc_project.State.BMC.Transition.Reboot'}) 729 }); 730 }, 731 getLastRebootTime: function() { 732 return $http({ 733 method: 'GET', 734 url: DataService.getHost() + 735 '/xyz/openbmc_project/state/bmc0/attr/LastRebootTime', 736 withCredentials: true 737 }) 738 .then(function(response) { 739 return response.data; 740 }); 741 }, 742 hostPowerOn: function() { 743 var deferred = $q.defer(); 744 $http({ 745 method: 'PUT', 746 url: DataService.getHost() + 747 '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition', 748 withCredentials: true, 749 data: JSON.stringify( 750 {'data': 'xyz.openbmc_project.State.Host.Transition.On'}) 751 }) 752 .then( 753 function(response) { 754 var json = JSON.stringify(response.data); 755 var content = JSON.parse(json); 756 deferred.resolve(content.status); 757 }, 758 function(error) { 759 console.log(error); 760 deferred.reject(error); 761 }); 762 return deferred.promise; 763 }, 764 hostPowerOff: function() { 765 var deferred = $q.defer(); 766 $http({ 767 method: 'PUT', 768 url: DataService.getHost() + 769 '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition', 770 withCredentials: true, 771 data: JSON.stringify( 772 {'data': 'xyz.openbmc_project.State.Host.Transition.Off'}) 773 }) 774 .then( 775 function(response) { 776 var json = JSON.stringify(response.data); 777 var content = JSON.parse(json); 778 deferred.resolve(content.status); 779 }, 780 function(error) { 781 console.log(error); 782 deferred.reject(error); 783 }); 784 return deferred.promise; 785 }, 786 hostReboot: function() { 787 var deferred = $q.defer(); 788 $http({ 789 method: 'PUT', 790 url: DataService.getHost() + 791 '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition', 792 withCredentials: true, 793 data: JSON.stringify( 794 {'data': 'xyz.openbmc_project.State.Host.Transition.Reboot'}) 795 }) 796 .then( 797 function(response) { 798 var json = JSON.stringify(response.data); 799 var content = JSON.parse(json); 800 deferred.resolve(content.status); 801 }, 802 function(error) { 803 console.log(error); 804 deferred.reject(error); 805 }); 806 807 return deferred.promise; 808 }, 809 getLastPowerTime: function() { 810 return $http({ 811 method: 'GET', 812 url: DataService.getHost() + 813 '/xyz/openbmc_project/state/chassis0/attr/LastStateChangeTime', 814 withCredentials: true 815 }) 816 .then(function(response) { 817 return response.data; 818 }); 819 }, 820 getLogs: function() { 821 var deferred = $q.defer(); 822 $http({ 823 method: 'GET', 824 url: DataService.getHost() + 825 '/xyz/openbmc_project/logging/enumerate', 826 withCredentials: true 827 }) 828 .then( 829 function(response) { 830 var json = JSON.stringify(response.data); 831 var content = JSON.parse(json); 832 var dataClone = JSON.parse(JSON.stringify(content.data)); 833 var data = []; 834 var severityCode = ''; 835 var priority = ''; 836 var health = ''; 837 var relatedItems = []; 838 var eventID = 'None'; 839 var description = 'None'; 840 841 for (var key in content.data) { 842 if (content.data.hasOwnProperty(key) && 843 content.data[key].hasOwnProperty('Id')) { 844 var severityFlags = { 845 low: false, 846 medium: false, 847 high: false 848 }; 849 severityCode = 850 content.data[key].Severity.split('.').pop(); 851 priority = 852 Constants.SEVERITY_TO_PRIORITY_MAP[severityCode]; 853 severityFlags[priority.toLowerCase()] = true; 854 relatedItems = []; 855 content.data[key].associations.forEach(function(item) { 856 relatedItems.push(item[2]); 857 }); 858 859 if (content.data[key].hasOwnProperty(['EventID'])) { 860 eventID = content.data[key].EventID; 861 } 862 863 if (content.data[key].hasOwnProperty(['Description'])) { 864 description = content.data[key].Description; 865 } 866 867 data.push(Object.assign( 868 { 869 path: key, 870 copied: false, 871 priority: priority, 872 severity_code: severityCode, 873 severity_flags: severityFlags, 874 additional_data: 875 content.data[key].AdditionalData.join('\n'), 876 type: content.data[key].Message, 877 selected: false, 878 search_text: 879 ('#' + content.data[key].Id + ' ' + 880 severityCode + ' ' + 881 content.data[key].Message + ' ' + 882 content.data[key].Severity + ' ' + 883 content.data[key].AdditionalData.join(' ')) 884 .toLowerCase(), 885 meta: false, 886 confirm: false, 887 related_items: relatedItems, 888 eventID: eventID, 889 description: description, 890 data: {key: key, value: content.data[key]} 891 }, 892 content.data[key])); 893 } 894 } 895 deferred.resolve({data: data, original: dataClone}); 896 }, 897 function(error) { 898 console.log(error); 899 deferred.reject(error); 900 }); 901 902 return deferred.promise; 903 }, 904 getAllSensorStatus: function(callback) { 905 $http({ 906 method: 'GET', 907 url: DataService.getHost() + 908 '/xyz/openbmc_project/sensors/enumerate', 909 withCredentials: true 910 }) 911 .then( 912 function(response) { 913 var json = JSON.stringify(response.data); 914 var content = JSON.parse(json); 915 var dataClone = JSON.parse(JSON.stringify(content.data)); 916 var sensorData = []; 917 var severity = {}; 918 var title = ''; 919 var tempKeyParts = []; 920 var order = 0; 921 var customOrder = 0; 922 923 function getSensorStatus(reading) { 924 var severityFlags = { 925 critical: false, 926 warning: false, 927 normal: false 928 }, 929 severityText = '', order = 0; 930 931 if (reading.hasOwnProperty('CriticalLow') && 932 reading.Value < reading.CriticalLow) { 933 severityFlags.critical = true; 934 severityText = 'critical'; 935 order = 2; 936 } else if ( 937 reading.hasOwnProperty('CriticalHigh') && 938 reading.Value > reading.CriticalHigh) { 939 severityFlags.critical = true; 940 severityText = 'critical'; 941 order = 2; 942 } else if ( 943 reading.hasOwnProperty('CriticalLow') && 944 reading.hasOwnProperty('WarningLow') && 945 reading.Value >= reading.CriticalLow && 946 reading.Value <= reading.WarningLow) { 947 severityFlags.warning = true; 948 severityText = 'warning'; 949 order = 1; 950 } else if ( 951 reading.hasOwnProperty('WarningHigh') && 952 reading.hasOwnProperty('CriticalHigh') && 953 reading.Value >= reading.WarningHigh && 954 reading.Value <= reading.CriticalHigh) { 955 severityFlags.warning = true; 956 severityText = 'warning'; 957 order = 1; 958 } else { 959 severityFlags.normal = true; 960 severityText = 'normal'; 961 } 962 return { 963 flags: severityFlags, 964 severityText: severityText, 965 order: order 966 }; 967 } 968 969 for (var key in content.data) { 970 if (content.data.hasOwnProperty(key) && 971 content.data[key].hasOwnProperty('Unit')) { 972 severity = getSensorStatus(content.data[key]); 973 974 if (!content.data[key].hasOwnProperty('CriticalLow')) { 975 content.data[key].CriticalLow = '--'; 976 content.data[key].CriticalHigh = '--'; 977 } 978 979 if (!content.data[key].hasOwnProperty('WarningLow')) { 980 content.data[key].WarningLow = '--'; 981 content.data[key].WarningHigh = '--'; 982 } 983 984 tempKeyParts = key.split('/'); 985 title = tempKeyParts.pop(); 986 title = tempKeyParts.pop() + '_' + title; 987 title = title.split('_') 988 .map(function(item) { 989 return item.toLowerCase() 990 .charAt(0) 991 .toUpperCase() + 992 item.slice(1); 993 }) 994 .reduce(function(prev, el) { 995 return prev + ' ' + el; 996 }); 997 998 content.data[key].Value = getScaledValue( 999 content.data[key].Value, content.data[key].Scale); 1000 content.data[key].CriticalLow = getScaledValue( 1001 content.data[key].CriticalLow, 1002 content.data[key].Scale); 1003 content.data[key].CriticalHigh = getScaledValue( 1004 content.data[key].CriticalHigh, 1005 content.data[key].Scale); 1006 content.data[key].WarningLow = getScaledValue( 1007 content.data[key].WarningLow, 1008 content.data[key].Scale); 1009 content.data[key].WarningHigh = getScaledValue( 1010 content.data[key].WarningHigh, 1011 content.data[key].Scale); 1012 if (Constants.SENSOR_SORT_ORDER.indexOf( 1013 content.data[key].Unit) > -1) { 1014 customOrder = Constants.SENSOR_SORT_ORDER.indexOf( 1015 content.data[key].Unit); 1016 } else { 1017 customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT; 1018 } 1019 1020 sensorData.push(Object.assign( 1021 { 1022 path: key, 1023 selected: false, 1024 confirm: false, 1025 copied: false, 1026 title: title, 1027 unit: 1028 Constants 1029 .SENSOR_UNIT_MAP[content.data[key].Unit], 1030 severity_flags: severity.flags, 1031 status: severity.severityText, 1032 order: severity.order, 1033 custom_order: customOrder, 1034 search_text: 1035 (title + ' ' + content.data[key].Value + ' ' + 1036 Constants.SENSOR_UNIT_MAP[content.data[key] 1037 .Unit] + 1038 ' ' + severity.severityText + ' ' + 1039 content.data[key].CriticalLow + ' ' + 1040 content.data[key].CriticalHigh + ' ' + 1041 content.data[key].WarningLow + ' ' + 1042 content.data[key].WarningHigh + ' ') 1043 .toLowerCase(), 1044 original_data: 1045 {key: key, value: content.data[key]} 1046 }, 1047 content.data[key])); 1048 } 1049 } 1050 1051 sensorData.sort(function(a, b) { 1052 return a.title.localeCompare( 1053 b.title, 'en', {numeric: true}); 1054 }); 1055 1056 callback(sensorData, dataClone); 1057 }, 1058 function(error) { 1059 console.log(error); 1060 }); 1061 }, 1062 getActivation: function(imageId) { 1063 return $http({ 1064 method: 'GET', 1065 url: DataService.getHost() + 1066 '/xyz/openbmc_project/software/' + imageId + 1067 '/attr/Activation', 1068 withCredentials: true 1069 }) 1070 .then(function(response) { 1071 return response.data; 1072 }); 1073 }, 1074 getFirmwares: function() { 1075 var deferred = $q.defer(); 1076 $http({ 1077 method: 'GET', 1078 url: DataService.getHost() + 1079 '/xyz/openbmc_project/software/enumerate', 1080 withCredentials: true 1081 }) 1082 .then( 1083 function(response) { 1084 var json = JSON.stringify(response.data); 1085 var content = JSON.parse(json); 1086 var data = []; 1087 var isExtended = false; 1088 var bmcActiveVersion = ''; 1089 var hostActiveVersion = ''; 1090 var imageType = ''; 1091 var extendedVersions = []; 1092 var functionalImages = []; 1093 1094 function getFormatedExtendedVersions(extendedVersion) { 1095 var versions = []; 1096 extendedVersion = extendedVersion.split(','); 1097 1098 extendedVersion.forEach(function(item) { 1099 var parts = item.split('-'); 1100 var numberIndex = 0; 1101 for (var i = 0; i < parts.length; i++) { 1102 if (/[0-9]/.test(parts[i])) { 1103 numberIndex = i; 1104 break; 1105 } 1106 } 1107 if (numberIndex > 0) { 1108 var titlePart = parts.splice(0, numberIndex); 1109 titlePart = titlePart.join(''); 1110 titlePart = titlePart[0].toUpperCase() + 1111 titlePart.substr(1, titlePart.length); 1112 var versionPart = parts.join('-'); 1113 versions.push( 1114 {title: titlePart, version: versionPart}); 1115 } 1116 }); 1117 1118 return versions; 1119 } 1120 1121 // Get the list of functional images so we can compare 1122 // later if an image is functional 1123 if (content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]) { 1124 functionalImages = 1125 content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH] 1126 .endpoints; 1127 } 1128 for (var key in content.data) { 1129 if (content.data.hasOwnProperty(key) && 1130 content.data[key].hasOwnProperty('Version')) { 1131 var activationStatus = ''; 1132 1133 // If the image is "Functional" use that for the 1134 // activation status, else use the value of 1135 // "Activation" 1136 // github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml 1137 if (content.data[key].Activation) { 1138 activationStatus = 1139 content.data[key].Activation.split('.').pop(); 1140 } 1141 1142 if (functionalImages.includes(key)) { 1143 activationStatus = 'Functional'; 1144 } 1145 1146 imageType = content.data[key].Purpose.split('.').pop(); 1147 isExtended = content.data[key].hasOwnProperty( 1148 'ExtendedVersion') && 1149 content.data[key].ExtendedVersion != ''; 1150 if (isExtended) { 1151 extendedVersions = getFormatedExtendedVersions( 1152 content.data[key].ExtendedVersion); 1153 } 1154 data.push(Object.assign( 1155 { 1156 path: key, 1157 activationStatus: activationStatus, 1158 imageId: key.split('/').pop(), 1159 imageType: imageType, 1160 isExtended: isExtended, 1161 extended: 1162 {show: false, versions: extendedVersions}, 1163 data: {key: key, value: content.data[key]} 1164 }, 1165 content.data[key])); 1166 1167 if (activationStatus == 'Functional' && 1168 imageType == 'BMC') { 1169 bmcActiveVersion = content.data[key].Version; 1170 } 1171 1172 if (activationStatus == 'Functional' && 1173 imageType == 'Host') { 1174 hostActiveVersion = content.data[key].Version; 1175 } 1176 } 1177 } 1178 1179 deferred.resolve({ 1180 data: data, 1181 bmcActiveVersion: bmcActiveVersion, 1182 hostActiveVersion: hostActiveVersion 1183 }); 1184 }, 1185 function(error) { 1186 console.log(error); 1187 deferred.reject(error); 1188 }); 1189 1190 return deferred.promise; 1191 }, 1192 changePriority: function(imageId, priority) { 1193 return $http({ 1194 method: 'PUT', 1195 url: DataService.getHost() + 1196 '/xyz/openbmc_project/software/' + imageId + 1197 '/attr/Priority', 1198 withCredentials: true, 1199 data: JSON.stringify({'data': priority}) 1200 }) 1201 .then(function(response) { 1202 return response.data; 1203 }); 1204 }, 1205 deleteImage: function(imageId) { 1206 return $http({ 1207 method: 'POST', 1208 url: DataService.getHost() + 1209 '/xyz/openbmc_project/software/' + imageId + 1210 '/action/Delete', 1211 withCredentials: true, 1212 data: JSON.stringify({'data': []}) 1213 }) 1214 .then(function(response) { 1215 return response.data; 1216 }); 1217 }, 1218 activateImage: function(imageId) { 1219 return $http({ 1220 method: 'PUT', 1221 url: DataService.getHost() + 1222 '/xyz/openbmc_project/software/' + imageId + 1223 '/attr/RequestedActivation', 1224 withCredentials: true, 1225 data: JSON.stringify( 1226 {'data': Constants.FIRMWARE.ACTIVATE_FIRMWARE}) 1227 }) 1228 .then(function(response) { 1229 return response.data; 1230 }); 1231 }, 1232 uploadImage: function(file) { 1233 return $http({ 1234 method: 'POST', 1235 timeout: 5 * 60 * 1000, 1236 url: DataService.getHost() + '/upload/image', 1237 // Overwrite the default 'application/json' Content-Type 1238 headers: {'Content-Type': 'application/octet-stream'}, 1239 withCredentials: true, 1240 data: file 1241 }) 1242 .then(function(response) { 1243 return response.data; 1244 }); 1245 }, 1246 downloadImage: function(host, filename) { 1247 return $http({ 1248 method: 'POST', 1249 url: DataService.getHost() + 1250 '/xyz/openbmc_project/software/action/DownloadViaTFTP', 1251 withCredentials: true, 1252 data: JSON.stringify({'data': [filename, host]}), 1253 responseType: 'arraybuffer' 1254 }) 1255 .then(function(response) { 1256 return response.data; 1257 }); 1258 }, 1259 getServerInfo: function() { 1260 // TODO: openbmc/openbmc#3117 Need a way via REST to get 1261 // interfaces so we can get the system object(s) by the looking 1262 // for the system interface. 1263 return $http({ 1264 method: 'GET', 1265 url: DataService.getHost() + 1266 '/xyz/openbmc_project/inventory/system', 1267 withCredentials: true 1268 }) 1269 .then(function(response) { 1270 return response.data; 1271 }); 1272 }, 1273 getBMCTime: function() { 1274 return $http({ 1275 method: 'GET', 1276 url: DataService.getHost() + '/xyz/openbmc_project/time/bmc', 1277 withCredentials: true 1278 }) 1279 .then(function(response) { 1280 return response.data; 1281 }); 1282 }, 1283 getTime: function() { 1284 return $http({ 1285 method: 'GET', 1286 url: DataService.getHost() + 1287 '/xyz/openbmc_project/time/enumerate', 1288 withCredentials: true 1289 }) 1290 .then(function(response) { 1291 return response.data; 1292 }); 1293 }, 1294 // Even though NTPServers is a network interface specific path 1295 // (e.g. /xyz/openbmc_project/network/eth0/attr/NTPServers) it acts 1296 // like a global setting. Just use eth0 for setting and getting the 1297 // NTP Servers until it is moved to a non-network interface specific 1298 // path like it is in Redfish. TODO: openbmc/phosphor-time-manager#4 1299 getNTPServers: function() { 1300 return $http({ 1301 method: 'GET', 1302 url: DataService.getHost() + 1303 '/xyz/openbmc_project/network/eth0/attr/NTPServers', 1304 withCredentials: true 1305 }) 1306 .then(function(response) { 1307 return response.data; 1308 }); 1309 }, 1310 setNTPServers: function(ntpServers) { 1311 return $http({ 1312 method: 'PUT', 1313 url: DataService.getHost() + 1314 '/xyz/openbmc_project/network/eth0/attr/NTPServers', 1315 withCredentials: true, 1316 data: JSON.stringify({'data': ntpServers}) 1317 }) 1318 .then(function(response) { 1319 return response.data; 1320 }); 1321 }, 1322 setTimeMode: function(timeMode) { 1323 return $http({ 1324 method: 'PUT', 1325 url: DataService.getHost() + 1326 '/xyz/openbmc_project/time/sync_method/attr/TimeSyncMethod', 1327 withCredentials: true, 1328 data: JSON.stringify({'data': timeMode}) 1329 }) 1330 .then(function(response) { 1331 return response.data; 1332 }); 1333 }, 1334 setTimeOwner: function(timeOwner) { 1335 return $http({ 1336 method: 'PUT', 1337 url: DataService.getHost() + 1338 '/xyz/openbmc_project/time/owner/attr/TimeOwner', 1339 withCredentials: true, 1340 data: JSON.stringify({'data': timeOwner}) 1341 }) 1342 .then(function(response) { 1343 return response.data; 1344 }); 1345 }, 1346 setBMCTime: function(time) { 1347 return $http({ 1348 method: 'PUT', 1349 url: DataService.getHost() + 1350 '/xyz/openbmc_project/time/bmc/attr/Elapsed', 1351 withCredentials: true, 1352 data: JSON.stringify({'data': time}) 1353 }) 1354 .then(function(response) { 1355 return response.data; 1356 }); 1357 }, 1358 setHostTime: function(time) { 1359 return $http({ 1360 method: 'PUT', 1361 url: DataService.getHost() + 1362 '/xyz/openbmc_project/time/host/attr/Elapsed', 1363 withCredentials: true, 1364 data: JSON.stringify({'data': time}) 1365 }) 1366 .then(function(response) { 1367 return response.data; 1368 }); 1369 }, 1370 getCertificateLocations: function() { 1371 return $http({ 1372 method: 'GET', 1373 url: DataService.getHost() + 1374 '/redfish/v1/CertificateService/CertificateLocations', 1375 withCredentials: true 1376 }) 1377 .then(function(response) { 1378 return response.data; 1379 }); 1380 }, 1381 getCertificate: function(location) { 1382 return $http({ 1383 method: 'GET', 1384 url: DataService.getHost() + location, 1385 withCredentials: true 1386 }) 1387 .then(function(response) { 1388 return response.data; 1389 }); 1390 }, 1391 addNewCertificate: function(file, type) { 1392 return $http({ 1393 method: 'POST', 1394 url: DataService.getHost() + type.location, 1395 headers: {'Content-Type': 'application/x-pem-file'}, 1396 withCredentials: true, 1397 data: file 1398 }) 1399 .then(function(response) { 1400 return response.data; 1401 }); 1402 }, 1403 replaceCertificate: function(data) { 1404 return $http({ 1405 method: 'POST', 1406 url: DataService.getHost() + 1407 '/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate', 1408 withCredentials: true, 1409 data: data 1410 }) 1411 .then(function(response) { 1412 return response.data; 1413 }); 1414 }, 1415 getHardwares: function(callback) { 1416 $http({ 1417 method: 'GET', 1418 url: DataService.getHost() + 1419 '/xyz/openbmc_project/inventory/enumerate', 1420 withCredentials: true 1421 }).then(function(response) { 1422 var json = JSON.stringify(response.data); 1423 var content = JSON.parse(json); 1424 var hardwareData = []; 1425 var keyIndexMap = {}; 1426 var title = ''; 1427 var depth = ''; 1428 var data = []; 1429 var searchText = ''; 1430 var componentIndex = -1; 1431 var parent = ''; 1432 1433 function isSubComponent(key) { 1434 for (var i = 0; i < Constants.HARDWARE.parent_components.length; 1435 i++) { 1436 if (key.split(Constants.HARDWARE.parent_components[i]).length == 1437 2) 1438 return true; 1439 } 1440 1441 return false; 1442 } 1443 1444 function titlelize(title) { 1445 title = title.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, ''); 1446 for (var i = 0; i < Constants.HARDWARE.uppercase_titles.length; 1447 i++) { 1448 if (title.toLowerCase().indexOf( 1449 (Constants.HARDWARE.uppercase_titles[i] + ' ')) > -1) { 1450 return title.toUpperCase(); 1451 } 1452 } 1453 1454 return title; 1455 } 1456 1457 function camelcaseToLabel(obj) { 1458 var transformed = [], label = '', value = ''; 1459 for (var key in obj) { 1460 label = key.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, ''); 1461 if (obj[key] !== '') { 1462 value = obj[key]; 1463 if (value == 1 || value == 0) { 1464 value = (value == 1) ? 'Yes' : 'No'; 1465 } 1466 transformed.push({key: label, value: value}); 1467 } 1468 } 1469 1470 return transformed; 1471 } 1472 1473 function determineParent(key) { 1474 var levels = key.split('/'); 1475 levels.pop(); 1476 return levels.join('/'); 1477 } 1478 1479 function getSearchText(data) { 1480 var searchText = ''; 1481 for (var i = 0; i < data.length; i++) { 1482 searchText += ' ' + data[i].key + ' ' + data[i].value; 1483 } 1484 1485 return searchText; 1486 } 1487 1488 for (var key in content.data) { 1489 if (content.data.hasOwnProperty(key) && 1490 key.indexOf(Constants.HARDWARE.component_key_filter) == 0) { 1491 // All and only associations have the property "endpoints". 1492 // We don't want to show forward/reverse association objects 1493 // that the mapper created on the inventory panel. 1494 // Example: An association from the BMC inventory item to the 1495 // BMC firmware images. See: 1496 // https://github.com/openbmc/docs/blob/master/object-mapper.md#associations 1497 if (content.data[key].hasOwnProperty('endpoints')) { 1498 continue; 1499 } 1500 // There is also an "Associations" property created by the 1501 // Association interface. These would show on the inventory 1502 // panel under the individual inventory item dropdown. There 1503 // can be a lot of associations in this property and they are 1504 // long, full D-Bus paths. Not particularly useful. Remove 1505 // for now. 1506 1507 if (content.data[key].hasOwnProperty('Associations')) { 1508 delete content.data[key].Associations; 1509 } 1510 1511 // Support old Associations interface property 1512 // https://github.com/openbmc/phosphor-logging/blob/master/org/openbmc/Associations.interface.yaml 1513 // Remove when we move to new Associations interface 1514 // openbmc/openbmc#3584 1515 if (content.data[key].hasOwnProperty('associations')) { 1516 delete content.data[key].associations; 1517 } 1518 1519 data = camelcaseToLabel(content.data[key]); 1520 searchText = getSearchText(data); 1521 title = key.split('/').pop(); 1522 title = titlelize(title); 1523 // e.g. /xyz/openbmc_project/inventory/system and 1524 // /xyz/openbmc_project/inventory/system/chassis are depths of 5 1525 // and 6. 1526 depth = key.split('/').length; 1527 parent = determineParent(key); 1528 1529 if (!isSubComponent(key)) { 1530 hardwareData.push(Object.assign( 1531 { 1532 path: key, 1533 title: title, 1534 depth: depth, 1535 parent: parent, 1536 selected: false, 1537 expanded: false, 1538 search_text: title.toLowerCase() + ' ' + 1539 searchText.toLowerCase(), 1540 sub_components: [], 1541 original_data: {key: key, value: content.data[key]} 1542 }, 1543 {items: data})); 1544 1545 1546 keyIndexMap[key] = hardwareData.length - 1; 1547 } else { 1548 parent = determineParent(key) 1549 componentIndex = keyIndexMap[parent]; 1550 data = content.data[key]; 1551 data.title = title; 1552 hardwareData[componentIndex].sub_components.push(data); 1553 hardwareData[componentIndex].search_text += 1554 ' ' + title.toLowerCase(); 1555 1556 // Sort the subcomponents alphanumeric so they are displayed 1557 // on the inventory page in order (e.g. core 0, core 1, core 1558 // 2, ... core 12, core 13) 1559 hardwareData[componentIndex].sub_components.sort(function( 1560 a, b) { 1561 return a.title.localeCompare( 1562 b.title, 'en', {numeric: true}); 1563 }); 1564 } 1565 } 1566 } 1567 // First, order the components by depth and then place the child 1568 // components beneath their parent component alphanumerically. Can 1569 // be removed with completion of 1570 // https://github.com/openbmc/openbmc/issues/3401 1571 // TODO: Remove this once implemented in back end 1572 hardwareData.sort(function(a, b) { 1573 if (a.depth < b.depth) return -1; 1574 if (a.depth > b.depth) return 1; 1575 return b.title.localeCompare(a.title, 'en', {numeric: true}); 1576 }); 1577 1578 var orderedComponents = []; 1579 1580 for (var i = 0; i < hardwareData.length; i++) { 1581 if (!keyIndexMap[hardwareData[i].parent]) { 1582 orderedComponents.push(hardwareData[i]); 1583 } else { 1584 for (var j = 0; j < orderedComponents.length; j++) { 1585 if (orderedComponents[j].path === hardwareData[i].parent) { 1586 var child = hardwareData[i]; 1587 orderedComponents.splice(j + 1, 0, child); 1588 } 1589 } 1590 } 1591 } 1592 1593 if (callback) { 1594 callback(orderedComponents, content.data); 1595 } else { 1596 return {data: orderedComponents, original_data: content.data}; 1597 } 1598 }); 1599 }, 1600 deleteLogs: function(logs) { 1601 var defer = $q.defer(); 1602 var promises = []; 1603 1604 function finished() { 1605 defer.resolve(); 1606 } 1607 1608 logs.forEach(function(item) { 1609 promises.push($http({ 1610 method: 'POST', 1611 url: DataService.getHost() + 1612 '/xyz/openbmc_project/logging/entry/' + item.Id + 1613 '/action/Delete', 1614 withCredentials: true, 1615 data: JSON.stringify({'data': []}) 1616 })); 1617 }); 1618 1619 $q.all(promises).then(finished); 1620 1621 return defer.promise; 1622 }, 1623 resolveLogs: function(logs) { 1624 var promises = []; 1625 1626 logs.forEach(function(item) { 1627 promises.push($http({ 1628 method: 'PUT', 1629 url: DataService.getHost() + 1630 '/xyz/openbmc_project/logging/entry/' + item.Id + 1631 '/attr/Resolved', 1632 withCredentials: true, 1633 data: JSON.stringify({'data': true}) 1634 })); 1635 }); 1636 return $q.all(promises); 1637 }, 1638 setRemoteLoggingServer: (data) => { 1639 const ip = data.hostname; 1640 const port = data.port; 1641 const setIPRequest = $http({ 1642 method: 'PUT', 1643 url: DataService.getHost() + 1644 '/xyz/openbmc_project/logging/config/remote/attr/Address', 1645 withCredentials: true, 1646 data: {'data': ip} 1647 }); 1648 const setPortRequest = $http({ 1649 method: 'PUT', 1650 url: DataService.getHost() + 1651 '/xyz/openbmc_project/logging/config/remote/attr/Port', 1652 withCredentials: true, 1653 data: {'data': port} 1654 }); 1655 const promises = [setIPRequest, setPortRequest]; 1656 return $q.all(promises); 1657 }, 1658 getRemoteLoggingServer: () => { 1659 return $http({ 1660 method: 'GET', 1661 url: DataService.getHost() + 1662 '/xyz/openbmc_project/logging/config/remote', 1663 withCredentials: true 1664 }) 1665 .then((response) => { 1666 const remoteServer = response.data.data; 1667 if (remoteServer === undefined) { 1668 return undefined; 1669 } 1670 const hostname = remoteServer.Address; 1671 const port = remoteServer.Port; 1672 if (hostname === '') { 1673 return undefined; 1674 } else { 1675 return { 1676 hostname, port 1677 } 1678 } 1679 }); 1680 }, 1681 disableRemoteLoggingServer: () => { 1682 return SERVICE.setRemoteLoggingServer({hostname: '', port: 0}); 1683 }, 1684 updateRemoteLoggingServer: (data) => { 1685 // Recommended to disable existing configuration 1686 // before updating config to new server 1687 // https://github.com/openbmc/phosphor-logging#changing-the-rsyslog-server 1688 return SERVICE.disableRemoteLoggingServer() 1689 .then(() => { 1690 return SERVICE.setRemoteLoggingServer(data); 1691 }) 1692 .catch(() => { 1693 // try updating server even if initial disable attempt fails 1694 return SERVICE.setRemoteLoggingServer(data); 1695 }); 1696 }, 1697 getPowerConsumption: function() { 1698 return $http({ 1699 method: 'GET', 1700 url: DataService.getHost() + 1701 '/xyz/openbmc_project/sensors/power/total_power', 1702 withCredentials: true 1703 }) 1704 .then( 1705 function(response) { 1706 var json = JSON.stringify(response.data); 1707 var content = JSON.parse(json); 1708 1709 return getScaledValue( 1710 content.data.Value, content.data.Scale) + 1711 ' ' + 1712 Constants.POWER_CONSUMPTION_TEXT[content.data.Unit]; 1713 }, 1714 function(error) { 1715 if ('Not Found' == error.statusText) { 1716 return Constants.POWER_CONSUMPTION_TEXT.notavailable; 1717 } else { 1718 throw error; 1719 } 1720 }); 1721 }, 1722 getPowerCap: function() { 1723 return $http({ 1724 method: 'GET', 1725 url: DataService.getHost() + 1726 '/xyz/openbmc_project/control/host0/power_cap', 1727 withCredentials: true 1728 }) 1729 .then(function(response) { 1730 return response.data; 1731 }); 1732 }, 1733 setPowerCapEnable: function(powerCapEnable) { 1734 return $http({ 1735 method: 'PUT', 1736 url: DataService.getHost() + 1737 '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCapEnable', 1738 withCredentials: true, 1739 data: JSON.stringify({'data': powerCapEnable}) 1740 }) 1741 .then(function(response) { 1742 return response.data; 1743 }); 1744 }, 1745 setPowerCap: function(powerCap) { 1746 return $http({ 1747 method: 'PUT', 1748 url: DataService.getHost() + 1749 '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCap', 1750 withCredentials: true, 1751 data: JSON.stringify({'data': powerCap}) 1752 }) 1753 .then(function(response) { 1754 return response.data; 1755 }); 1756 }, 1757 setHostname: function(hostname) { 1758 return $http({ 1759 method: 'PUT', 1760 url: DataService.getHost() + 1761 '/xyz/openbmc_project/network/config/attr/HostName', 1762 withCredentials: true, 1763 data: JSON.stringify({'data': hostname}) 1764 }) 1765 .then(function(response) { 1766 return response.data; 1767 }); 1768 }, 1769 }; 1770 return SERVICE; 1771 } 1772 ]); 1773})(window.angular); 1774