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 saveLdapProperties: function(properties) { 608 return $http({ 609 method: 'PATCH', 610 url: DataService.getHost() + '/redfish/v1/AccountService', 611 withCredentials: true, 612 data: properties 613 }); 614 }, 615 createUser: function(user, passwd, role, enabled) { 616 var data = {}; 617 data['UserName'] = user; 618 data['Password'] = passwd; 619 data['RoleId'] = role; 620 data['Enabled'] = enabled; 621 622 return $http({ 623 method: 'POST', 624 url: DataService.getHost() + '/redfish/v1/AccountService/Accounts', 625 withCredentials: true, 626 data: data 627 }); 628 }, 629 updateUser: function(user, newUser, passwd, role, enabled, locked) { 630 var data = {}; 631 if ((newUser !== undefined) && (newUser != null)) { 632 data['UserName'] = newUser; 633 } 634 if ((role !== undefined) && (role != null)) { 635 data['RoleId'] = role; 636 } 637 if ((enabled !== undefined) && (enabled != null)) { 638 data['Enabled'] = enabled; 639 } 640 if ((passwd !== undefined) && (passwd != null)) { 641 data['Password'] = passwd; 642 } 643 if ((locked !== undefined) && (locked !== null)) { 644 data['Locked'] = locked 645 } 646 return $http({ 647 method: 'PATCH', 648 url: DataService.getHost() + 649 '/redfish/v1/AccountService/Accounts/' + user, 650 withCredentials: true, 651 data: data 652 }); 653 }, 654 deleteUser: function(user) { 655 return $http({ 656 method: 'DELETE', 657 url: DataService.getHost() + 658 '/redfish/v1/AccountService/Accounts/' + user, 659 withCredentials: true, 660 }); 661 }, 662 chassisPowerOff: function() { 663 var deferred = $q.defer(); 664 $http({ 665 method: 'PUT', 666 url: DataService.getHost() + 667 '/xyz/openbmc_project/state/chassis0/attr/RequestedPowerTransition', 668 withCredentials: true, 669 data: JSON.stringify( 670 {'data': 'xyz.openbmc_project.State.Chassis.Transition.Off'}) 671 }) 672 .then( 673 function(response) { 674 var json = JSON.stringify(response.data); 675 var content = JSON.parse(json); 676 deferred.resolve(content.status); 677 }, 678 function(error) { 679 console.log(error); 680 deferred.reject(error); 681 }); 682 return deferred.promise; 683 }, 684 setLEDState: function(state) { 685 return $http({ 686 method: 'PUT', 687 url: DataService.getHost() + 688 '/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted', 689 withCredentials: true, 690 data: JSON.stringify({'data': state}) 691 }) 692 }, 693 getBootOptions: function() { 694 return $http({ 695 method: 'GET', 696 url: DataService.getHost() + '/redfish/v1/Systems/system', 697 withCredentials: true 698 }) 699 .then(function(response) { 700 return response.data; 701 }); 702 }, 703 saveBootSettings: function(data) { 704 return $http({ 705 method: 'PATCH', 706 url: DataService.getHost() + '/redfish/v1/Systems/system', 707 withCredentials: true, 708 data: data 709 }); 710 }, 711 getTPMStatus: function() { 712 return $http({ 713 method: 'GET', 714 url: DataService.getHost() + 715 '/xyz/openbmc_project/control/host0/TPMEnable', 716 withCredentials: true 717 }) 718 .then(function(response) { 719 return response.data; 720 }); 721 }, 722 saveTPMEnable: function(data) { 723 return $http({ 724 method: 'PUT', 725 url: DataService.getHost() + 726 '/xyz/openbmc_project/control/host0/TPMEnable/attr/TPMEnable', 727 withCredentials: true, 728 data: JSON.stringify({'data': data}) 729 }) 730 }, 731 732 bmcReboot: function() { 733 return $http({ 734 method: 'PUT', 735 url: DataService.getHost() + 736 '/xyz/openbmc_project/state/bmc0/attr/RequestedBMCTransition', 737 withCredentials: true, 738 data: JSON.stringify( 739 {'data': 'xyz.openbmc_project.State.BMC.Transition.Reboot'}) 740 }); 741 }, 742 getLastRebootTime: function() { 743 return $http({ 744 method: 'GET', 745 url: DataService.getHost() + 746 '/xyz/openbmc_project/state/bmc0/attr/LastRebootTime', 747 withCredentials: true 748 }) 749 .then(function(response) { 750 return response.data; 751 }); 752 }, 753 hostPowerOn: function() { 754 var deferred = $q.defer(); 755 $http({ 756 method: 'PUT', 757 url: DataService.getHost() + 758 '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition', 759 withCredentials: true, 760 data: JSON.stringify( 761 {'data': 'xyz.openbmc_project.State.Host.Transition.On'}) 762 }) 763 .then( 764 function(response) { 765 var json = JSON.stringify(response.data); 766 var content = JSON.parse(json); 767 deferred.resolve(content.status); 768 }, 769 function(error) { 770 console.log(error); 771 deferred.reject(error); 772 }); 773 return deferred.promise; 774 }, 775 hostPowerOff: function() { 776 var deferred = $q.defer(); 777 $http({ 778 method: 'PUT', 779 url: DataService.getHost() + 780 '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition', 781 withCredentials: true, 782 data: JSON.stringify( 783 {'data': 'xyz.openbmc_project.State.Host.Transition.Off'}) 784 }) 785 .then( 786 function(response) { 787 var json = JSON.stringify(response.data); 788 var content = JSON.parse(json); 789 deferred.resolve(content.status); 790 }, 791 function(error) { 792 console.log(error); 793 deferred.reject(error); 794 }); 795 return deferred.promise; 796 }, 797 hostReboot: function() { 798 var deferred = $q.defer(); 799 $http({ 800 method: 'PUT', 801 url: DataService.getHost() + 802 '/xyz/openbmc_project/state/host0/attr/RequestedHostTransition', 803 withCredentials: true, 804 data: JSON.stringify( 805 {'data': 'xyz.openbmc_project.State.Host.Transition.Reboot'}) 806 }) 807 .then( 808 function(response) { 809 var json = JSON.stringify(response.data); 810 var content = JSON.parse(json); 811 deferred.resolve(content.status); 812 }, 813 function(error) { 814 console.log(error); 815 deferred.reject(error); 816 }); 817 818 return deferred.promise; 819 }, 820 getLastPowerTime: function() { 821 return $http({ 822 method: 'GET', 823 url: DataService.getHost() + 824 '/xyz/openbmc_project/state/chassis0/attr/LastStateChangeTime', 825 withCredentials: true 826 }) 827 .then(function(response) { 828 return response.data; 829 }); 830 }, 831 getLogs: function() { 832 var deferred = $q.defer(); 833 $http({ 834 method: 'GET', 835 url: DataService.getHost() + 836 '/xyz/openbmc_project/logging/enumerate', 837 withCredentials: true 838 }) 839 .then( 840 function(response) { 841 var json = JSON.stringify(response.data); 842 var content = JSON.parse(json); 843 var dataClone = JSON.parse(JSON.stringify(content.data)); 844 var data = []; 845 var severityCode = ''; 846 var priority = ''; 847 var health = ''; 848 var relatedItems = []; 849 var eventID = 'None'; 850 var description = 'None'; 851 852 for (var key in content.data) { 853 if (content.data.hasOwnProperty(key) && 854 content.data[key].hasOwnProperty('Id')) { 855 var severityFlags = { 856 low: false, 857 medium: false, 858 high: false 859 }; 860 severityCode = 861 content.data[key].Severity.split('.').pop(); 862 priority = 863 Constants.SEVERITY_TO_PRIORITY_MAP[severityCode]; 864 severityFlags[priority.toLowerCase()] = true; 865 relatedItems = []; 866 content.data[key].associations.forEach(function(item) { 867 relatedItems.push(item[2]); 868 }); 869 870 if (content.data[key].hasOwnProperty(['EventID'])) { 871 eventID = content.data[key].EventID; 872 } 873 874 if (content.data[key].hasOwnProperty(['Description'])) { 875 description = content.data[key].Description; 876 } 877 878 data.push(Object.assign( 879 { 880 path: key, 881 copied: false, 882 priority: priority, 883 severity_code: severityCode, 884 severity_flags: severityFlags, 885 additional_data: 886 content.data[key].AdditionalData.join('\n'), 887 type: content.data[key].Message, 888 selected: false, 889 search_text: 890 ('#' + content.data[key].Id + ' ' + 891 severityCode + ' ' + 892 content.data[key].Message + ' ' + 893 content.data[key].Severity + ' ' + 894 content.data[key].AdditionalData.join(' ')) 895 .toLowerCase(), 896 meta: false, 897 confirm: false, 898 related_items: relatedItems, 899 eventID: eventID, 900 description: description, 901 data: {key: key, value: content.data[key]} 902 }, 903 content.data[key])); 904 } 905 } 906 deferred.resolve({data: data, original: dataClone}); 907 }, 908 function(error) { 909 console.log(error); 910 deferred.reject(error); 911 }); 912 913 return deferred.promise; 914 }, 915 getAllSensorStatus: function(callback) { 916 $http({ 917 method: 'GET', 918 url: DataService.getHost() + 919 '/xyz/openbmc_project/sensors/enumerate', 920 withCredentials: true 921 }) 922 .then( 923 function(response) { 924 var json = JSON.stringify(response.data); 925 var content = JSON.parse(json); 926 var dataClone = JSON.parse(JSON.stringify(content.data)); 927 var sensorData = []; 928 var severity = {}; 929 var title = ''; 930 var tempKeyParts = []; 931 var order = 0; 932 var customOrder = 0; 933 934 function getSensorStatus(reading) { 935 var severityFlags = { 936 critical: false, 937 warning: false, 938 normal: false 939 }, 940 severityText = '', order = 0; 941 942 if (reading.hasOwnProperty('CriticalLow') && 943 reading.Value < reading.CriticalLow) { 944 severityFlags.critical = true; 945 severityText = 'critical'; 946 order = 2; 947 } else if ( 948 reading.hasOwnProperty('CriticalHigh') && 949 reading.Value > reading.CriticalHigh) { 950 severityFlags.critical = true; 951 severityText = 'critical'; 952 order = 2; 953 } else if ( 954 reading.hasOwnProperty('CriticalLow') && 955 reading.hasOwnProperty('WarningLow') && 956 reading.Value >= reading.CriticalLow && 957 reading.Value <= reading.WarningLow) { 958 severityFlags.warning = true; 959 severityText = 'warning'; 960 order = 1; 961 } else if ( 962 reading.hasOwnProperty('WarningHigh') && 963 reading.hasOwnProperty('CriticalHigh') && 964 reading.Value >= reading.WarningHigh && 965 reading.Value <= reading.CriticalHigh) { 966 severityFlags.warning = true; 967 severityText = 'warning'; 968 order = 1; 969 } else { 970 severityFlags.normal = true; 971 severityText = 'normal'; 972 } 973 return { 974 flags: severityFlags, 975 severityText: severityText, 976 order: order 977 }; 978 } 979 980 for (var key in content.data) { 981 if (content.data.hasOwnProperty(key) && 982 content.data[key].hasOwnProperty('Unit')) { 983 severity = getSensorStatus(content.data[key]); 984 985 if (!content.data[key].hasOwnProperty('CriticalLow')) { 986 content.data[key].CriticalLow = '--'; 987 content.data[key].CriticalHigh = '--'; 988 } 989 990 if (!content.data[key].hasOwnProperty('WarningLow')) { 991 content.data[key].WarningLow = '--'; 992 content.data[key].WarningHigh = '--'; 993 } 994 995 tempKeyParts = key.split('/'); 996 title = tempKeyParts.pop(); 997 title = tempKeyParts.pop() + '_' + title; 998 title = title.split('_') 999 .map(function(item) { 1000 return item.toLowerCase() 1001 .charAt(0) 1002 .toUpperCase() + 1003 item.slice(1); 1004 }) 1005 .reduce(function(prev, el) { 1006 return prev + ' ' + el; 1007 }); 1008 1009 content.data[key].Value = getScaledValue( 1010 content.data[key].Value, content.data[key].Scale); 1011 content.data[key].CriticalLow = getScaledValue( 1012 content.data[key].CriticalLow, 1013 content.data[key].Scale); 1014 content.data[key].CriticalHigh = getScaledValue( 1015 content.data[key].CriticalHigh, 1016 content.data[key].Scale); 1017 content.data[key].WarningLow = getScaledValue( 1018 content.data[key].WarningLow, 1019 content.data[key].Scale); 1020 content.data[key].WarningHigh = getScaledValue( 1021 content.data[key].WarningHigh, 1022 content.data[key].Scale); 1023 if (Constants.SENSOR_SORT_ORDER.indexOf( 1024 content.data[key].Unit) > -1) { 1025 customOrder = Constants.SENSOR_SORT_ORDER.indexOf( 1026 content.data[key].Unit); 1027 } else { 1028 customOrder = Constants.SENSOR_SORT_ORDER_DEFAULT; 1029 } 1030 1031 sensorData.push(Object.assign( 1032 { 1033 path: key, 1034 selected: false, 1035 confirm: false, 1036 copied: false, 1037 title: title, 1038 unit: 1039 Constants 1040 .SENSOR_UNIT_MAP[content.data[key].Unit], 1041 severity_flags: severity.flags, 1042 status: severity.severityText, 1043 order: severity.order, 1044 custom_order: customOrder, 1045 search_text: 1046 (title + ' ' + content.data[key].Value + ' ' + 1047 Constants.SENSOR_UNIT_MAP[content.data[key] 1048 .Unit] + 1049 ' ' + severity.severityText + ' ' + 1050 content.data[key].CriticalLow + ' ' + 1051 content.data[key].CriticalHigh + ' ' + 1052 content.data[key].WarningLow + ' ' + 1053 content.data[key].WarningHigh + ' ') 1054 .toLowerCase(), 1055 original_data: 1056 {key: key, value: content.data[key]} 1057 }, 1058 content.data[key])); 1059 } 1060 } 1061 1062 sensorData.sort(function(a, b) { 1063 return a.title.localeCompare( 1064 b.title, 'en', {numeric: true}); 1065 }); 1066 1067 callback(sensorData, dataClone); 1068 }, 1069 function(error) { 1070 console.log(error); 1071 }); 1072 }, 1073 getActivation: function(imageId) { 1074 return $http({ 1075 method: 'GET', 1076 url: DataService.getHost() + 1077 '/xyz/openbmc_project/software/' + imageId + 1078 '/attr/Activation', 1079 withCredentials: true 1080 }) 1081 .then(function(response) { 1082 return response.data; 1083 }); 1084 }, 1085 getFirmwares: function() { 1086 var deferred = $q.defer(); 1087 $http({ 1088 method: 'GET', 1089 url: DataService.getHost() + 1090 '/xyz/openbmc_project/software/enumerate', 1091 withCredentials: true 1092 }) 1093 .then( 1094 function(response) { 1095 var json = JSON.stringify(response.data); 1096 var content = JSON.parse(json); 1097 var data = []; 1098 var isExtended = false; 1099 var bmcActiveVersion = ''; 1100 var hostActiveVersion = ''; 1101 var imageType = ''; 1102 var extendedVersions = []; 1103 var functionalImages = []; 1104 1105 function getFormatedExtendedVersions(extendedVersion) { 1106 var versions = []; 1107 extendedVersion = extendedVersion.split(','); 1108 1109 extendedVersion.forEach(function(item) { 1110 var parts = item.split('-'); 1111 var numberIndex = 0; 1112 for (var i = 0; i < parts.length; i++) { 1113 if (/[0-9]/.test(parts[i])) { 1114 numberIndex = i; 1115 break; 1116 } 1117 } 1118 if (numberIndex > 0) { 1119 var titlePart = parts.splice(0, numberIndex); 1120 titlePart = titlePart.join(''); 1121 titlePart = titlePart[0].toUpperCase() + 1122 titlePart.substr(1, titlePart.length); 1123 var versionPart = parts.join('-'); 1124 versions.push( 1125 {title: titlePart, version: versionPart}); 1126 } 1127 }); 1128 1129 return versions; 1130 } 1131 1132 // Get the list of functional images so we can compare 1133 // later if an image is functional 1134 if (content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH]) { 1135 functionalImages = 1136 content.data[Constants.FIRMWARE.FUNCTIONAL_OBJPATH] 1137 .endpoints; 1138 } 1139 for (var key in content.data) { 1140 if (content.data.hasOwnProperty(key) && 1141 content.data[key].hasOwnProperty('Version')) { 1142 var activationStatus = ''; 1143 1144 // If the image is "Functional" use that for the 1145 // activation status, else use the value of 1146 // "Activation" 1147 // github.com/openbmc/phosphor-dbus-interfaces/blob/master/xyz/openbmc_project/Software/Activation.interface.yaml 1148 if (content.data[key].Activation) { 1149 activationStatus = 1150 content.data[key].Activation.split('.').pop(); 1151 } 1152 1153 if (functionalImages.includes(key)) { 1154 activationStatus = 'Functional'; 1155 } 1156 1157 imageType = content.data[key].Purpose.split('.').pop(); 1158 isExtended = content.data[key].hasOwnProperty( 1159 'ExtendedVersion') && 1160 content.data[key].ExtendedVersion != ''; 1161 if (isExtended) { 1162 extendedVersions = getFormatedExtendedVersions( 1163 content.data[key].ExtendedVersion); 1164 } 1165 data.push(Object.assign( 1166 { 1167 path: key, 1168 activationStatus: activationStatus, 1169 imageId: key.split('/').pop(), 1170 imageType: imageType, 1171 isExtended: isExtended, 1172 extended: 1173 {show: false, versions: extendedVersions}, 1174 data: {key: key, value: content.data[key]} 1175 }, 1176 content.data[key])); 1177 1178 if (activationStatus == 'Functional' && 1179 imageType == 'BMC') { 1180 bmcActiveVersion = content.data[key].Version; 1181 } 1182 1183 if (activationStatus == 'Functional' && 1184 imageType == 'Host') { 1185 hostActiveVersion = content.data[key].Version; 1186 } 1187 } 1188 } 1189 1190 deferred.resolve({ 1191 data: data, 1192 bmcActiveVersion: bmcActiveVersion, 1193 hostActiveVersion: hostActiveVersion 1194 }); 1195 }, 1196 function(error) { 1197 console.log(error); 1198 deferred.reject(error); 1199 }); 1200 1201 return deferred.promise; 1202 }, 1203 changePriority: function(imageId, priority) { 1204 return $http({ 1205 method: 'PUT', 1206 url: DataService.getHost() + 1207 '/xyz/openbmc_project/software/' + imageId + 1208 '/attr/Priority', 1209 withCredentials: true, 1210 data: JSON.stringify({'data': priority}) 1211 }) 1212 .then(function(response) { 1213 return response.data; 1214 }); 1215 }, 1216 deleteImage: function(imageId) { 1217 return $http({ 1218 method: 'POST', 1219 url: DataService.getHost() + 1220 '/xyz/openbmc_project/software/' + imageId + 1221 '/action/Delete', 1222 withCredentials: true, 1223 data: JSON.stringify({'data': []}) 1224 }) 1225 .then(function(response) { 1226 return response.data; 1227 }); 1228 }, 1229 activateImage: function(imageId) { 1230 return $http({ 1231 method: 'PUT', 1232 url: DataService.getHost() + 1233 '/xyz/openbmc_project/software/' + imageId + 1234 '/attr/RequestedActivation', 1235 withCredentials: true, 1236 data: JSON.stringify( 1237 {'data': Constants.FIRMWARE.ACTIVATE_FIRMWARE}) 1238 }) 1239 .then(function(response) { 1240 return response.data; 1241 }); 1242 }, 1243 uploadImage: function(file) { 1244 return $http({ 1245 method: 'POST', 1246 timeout: 5 * 60 * 1000, 1247 url: DataService.getHost() + '/upload/image', 1248 // Overwrite the default 'application/json' Content-Type 1249 headers: {'Content-Type': 'application/octet-stream'}, 1250 withCredentials: true, 1251 data: file 1252 }) 1253 .then(function(response) { 1254 return response.data; 1255 }); 1256 }, 1257 downloadImage: function(host, filename) { 1258 return $http({ 1259 method: 'POST', 1260 url: DataService.getHost() + 1261 '/xyz/openbmc_project/software/action/DownloadViaTFTP', 1262 withCredentials: true, 1263 data: JSON.stringify({'data': [filename, host]}), 1264 responseType: 'arraybuffer' 1265 }) 1266 .then(function(response) { 1267 return response.data; 1268 }); 1269 }, 1270 getServerInfo: function() { 1271 // TODO: openbmc/openbmc#3117 Need a way via REST to get 1272 // interfaces so we can get the system object(s) by the looking 1273 // for the system interface. 1274 return $http({ 1275 method: 'GET', 1276 url: DataService.getHost() + 1277 '/xyz/openbmc_project/inventory/system', 1278 withCredentials: true 1279 }) 1280 .then(function(response) { 1281 return response.data; 1282 }); 1283 }, 1284 getBMCTime: function() { 1285 return $http({ 1286 method: 'GET', 1287 url: DataService.getHost() + '/xyz/openbmc_project/time/bmc', 1288 withCredentials: true 1289 }) 1290 .then(function(response) { 1291 return response.data; 1292 }); 1293 }, 1294 getTime: function() { 1295 return $http({ 1296 method: 'GET', 1297 url: DataService.getHost() + 1298 '/xyz/openbmc_project/time/enumerate', 1299 withCredentials: true 1300 }) 1301 .then(function(response) { 1302 return response.data; 1303 }); 1304 }, 1305 // Even though NTPServers is a network interface specific path 1306 // (e.g. /xyz/openbmc_project/network/eth0/attr/NTPServers) it acts 1307 // like a global setting. Just use eth0 for setting and getting the 1308 // NTP Servers until it is moved to a non-network interface specific 1309 // path like it is in Redfish. TODO: openbmc/phosphor-time-manager#4 1310 getNTPServers: function() { 1311 return $http({ 1312 method: 'GET', 1313 url: DataService.getHost() + 1314 '/xyz/openbmc_project/network/eth0/attr/NTPServers', 1315 withCredentials: true 1316 }) 1317 .then(function(response) { 1318 return response.data; 1319 }); 1320 }, 1321 setNTPServers: function(ntpServers) { 1322 return $http({ 1323 method: 'PUT', 1324 url: DataService.getHost() + 1325 '/xyz/openbmc_project/network/eth0/attr/NTPServers', 1326 withCredentials: true, 1327 data: JSON.stringify({'data': ntpServers}) 1328 }) 1329 .then(function(response) { 1330 return response.data; 1331 }); 1332 }, 1333 setTimeMode: function(timeMode) { 1334 return $http({ 1335 method: 'PUT', 1336 url: DataService.getHost() + 1337 '/xyz/openbmc_project/time/sync_method/attr/TimeSyncMethod', 1338 withCredentials: true, 1339 data: JSON.stringify({'data': timeMode}) 1340 }) 1341 .then(function(response) { 1342 return response.data; 1343 }); 1344 }, 1345 setTimeOwner: function(timeOwner) { 1346 return $http({ 1347 method: 'PUT', 1348 url: DataService.getHost() + 1349 '/xyz/openbmc_project/time/owner/attr/TimeOwner', 1350 withCredentials: true, 1351 data: JSON.stringify({'data': timeOwner}) 1352 }) 1353 .then(function(response) { 1354 return response.data; 1355 }); 1356 }, 1357 setBMCTime: function(time) { 1358 return $http({ 1359 method: 'PUT', 1360 url: DataService.getHost() + 1361 '/xyz/openbmc_project/time/bmc/attr/Elapsed', 1362 withCredentials: true, 1363 data: JSON.stringify({'data': time}) 1364 }) 1365 .then(function(response) { 1366 return response.data; 1367 }); 1368 }, 1369 setHostTime: function(time) { 1370 return $http({ 1371 method: 'PUT', 1372 url: DataService.getHost() + 1373 '/xyz/openbmc_project/time/host/attr/Elapsed', 1374 withCredentials: true, 1375 data: JSON.stringify({'data': time}) 1376 }) 1377 .then(function(response) { 1378 return response.data; 1379 }); 1380 }, 1381 getCertificateLocations: function() { 1382 return $http({ 1383 method: 'GET', 1384 url: DataService.getHost() + 1385 '/redfish/v1/CertificateService/CertificateLocations', 1386 withCredentials: true 1387 }) 1388 .then(function(response) { 1389 return response.data; 1390 }); 1391 }, 1392 getCertificate: function(location) { 1393 return $http({ 1394 method: 'GET', 1395 url: DataService.getHost() + location, 1396 withCredentials: true 1397 }) 1398 .then(function(response) { 1399 return response.data; 1400 }); 1401 }, 1402 addNewCertificate: function(file, type) { 1403 return $http({ 1404 method: 'POST', 1405 url: DataService.getHost() + type.location, 1406 headers: {'Content-Type': 'application/x-pem-file'}, 1407 withCredentials: true, 1408 data: file 1409 }) 1410 .then(function(response) { 1411 return response.data; 1412 }); 1413 }, 1414 createCSRCertificate: function(data) { 1415 return $http({ 1416 method: 'POST', 1417 url: DataService.getHost() + 1418 '/redfish/v1/CertificateService/Actions/CertificateService.GenerateCSR', 1419 withCredentials: true, 1420 data: data 1421 }) 1422 .then(function(response) { 1423 return response.data['CSRString']; 1424 }); 1425 }, 1426 replaceCertificate: function(data) { 1427 return $http({ 1428 method: 'POST', 1429 url: DataService.getHost() + 1430 '/redfish/v1/CertificateService/Actions/CertificateService.ReplaceCertificate', 1431 withCredentials: true, 1432 data: data 1433 }) 1434 .then(function(response) { 1435 return response.data; 1436 }); 1437 }, 1438 getHardwares: function(callback) { 1439 $http({ 1440 method: 'GET', 1441 url: DataService.getHost() + 1442 '/xyz/openbmc_project/inventory/enumerate', 1443 withCredentials: true 1444 }).then(function(response) { 1445 var json = JSON.stringify(response.data); 1446 var content = JSON.parse(json); 1447 var hardwareData = []; 1448 var keyIndexMap = {}; 1449 var title = ''; 1450 var depth = ''; 1451 var data = []; 1452 var searchText = ''; 1453 var componentIndex = -1; 1454 var parent = ''; 1455 1456 function isSubComponent(key) { 1457 for (var i = 0; i < Constants.HARDWARE.parent_components.length; 1458 i++) { 1459 if (key.split(Constants.HARDWARE.parent_components[i]).length == 1460 2) 1461 return true; 1462 } 1463 1464 return false; 1465 } 1466 1467 function titlelize(title) { 1468 title = title.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, ''); 1469 for (var i = 0; i < Constants.HARDWARE.uppercase_titles.length; 1470 i++) { 1471 if (title.toLowerCase().indexOf( 1472 (Constants.HARDWARE.uppercase_titles[i] + ' ')) > -1) { 1473 return title.toUpperCase(); 1474 } 1475 } 1476 1477 return title; 1478 } 1479 1480 function camelcaseToLabel(obj) { 1481 var transformed = [], label = '', value = ''; 1482 for (var key in obj) { 1483 label = key.replace(/([A-Z0-9]+)/g, ' $1').replace(/^\s+/, ''); 1484 if (obj[key] !== '') { 1485 value = obj[key]; 1486 if (value == 1 || value == 0) { 1487 value = (value == 1) ? 'Yes' : 'No'; 1488 } 1489 transformed.push({key: label, value: value}); 1490 } 1491 } 1492 1493 return transformed; 1494 } 1495 1496 function determineParent(key) { 1497 var levels = key.split('/'); 1498 levels.pop(); 1499 return levels.join('/'); 1500 } 1501 1502 function getSearchText(data) { 1503 var searchText = ''; 1504 for (var i = 0; i < data.length; i++) { 1505 searchText += ' ' + data[i].key + ' ' + data[i].value; 1506 } 1507 1508 return searchText; 1509 } 1510 1511 for (var key in content.data) { 1512 if (content.data.hasOwnProperty(key) && 1513 key.indexOf(Constants.HARDWARE.component_key_filter) == 0) { 1514 // All and only associations have the property "endpoints". 1515 // We don't want to show forward/reverse association objects 1516 // that the mapper created on the inventory panel. 1517 // Example: An association from the BMC inventory item to the 1518 // BMC firmware images. See: 1519 // https://github.com/openbmc/docs/blob/master/object-mapper.md#associations 1520 if (content.data[key].hasOwnProperty('endpoints')) { 1521 continue; 1522 } 1523 // There is also an "Associations" property created by the 1524 // Association interface. These would show on the inventory 1525 // panel under the individual inventory item dropdown. There 1526 // can be a lot of associations in this property and they are 1527 // long, full D-Bus paths. Not particularly useful. Remove 1528 // for now. 1529 1530 if (content.data[key].hasOwnProperty('Associations')) { 1531 delete content.data[key].Associations; 1532 } 1533 1534 // Support old Associations interface property 1535 // https://github.com/openbmc/phosphor-logging/blob/master/org/openbmc/Associations.interface.yaml 1536 // Remove when we move to new Associations interface 1537 // openbmc/openbmc#3584 1538 if (content.data[key].hasOwnProperty('associations')) { 1539 delete content.data[key].associations; 1540 } 1541 1542 // Remove the Purpose property from any inventory item. 1543 // The purpose property isn't useful to a user. 1544 // E.g. in a Power Supply: 1545 // Purpose 1546 // xyz.openbmc_project.Software.Version.VersionPurpose.Other 1547 // Remove when we move inventory to Redfish 1548 if (content.data[key].hasOwnProperty('Purpose')) { 1549 delete content.data[key].Purpose; 1550 } 1551 1552 data = camelcaseToLabel(content.data[key]); 1553 searchText = getSearchText(data); 1554 title = key.split('/').pop(); 1555 title = titlelize(title); 1556 // e.g. /xyz/openbmc_project/inventory/system and 1557 // /xyz/openbmc_project/inventory/system/chassis are depths of 5 1558 // and 6. 1559 depth = key.split('/').length; 1560 parent = determineParent(key); 1561 1562 if (!isSubComponent(key)) { 1563 hardwareData.push(Object.assign( 1564 { 1565 path: key, 1566 title: title, 1567 depth: depth, 1568 parent: parent, 1569 selected: false, 1570 expanded: false, 1571 search_text: title.toLowerCase() + ' ' + 1572 searchText.toLowerCase(), 1573 sub_components: [], 1574 original_data: {key: key, value: content.data[key]} 1575 }, 1576 {items: data})); 1577 1578 1579 keyIndexMap[key] = hardwareData.length - 1; 1580 } else { 1581 parent = determineParent(key) 1582 componentIndex = keyIndexMap[parent]; 1583 data = content.data[key]; 1584 data.title = title; 1585 hardwareData[componentIndex].sub_components.push(data); 1586 hardwareData[componentIndex].search_text += 1587 ' ' + title.toLowerCase(); 1588 1589 // Sort the subcomponents alphanumeric so they are displayed 1590 // on the inventory page in order (e.g. core 0, core 1, core 1591 // 2, ... core 12, core 13) 1592 hardwareData[componentIndex].sub_components.sort(function( 1593 a, b) { 1594 return a.title.localeCompare( 1595 b.title, 'en', {numeric: true}); 1596 }); 1597 } 1598 } 1599 } 1600 // First, order the components by depth and then place the child 1601 // components beneath their parent component alphanumerically. Can 1602 // be removed with completion of 1603 // https://github.com/openbmc/openbmc/issues/3401 1604 // TODO: Remove this once implemented in back end 1605 hardwareData.sort(function(a, b) { 1606 if (a.depth < b.depth) return -1; 1607 if (a.depth > b.depth) return 1; 1608 return b.title.localeCompare(a.title, 'en', {numeric: true}); 1609 }); 1610 1611 var orderedComponents = []; 1612 1613 for (var i = 0; i < hardwareData.length; i++) { 1614 if (!keyIndexMap[hardwareData[i].parent]) { 1615 orderedComponents.push(hardwareData[i]); 1616 } else { 1617 for (var j = 0; j < orderedComponents.length; j++) { 1618 if (orderedComponents[j].path === hardwareData[i].parent) { 1619 var child = hardwareData[i]; 1620 orderedComponents.splice(j + 1, 0, child); 1621 } 1622 } 1623 } 1624 } 1625 1626 if (callback) { 1627 callback(orderedComponents, content.data); 1628 } else { 1629 return {data: orderedComponents, original_data: content.data}; 1630 } 1631 }); 1632 }, 1633 deleteLogs: function(logs) { 1634 var defer = $q.defer(); 1635 var promises = []; 1636 1637 function finished() { 1638 defer.resolve(); 1639 } 1640 1641 logs.forEach(function(item) { 1642 promises.push($http({ 1643 method: 'POST', 1644 url: DataService.getHost() + 1645 '/xyz/openbmc_project/logging/entry/' + item.Id + 1646 '/action/Delete', 1647 withCredentials: true, 1648 data: JSON.stringify({'data': []}) 1649 })); 1650 }); 1651 1652 $q.all(promises).then(finished); 1653 1654 return defer.promise; 1655 }, 1656 resolveLogs: function(logs) { 1657 var promises = []; 1658 1659 logs.forEach(function(item) { 1660 promises.push($http({ 1661 method: 'PUT', 1662 url: DataService.getHost() + 1663 '/xyz/openbmc_project/logging/entry/' + item.Id + 1664 '/attr/Resolved', 1665 withCredentials: true, 1666 data: JSON.stringify({'data': true}) 1667 })); 1668 }); 1669 return $q.all(promises); 1670 }, 1671 setRemoteLoggingServer: (data) => { 1672 const ip = data.hostname; 1673 const port = data.port; 1674 const setIPRequest = $http({ 1675 method: 'PUT', 1676 url: DataService.getHost() + 1677 '/xyz/openbmc_project/logging/config/remote/attr/Address', 1678 withCredentials: true, 1679 data: {'data': ip} 1680 }); 1681 const setPortRequest = $http({ 1682 method: 'PUT', 1683 url: DataService.getHost() + 1684 '/xyz/openbmc_project/logging/config/remote/attr/Port', 1685 withCredentials: true, 1686 data: {'data': port} 1687 }); 1688 const promises = [setIPRequest, setPortRequest]; 1689 return $q.all(promises); 1690 }, 1691 getRemoteLoggingServer: () => { 1692 return $http({ 1693 method: 'GET', 1694 url: DataService.getHost() + 1695 '/xyz/openbmc_project/logging/config/remote', 1696 withCredentials: true 1697 }) 1698 .then((response) => { 1699 const remoteServer = response.data.data; 1700 if (remoteServer === undefined) { 1701 return undefined; 1702 } 1703 const hostname = remoteServer.Address; 1704 const port = remoteServer.Port; 1705 if (hostname === '') { 1706 return undefined; 1707 } else { 1708 return { 1709 hostname, port 1710 } 1711 } 1712 }); 1713 }, 1714 disableRemoteLoggingServer: () => { 1715 return SERVICE.setRemoteLoggingServer({hostname: '', port: 0}); 1716 }, 1717 updateRemoteLoggingServer: (data) => { 1718 // Recommended to disable existing configuration 1719 // before updating config to new server 1720 // https://github.com/openbmc/phosphor-logging#changing-the-rsyslog-server 1721 return SERVICE.disableRemoteLoggingServer() 1722 .then(() => { 1723 return SERVICE.setRemoteLoggingServer(data); 1724 }) 1725 .catch(() => { 1726 // try updating server even if initial disable attempt fails 1727 return SERVICE.setRemoteLoggingServer(data); 1728 }); 1729 }, 1730 getPowerConsumption: function() { 1731 return $http({ 1732 method: 'GET', 1733 url: DataService.getHost() + 1734 '/xyz/openbmc_project/sensors/power/total_power', 1735 withCredentials: true 1736 }) 1737 .then( 1738 function(response) { 1739 var json = JSON.stringify(response.data); 1740 var content = JSON.parse(json); 1741 1742 return getScaledValue( 1743 content.data.Value, content.data.Scale) + 1744 ' ' + 1745 Constants.POWER_CONSUMPTION_TEXT[content.data.Unit]; 1746 }, 1747 function(error) { 1748 if ('Not Found' == error.statusText) { 1749 return Constants.POWER_CONSUMPTION_TEXT.notavailable; 1750 } else { 1751 throw error; 1752 } 1753 }); 1754 }, 1755 getPowerCap: function() { 1756 return $http({ 1757 method: 'GET', 1758 url: DataService.getHost() + 1759 '/xyz/openbmc_project/control/host0/power_cap', 1760 withCredentials: true 1761 }) 1762 .then(function(response) { 1763 return response.data; 1764 }); 1765 }, 1766 setPowerCapEnable: function(powerCapEnable) { 1767 return $http({ 1768 method: 'PUT', 1769 url: DataService.getHost() + 1770 '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCapEnable', 1771 withCredentials: true, 1772 data: JSON.stringify({'data': powerCapEnable}) 1773 }) 1774 .then(function(response) { 1775 return response.data; 1776 }); 1777 }, 1778 setPowerCap: function(powerCap) { 1779 return $http({ 1780 method: 'PUT', 1781 url: DataService.getHost() + 1782 '/xyz/openbmc_project/control/host0/power_cap/attr/PowerCap', 1783 withCredentials: true, 1784 data: JSON.stringify({'data': powerCap}) 1785 }) 1786 .then(function(response) { 1787 return response.data; 1788 }); 1789 }, 1790 setHostname: function(hostname) { 1791 return $http({ 1792 method: 'PUT', 1793 url: DataService.getHost() + 1794 '/xyz/openbmc_project/network/config/attr/HostName', 1795 withCredentials: true, 1796 data: JSON.stringify({'data': hostname}) 1797 }) 1798 .then(function(response) { 1799 return response.data; 1800 }); 1801 }, 1802 }; 1803 return SERVICE; 1804 } 1805 ]); 1806})(window.angular); 1807