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