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