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