1/** 2 * API utilities service 3 * 4 * @module app/common/services/api-utils 5 * @exports APIUtils 6 * @name APIUtils 7 * @version 0.0.1 8 */ 9 10window.angular && (function (angular) { 11 'use strict'; 12 angular 13 .module('app.common.services') 14 .factory('APIUtils', ['$http', 'Constants', '$q', function($http, Constants, $q){ 15 var SERVICE = { 16 LOGIN_CREDENTIALS: Constants.LOGIN_CREDENTIALS, 17 API_CREDENTIALS: Constants.API_CREDENTIALS, 18 API_RESPONSE: Constants.API_RESPONSE, 19 CHASSIS_POWER_STATE: Constants.CHASSIS_POWER_STATE, 20 HOST_STATE_TEXT: Constants.HOST_STATE, 21 HOST_STATE: Constants.HOST_STATE, 22 LED_STATE: Constants.LED_STATE, 23 LED_STATE_TEXT: Constants.LED_STATE_TEXT, 24 getChassisState: function(callback){ 25 $http({ 26 method: 'GET', 27 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/chassis0", 28 headers: { 29 'Accept': 'application/json', 30 'Content-Type': 'application/json' 31 }, 32 withCredentials: true 33 }).success(function(response){ 34 var json = JSON.stringify(response); 35 var content = JSON.parse(json); 36 callback(content.data.CurrentPowerState); 37 }).error(function(error){ 38 console.log(error); 39 }); 40 }, 41 getHostState: function(callback){ 42 $http({ 43 method: 'GET', 44 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", 45 headers: { 46 'Accept': 'application/json', 47 'Content-Type': 'application/json' 48 }, 49 withCredentials: true 50 }).success(function(response){ 51 var json = JSON.stringify(response); 52 var content = JSON.parse(json); 53 callback(content.data.CurrentHostState); 54 }).error(function(error){ 55 console.log(error); 56 }); 57 }, 58 getLEDState: function(callback){ 59 $http({ 60 method: 'GET', 61 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/led/groups/enclosure_identify", 62 headers: { 63 'Accept': 'application/json', 64 'Content-Type': 'application/json' 65 }, 66 withCredentials: true 67 }).success(function(response){ 68 var json = JSON.stringify(response); 69 var content = JSON.parse(json); 70 if(callback){ 71 callback(content.data.Asserted); 72 }else{ 73 return content.data.Asserted; 74 } 75 }).error(function(error){ 76 console.log(error); 77 }); 78 }, 79 login: function(username, password, callback){ 80 $http({ 81 method: 'POST', 82 url: SERVICE.API_CREDENTIALS.host + "/login", 83 headers: { 84 'Accept': 'application/json', 85 'Content-Type': 'application/json' 86 }, 87 withCredentials: true, 88 data: JSON.stringify({"data": [username, password]}) 89 }).success(function(response){ 90 if(callback){ 91 callback(response); 92 } 93 }).error(function(error){ 94 if(callback){ 95 if(error && error.status && error.status == 'error'){ 96 callback(error); 97 }else{ 98 callback(error, true); 99 } 100 } 101 console.log(error); 102 }); 103 }, 104 logout: function(callback){ 105 $http({ 106 method: 'POST', 107 url: SERVICE.API_CREDENTIALS.host + "/logout", 108 headers: { 109 'Accept': 'application/json', 110 'Content-Type': 'application/json' 111 }, 112 withCredentials: true, 113 data: JSON.stringify({"data": []}) 114 }).success(function(response){ 115 if(callback){ 116 callback(response); 117 } 118 }).error(function(error){ 119 if(callback){ 120 callback(null, error); 121 } 122 console.log(error); 123 }); 124 }, 125 chassisPowerOn: function(callback){ 126 $http({ 127 method: 'POST', 128 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", 129 headers: { 130 'Accept': 'application/json', 131 'Content-Type': 'application/json' 132 }, 133 withCredentials: true, 134 data: JSON.stringify({"data": []}) 135 }).success(function(response){ 136 var json = JSON.stringify(response); 137 var content = JSON.parse(json); 138 if(callback){ 139 return callback(content.data.CurrentPowerState); 140 } 141 }).error(function(error){ 142 if(callback){ 143 callback(error); 144 }else{ 145 console.log(error); 146 } 147 }); 148 }, 149 chassisPowerOff: function(callback){ 150 $http({ 151 method: 'POST', 152 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", 153 headers: { 154 'Accept': 'application/json', 155 'Content-Type': 'application/json' 156 }, 157 withCredentials: true, 158 data: JSON.stringify({"data": []}) 159 }).success(function(response){ 160 var json = JSON.stringify(response); 161 var content = JSON.parse(json); 162 if(callback){ 163 return callback(content.data.CurrentPowerState); 164 } 165 }).error(function(error){ 166 if(callback){ 167 callback(error); 168 }else{ 169 console.log(error); 170 } 171 }); 172 }, 173 setLEDState: function(state, callback){ 174 $http({ 175 method: 'PUT', 176 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted", 177 headers: { 178 'Accept': 'application/json', 179 'Content-Type': 'application/json' 180 }, 181 withCredentials: true, 182 data: JSON.stringify({"data": state}) 183 }).success(function(response){ 184 var json = JSON.stringify(response); 185 var content = JSON.parse(json); 186 if(callback){ 187 return callback(content.status); 188 } 189 }).error(function(error){ 190 if(callback){ 191 callback(error); 192 }else{ 193 console.log(error); 194 } 195 }); 196 }, 197 bmcReboot: function(callback){ 198 $http({ 199 method: 'PUT', 200 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/bmc0/attr/RequestedBmcTransition", 201 headers: { 202 'Accept': 'application/json', 203 'Content-Type': 'application/json' 204 }, 205 withCredentials: true, 206 data: JSON.stringify({"data": "xyz.openbmc_project.State.BMC.Transition.Reboot"}) 207 }).success(function(response){ 208 var json = JSON.stringify(response); 209 var content = JSON.parse(json); 210 if(callback){ 211 return callback(content.status); 212 } 213 }).error(function(error){ 214 if(callback){ 215 callback(error); 216 }else{ 217 console.log(error); 218 } 219 }); 220 }, 221 hostPowerOn: function(callback){ 222 $http({ 223 method: 'PUT', 224 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", 225 headers: { 226 'Accept': 'application/json', 227 'Content-Type': 'application/json' 228 }, 229 withCredentials: true, 230 data: JSON.stringify({"data": "xyz.openbmc_project.State.Host.Transition.On"}) 231 }).success(function(response){ 232 var json = JSON.stringify(response); 233 var content = JSON.parse(json); 234 if(callback){ 235 return callback(content.status); 236 } 237 }).error(function(error){ 238 if(callback){ 239 callback(error); 240 }else{ 241 console.log(error); 242 } 243 }); 244 }, 245 hostPowerOff: function(callback){ 246 $http({ 247 method: 'PUT', 248 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", 249 headers: { 250 'Accept': 'application/json', 251 'Content-Type': 'application/json' 252 }, 253 withCredentials: true, 254 data: JSON.stringify({"data": "xyz.openbmc_project.State.Host.Transition.Off"}) 255 }).success(function(response){ 256 var json = JSON.stringify(response); 257 var content = JSON.parse(json); 258 if(callback){ 259 return callback(content.status); 260 } 261 }).error(function(error){ 262 if(callback){ 263 callback(error); 264 }else{ 265 console.log(error); 266 } 267 }); 268 }, 269 hostReboot: function(callback){ 270 $http({ 271 method: 'POST', 272 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", 273 headers: { 274 'Accept': 'application/json', 275 'Content-Type': 'application/json' 276 }, 277 withCredentials: true, 278 data: JSON.stringify({"data": []}), 279 }).success(function(response){ 280 var json = JSON.stringify(response); 281 var content = JSON.parse(json); 282 if(callback){ 283 return callback(content); 284 } 285 }).error(function(error){ 286 if(callback){ 287 callback(error); 288 }else{ 289 console.log(error); 290 } 291 }); 292 }, 293 hostShutdown: function(callback){ 294 $http({ 295 method: 'POST', 296 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", 297 headers: { 298 'Accept': 'application/json', 299 'Content-Type': 'application/json' 300 }, 301 withCredentials: true, 302 data: JSON.stringify({"data": []}) 303 }).success(function(response){ 304 var json = JSON.stringify(response); 305 var content = JSON.parse(json); 306 if(callback){ 307 return callback(content); 308 } 309 }).error(function(error){ 310 if(callback){ 311 callback(error); 312 }else{ 313 console.log(error); 314 } 315 }); 316 }, 317 getLogs: function(callback){ 318 $http({ 319 method: 'GET', 320 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/logging/enumerate", 321 headers: { 322 'Accept': 'application/json', 323 'Content-Type': 'application/json' 324 }, 325 withCredentials: true 326 }).success(function(response){ 327 var json = JSON.stringify(response); 328 var content = JSON.parse(json); 329 var dataClone = JSON.parse(JSON.stringify(content.data)); 330 var data = []; 331 var severityCode = ''; 332 var priority = ''; 333 var relatedItems = []; 334 335 for(var key in content.data){ 336 if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Id')){ 337 var severityFlags = {low: false, medium: false, high: false}; 338 severityCode = content.data[key].Severity.split(".").pop(); 339 priority = Constants.SEVERITY_TO_PRIORITY_MAP[severityCode]; 340 severityFlags[priority.toLowerCase()] = true; 341 relatedItems = []; 342 content.data[key].associations.forEach(function(item){ 343 relatedItems.push(item[2]); 344 }); 345 346 data.push(Object.assign({ 347 path: key, 348 copied: false, 349 priority: priority, 350 severity_code: severityCode, 351 severity_flags: severityFlags, 352 additional_data: content.data[key].AdditionalData.join("\n"), 353 selected: false, 354 search_text: ("#" + content.data[key].Id + " " + severityCode + " " + content.data[key].Severity + " " + content.data[key].AdditionalData.join(" ")).toLowerCase(), 355 meta: false, 356 confirm: false, 357 related_items: relatedItems, 358 data: {key: key, value: content.data[key]} 359 }, content.data[key])); 360 } 361 } 362 if(callback){ 363 callback(data, dataClone); 364 }else{ 365 return data; 366 } 367 }).error(function(error){ 368 console.log(error); 369 }); 370 }, 371 getAllSensorStatus: function(callback){ 372 $http({ 373 method: 'GET', 374 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/sensors/enumerate", 375 headers: { 376 'Accept': 'application/json', 377 'Content-Type': 'application/json' 378 }, 379 withCredentials: true 380 }).success(function(response){ 381 var json = JSON.stringify(response); 382 var content = JSON.parse(json); 383 var dataClone = JSON.parse(JSON.stringify(content.data)); 384 var sensorData = []; 385 var severity = {}; 386 var title = ""; 387 var tempKeyParts = []; 388 var order = 0; 389 390 function getSensorStatus(reading){ 391 var severityFlags = {critical: false, warning: false, normal: false}, severityText = '', order = 0; 392 393 if(reading.hasOwnProperty('CriticalLow') && 394 reading.Value < reading.CriticalLow 395 ){ 396 severityFlags.critical = true; 397 severityText = 'critical'; 398 order = 2; 399 }else if(reading.hasOwnProperty('CriticalHigh') && 400 reading.Value > reading.CriticalHigh 401 ){ 402 severityFlags.critical = true; 403 severityText = 'critical'; 404 order = 2; 405 }else if(reading.hasOwnProperty('CriticalLow') && 406 reading.hasOwnProperty('WarningLow') && 407 reading.Value >= reading.CriticalLow && reading.Value <= reading.WarningLow){ 408 severityFlags.warning = true; 409 severityText = 'warning'; 410 order = 1; 411 }else if(reading.hasOwnProperty('WarningHigh') && 412 reading.hasOwnProperty('CriticalHigh') && 413 reading.Value >= reading.WarningHigh && reading.Value <= reading.CriticalHigh){ 414 severityFlags.warning = true; 415 severityText = 'warning'; 416 order = 1; 417 }else{ 418 severityFlags.normal = true; 419 severityText = 'normal'; 420 } 421 return { flags: severityFlags, severityText: severityText, order: order}; 422 } 423 424 for(var key in content.data){ 425 if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Unit')){ 426 427 severity = getSensorStatus(content.data[key]); 428 429 if(!content.data[key].hasOwnProperty('CriticalLow')){ 430 content.data[key].CriticalLow = "--"; 431 content.data[key].CriticalHigh = "--"; 432 } 433 434 if(!content.data[key].hasOwnProperty('WarningLow')){ 435 content.data[key].WarningLow = "--"; 436 content.data[key].WarningHigh = "--"; 437 } 438 439 tempKeyParts = key.split("/"); 440 title = tempKeyParts.pop(); 441 title = tempKeyParts.pop() + '_' + title; 442 title = title.split("_").map(function(item){ 443 return item.toLowerCase().charAt(0).toUpperCase() + item.slice(1); 444 }).reduce(function(prev, el){ 445 return prev + " " + el; 446 }); 447 448 sensorData.push(Object.assign({ 449 path: key, 450 selected: false, 451 confirm: false, 452 copied: false, 453 title: title, 454 unit: Constants.SENSOR_UNIT_MAP[content.data[key].Unit], 455 severity_flags: severity.flags, 456 status: severity.severityText, 457 order: severity.order, 458 search_text: (title + " " + content.data[key].Value + " " + 459 Constants.SENSOR_UNIT_MAP[content.data[key].Unit] + " " + 460 severity.severityText + " " + 461 content.data[key].CriticalLow + " " + 462 content.data[key].CriticalHigh + " " + 463 content.data[key].WarningLow + " " + 464 content.data[key].WarningHigh + " " 465 ).toLowerCase(), 466 original_data: {key: key, value: content.data[key]} 467 }, content.data[key])); 468 } 469 } 470 471 callback(sensorData, dataClone); 472 }).error(function(error){ 473 console.log(error); 474 }); 475 }, 476 getFirmwares: function(callback){ 477 $http({ 478 method: 'GET', 479 //url: SERVICE.API_CREDENTIALS.mock_host + "/software", 480 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/software/enumerate", 481 headers: { 482 'Accept': 'application/json', 483 'Content-Type': 'application/json' 484 }, 485 withCredentials: true 486 }).success(function(response){ 487 var json = JSON.stringify(response); 488 var content = JSON.parse(json); 489 var data = []; 490 var active = false; 491 var isExtended = false; 492 var bmcActiveVersion = ""; 493 var hostActiveVersion = ""; 494 var imageType = ""; 495 var extendedVersions = []; 496 497 function getFormatedExtendedVersions(extendedVersion){ 498 var versions = []; 499 extendedVersion = extendedVersion.split(","); 500 501 extendedVersion.forEach(function(item){ 502 var parts = item.split("-"); 503 var numberIndex = 0; 504 for(var i = 0; i < parts.length; i++){ 505 if(/[0-9]/.test(parts[i])){ 506 numberIndex = i; 507 break; 508 } 509 } 510 var titlePart = parts.splice(0, numberIndex); 511 titlePart = titlePart.join(""); 512 titlePart = titlePart[0].toUpperCase() + titlePart.substr(1, titlePart.length); 513 var versionPart = parts.join("-"); 514 versions.push({ 515 title: titlePart, 516 version: versionPart 517 }); 518 }); 519 520 return versions; 521 } 522 523 for(var key in content.data){ 524 if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Version')){ 525 active = (/\.Active$/).test(content.data[key].Activation); 526 imageType = content.data[key].Purpose.split(".").pop(); 527 isExtended = content.data[key].hasOwnProperty('ExtendedVersion') && content.data[key].ExtendedVersion != ""; 528 if(isExtended){ 529 extendedVersions = getFormatedExtendedVersions(content.data[key].ExtendedVersion); 530 } 531 data.push(Object.assign({ 532 path: key, 533 active: active, 534 imageId: key.split("/").pop(), 535 imageType: imageType, 536 isExtended: isExtended, 537 extended: { 538 show: false, 539 versions: extendedVersions 540 }, 541 data: {key: key, value: content.data[key]} 542 }, content.data[key])); 543 544 if(active && imageType == 'BMC'){ 545 bmcActiveVersion = content.data[key].Version; 546 } 547 548 if(active && imageType == 'Host'){ 549 hostActiveVersion = content.data[key].Version; 550 } 551 } 552 } 553 if(callback){ 554 callback(data, bmcActiveVersion, hostActiveVersion); 555 }else{ 556 return(data, bmcActiveVersion, hostActiveVersion); 557 } 558 }).error(function(error){ 559 console.log(error); 560 }); 561 }, 562 uploadImage: function(file, callback){ 563 $http({ 564 method: 'PUT', 565 timeout: 5 * 60 * 1000, 566 //url: 'http://localhost:3002/upload', 567 url: SERVICE.API_CREDENTIALS.host + "/upload/image/", 568 headers: { 569 'Accept': 'application/octet-stream', 570 'Content-Type': 'application/octet-stream' 571 }, 572 withCredentials: true, 573 data: file 574 }).success(function(response){ 575 var json = JSON.stringify(response); 576 var content = JSON.parse(json); 577 if(callback){ 578 return callback(content); 579 } 580 }).error(function(error){ 581 if(callback){ 582 callback(error); 583 }else{ 584 console.log(error); 585 } 586 }); 587 }, 588 getBMCEthernetInfo: function(callback){ 589 $http({ 590 method: 'GET', 591 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc/ethernet", 592 headers: { 593 'Accept': 'application/json', 594 'Content-Type': 'application/json' 595 }, 596 withCredentials: true 597 }).success(function(response){ 598 var json = JSON.stringify(response); 599 var content = JSON.parse(json); 600 if(callback){ 601 callback(content.data); 602 }else{ 603 return content.data; 604 } 605 }).error(function(error){ 606 console.log(error); 607 }); 608 }, 609 getBMCInfo: function(callback){ 610 $http({ 611 method: 'GET', 612 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc", 613 headers: { 614 'Accept': 'application/json', 615 'Content-Type': 'application/json' 616 }, 617 withCredentials: true 618 }).success(function(response){ 619 var json = JSON.stringify(response); 620 var content = JSON.parse(json); 621 if(callback){ 622 callback(content.data); 623 }else{ 624 return content.data; 625 } 626 }).error(function(error){ 627 console.log(error); 628 }); 629 }, 630 getHardwares: function(callback){ 631 $http({ 632 method: 'GET', 633 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/inventory/enumerate", 634 headers: { 635 'Accept': 'application/json', 636 'Content-Type': 'application/json' 637 }, 638 withCredentials: true 639 }).success(function(response){ 640 var json = JSON.stringify(response); 641 var content = JSON.parse(json); 642 var hardwareData = []; 643 var keyIndexMap = {}; 644 var title = ""; 645 var data = []; 646 var searchText = ""; 647 var componentIndex = -1; 648 var tempParts = []; 649 650 651 function isSubComponent(key){ 652 653 for(var i = 0; i < Constants.HARDWARE.parent_components.length; i++){ 654 if(key.split(Constants.HARDWARE.parent_components[i]).length == 2) return true; 655 } 656 657 return false; 658 } 659 660 function titlelize(title){ 661 title = title.replace(/([A-Z0-9]+)/g, " $1").replace(/^\s+/, ""); 662 for(var i = 0; i < Constants.HARDWARE.uppercase_titles.length; i++){ 663 if(title.toLowerCase().indexOf((Constants.HARDWARE.uppercase_titles[i] + " ")) > -1){ 664 return title.toUpperCase(); 665 } 666 } 667 668 return title; 669 } 670 671 function camelcaseToLabel(obj){ 672 var transformed = [], label = "", value = ""; 673 for(var key in obj){ 674 label = key.replace(/([A-Z0-9]+)/g, " $1").replace(/^\s+/, ""); 675 if(obj[key] !== ""){ 676 value = obj[key]; 677 if(value == 1 || value == 0){ 678 value = (value == 1) ? 'Yes' : 'No'; 679 } 680 transformed.push({key:label, value: value}); 681 } 682 } 683 684 return transformed; 685 } 686 687 function getSearchText(data){ 688 var searchText = ""; 689 for(var i = 0; i < data.length; i++){ 690 searchText += " " + data[i].key + " " + data[i].value; 691 } 692 693 return searchText; 694 } 695 696 for(var key in content.data){ 697 if(content.data.hasOwnProperty(key) && 698 key.indexOf(Constants.HARDWARE.component_key_filter) == 0){ 699 700 data = camelcaseToLabel(content.data[key]); 701 searchText = getSearchText(data); 702 title = key.split("/").pop(); 703 704 title = titlelize(title); 705 706 if(!isSubComponent(key)){ 707 hardwareData.push(Object.assign({ 708 path: key, 709 title: title, 710 selected: false, 711 expanded: false, 712 search_text: title.toLowerCase() + " " + searchText.toLowerCase(), 713 sub_components: [], 714 original_data: {key: key, value: content.data[key]} 715 }, {items: data})); 716 717 keyIndexMap[key] = hardwareData.length - 1; 718 }else{ 719 var tempParts = key.split("/"); 720 tempParts.pop(); 721 tempParts = tempParts.join("/"); 722 componentIndex = keyIndexMap[tempParts]; 723 data = content.data[key]; 724 data.title = title; 725 hardwareData[componentIndex].sub_components.push(data); 726 hardwareData[componentIndex].search_text += " " + title.toLowerCase(); 727 } 728 } 729 } 730 731 if(callback){ 732 callback(hardwareData, content.data); 733 }else{ 734 return { data: hardwareData, original_data: content.data}; 735 } 736 }); 737 }, 738 deleteLogs: function(logs) { 739 var defer = $q.defer(); 740 var promises = []; 741 742 function finished(){ 743 defer.resolve(); 744 } 745 746 logs.forEach(function(item){ 747 promises.push($http({ 748 method: 'POST', 749 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/logging/entry/"+item.Id+"/action/Delete", 750 headers: { 751 'Accept': 'application/json', 752 'Content-Type': 'application/json' 753 }, 754 withCredentials: true, 755 data: JSON.stringify({"data": []}) 756 })); 757 }); 758 759 $q.all(promises).then(finished); 760 761 return defer.promise; 762 }, 763 resolveLogs: function(logs) { 764 var defer = $q.defer(); 765 var promises = []; 766 767 function finished(){ 768 defer.resolve(); 769 } 770 771 logs.forEach(function(item){ 772 promises.push($http({ 773 method: 'PUT', 774 url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/logging/entry/"+item.Id+"/attr/Resolved", 775 headers: { 776 'Accept': 'application/json', 777 'Content-Type': 'application/json' 778 }, 779 withCredentials: true, 780 data: JSON.stringify({"data": "1"}) 781 })); 782 }); 783 784 $q.all(promises).then(finished); 785 786 return defer.promise; 787 }, 788 }; 789 return SERVICE; 790 }]); 791 792 })(window.angular); 793