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