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