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