diff options
-rw-r--r-- | app/common/directives/app-header.html | 4 | ||||
-rw-r--r-- | app/common/directives/app-navigation.html | 4 | ||||
-rw-r--r-- | app/common/directives/firmware-list.html | 19 | ||||
-rw-r--r-- | app/common/directives/firmware-list.js | 4 | ||||
-rw-r--r-- | app/common/services/api-utils.js | 127 | ||||
-rw-r--r-- | app/common/services/constants.js | 14 | ||||
-rw-r--r-- | app/common/services/dataService.js | 30 | ||||
-rw-r--r-- | app/common/services/userModel.js | 1 | ||||
-rw-r--r-- | app/configuration/controllers/firmware-controller.html | 24 | ||||
-rw-r--r-- | app/configuration/controllers/firmware-controller.js | 72 | ||||
-rw-r--r-- | app/login/controllers/login-controller.html | 16 | ||||
-rw-r--r-- | app/login/controllers/login-controller.js | 12 |
12 files changed, 257 insertions, 70 deletions
diff --git a/app/common/directives/app-header.html b/app/common/directives/app-header.html index 9388bb6..0ba8607 100644 --- a/app/common/directives/app-header.html +++ b/app/common/directives/app-header.html @@ -6,9 +6,9 @@ </header> <div class="header__functions-wrapper" role="heading"> <div class="logo__wrapper"><img src="assets/images/logo.svg" class="header__logo" alt="company logo"/></div> - <button class="inline header__multi-server" aria-label="multi server select" ng-class="{'active': multi_server_recent}" ng-click="multiRecent();"> + <!-- <button class="inline header__multi-server" aria-label="multi server select" ng-class="{'active': multi_server_recent}" ng-click="multiRecent();"> <span class="icon icon-angle" aria-hidden="true"></span><span class="accessible-text">Multi server switcher</span> - </button> + </button>--> <div class="inline header__server-name"> <p class="header__hostname">{{dataService.hostname}}</p> <p class="header__server-ip courier-bold">BMC IP address {{dataService.server_id}}</p> diff --git a/app/common/directives/app-navigation.html b/app/common/directives/app-navigation.html index 4e75a0d..3213345 100644 --- a/app/common/directives/app-navigation.html +++ b/app/common/directives/app-navigation.html @@ -64,7 +64,7 @@ <span>Users</span> </button> </li> - <li class="btn-multi-server"> + <!--<li class="btn-multi-server"> <a ng-class="{opened: firstLevel == 'multi-server'}" href="#/multi-server/overview" ng-click="change('multi-server')" tabindex="6"> <span> <svg class="nav-icon" version="1.1" xmlns="http://www.w3.org/2000/svg" x="0px" y="0px" viewBox="0 0 24 24" xml:space="preserve"> @@ -75,7 +75,7 @@ s4.7,2.1,4.7,4.7s-2.1,4.7-4.7,4.7S2.2,9.5,2.2,6.9z"/> </svg> All Servers</span></a> - </li> + </li> --> </ul> <ul class="nav__second-level btn-health" ng-style="navStyle" ng-class="{opened: (showSubMenu && firstLevel == 'server-health')}"> <li ng-class="{'active': (path == '/server-health/event-log')}"> diff --git a/app/common/directives/firmware-list.html b/app/common/directives/firmware-list.html index 2f1d3fc..c53a417 100644 --- a/app/common/directives/firmware-list.html +++ b/app/common/directives/firmware-list.html @@ -21,16 +21,23 @@ </div> </div> <div class="table__body"> - <div class="table__row" ng-class="firmware.active ? 'firmware__primary' : ''" ng-repeat="firmware in firmwares|filter:filterBy"> + <div class="table__row" ng-class="firmware.functional ? 'firmware__primary' : ''" ng-repeat="firmware in firmwares|filter:filterBy|orderBy:'+Priority'"> <div class="table__cell"> <span class="table__cell-label">Boot priority:</span> - <div class="icon icon__up-arrow icon-as-spacer" aria-hidden="true"> + <div class="icon icon__up-arrow" aria-hidden="true" ng-class="{'icon-as-spacer':$first}" + ng-click="!$first && changePriority(firmware.imageId, firmware.Priority, firmware.Priority - 1)" + ng-show="firmware.activationFlags.functional || firmware.activationFlags.ready"> <span class="accessible-text">firmware up in priority</span></div> - <div class="icon icon__down-arrow" aria-hidden="true"> + <div class="icon icon__down-arrow" aria-hidden="true" ng-class="{'icon-as-spacer':$last}" + ng-click="!$last && changePriority(firmware.imageId, firmware.Priority, firmware.Priority + 1)" + ng-hide="firmware.activationFlags.ready"> <span class="accessible-text">firmware down in priority</span></div> </div> <div class="table__cell firmware__active"> - <span class="table__cell-label">Image state:</span><span ng-if="firmware.active">Active</span> + <span class="table__cell-label">Image state:</span> + <span ng-if="firmware.activationFlags.functional">Functional</span> + <span ng-if="firmware.activationFlags.active">Active</span> + <span ng-if="firmware.activationFlags.ready">Ready</span> </div> <div class="table__cell firmware__version" ng-class="{'active':firmware.isExtended}"> <span class="table__cell-label">Version:</span>{{firmware.Version}} @@ -52,8 +59,8 @@ </div> <div class="table__cell"> <span class="table__cell-label">Action:</span> - <button class="firmware__action-link" ng-show="!firmware.active" ng-click="activate(firmware.imageId)">Activate</button> - <button class="firmware__action-link" ng-show="!firmware.active" ng-click="delete(firmware.imageId)">Delete</button> + <button class="firmware__action-link" ng-show="firmware.activationFlags.ready" ng-click="activate(firmware.imageId)">Activate</button> + <button class="firmware__action-link" ng-show="!firmware.functional" ng-click="delete(firmware.imageId)">Delete</button> </div> </div> </div> diff --git a/app/common/directives/firmware-list.js b/app/common/directives/firmware-list.js index f4cc94f..6cfa3a1 100644 --- a/app/common/directives/firmware-list.js +++ b/app/common/directives/firmware-list.js @@ -22,6 +22,10 @@ window.angular && (function (angular) { $scope.delete = function(imageId){ $scope.$parent.deleteImage(imageId); } + + $scope.changePriority = function(imageId, from, to){ + $scope.$parent.changePriority(imageId, from, to); + } }] }; }]); diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js index 46caf90..c17577c 100644 --- a/app/common/services/api-utils.js +++ b/app/common/services/api-utils.js @@ -11,7 +11,7 @@ window.angular && (function (angular) { 'use strict'; angular .module('app.common.services') - .factory('APIUtils', ['$http', 'Constants', '$q', function($http, Constants, $q){ + .factory('APIUtils', ['$http', 'Constants', '$q', 'dataService',function($http, Constants, $q, DataService){ var SERVICE = { LOGIN_CREDENTIALS: Constants.LOGIN_CREDENTIALS, API_CREDENTIALS: Constants.API_CREDENTIALS, @@ -21,10 +21,11 @@ window.angular && (function (angular) { HOST_STATE: Constants.HOST_STATE, LED_STATE: Constants.LED_STATE, LED_STATE_TEXT: Constants.LED_STATE_TEXT, + HOST_SESSION_STORAGE_KEY: Constants.API_CREDENTIALS.host_storage_key, getChassisState: function(callback){ $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/chassis0", + url: DataService.getHost() + "/xyz/openbmc_project/state/chassis0", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -41,7 +42,7 @@ window.angular && (function (angular) { getHostState: function(callback){ $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", + url: DataService.getHost() + "/xyz/openbmc_project/state/host0", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -59,7 +60,7 @@ window.angular && (function (angular) { var deferred = $q.defer(); $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/network/enumerate", + url: DataService.getHost() + "/xyz/openbmc_project/network/enumerate", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -98,7 +99,7 @@ window.angular && (function (angular) { var deferred = $q.defer(); $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/led/groups/enclosure_identify", + url: DataService.getHost() + "/xyz/openbmc_project/led/groups/enclosure_identify", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -117,7 +118,7 @@ window.angular && (function (angular) { login: function(username, password, callback){ $http({ method: 'POST', - url: SERVICE.API_CREDENTIALS.host + "/login", + url: DataService.getHost() + "/login", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -142,7 +143,7 @@ window.angular && (function (angular) { logout: function(callback){ $http({ method: 'POST', - url: SERVICE.API_CREDENTIALS.host + "/logout", + url: DataService.getHost() + "/logout", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -163,7 +164,7 @@ window.angular && (function (angular) { chassisPowerOn: function(callback){ $http({ method: 'POST', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", + url: DataService.getHost() + "/xyz/openbmc_project/state/host0", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -187,7 +188,7 @@ window.angular && (function (angular) { chassisPowerOff: function(callback){ $http({ method: 'POST', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", + url: DataService.getHost() + "/xyz/openbmc_project/state/host0", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -211,7 +212,7 @@ window.angular && (function (angular) { setLEDState: function(state, callback){ $http({ method: 'PUT', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted", + url: DataService.getHost() + "/xyz/openbmc_project/led/groups/enclosure_identify/attr/Asserted", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -235,7 +236,7 @@ window.angular && (function (angular) { bmcReboot: function(callback){ $http({ method: 'PUT', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/bmc0/attr/RequestedBmcTransition", + url: DataService.getHost() + "/xyz/openbmc_project/state/bmc0/attr/RequestedBmcTransition", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -259,7 +260,7 @@ window.angular && (function (angular) { hostPowerOn: function(callback){ $http({ method: 'PUT', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", + url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -283,7 +284,7 @@ window.angular && (function (angular) { hostPowerOff: function(callback){ $http({ method: 'PUT', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", + url: DataService.getHost() + "/xyz/openbmc_project/state/host0/attr/RequestedHostTransition", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -307,7 +308,7 @@ window.angular && (function (angular) { hostReboot: function(callback){ $http({ method: 'POST', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", + url: DataService.getHost() + "/xyz/openbmc_project/state/host0", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -331,7 +332,7 @@ window.angular && (function (angular) { hostShutdown: function(callback){ $http({ method: 'POST', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/state/host0", + url: DataService.getHost() + "/xyz/openbmc_project/state/host0", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -356,7 +357,7 @@ window.angular && (function (angular) { var deferred = $q.defer(); $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/logging/enumerate", + url: DataService.getHost() + "/xyz/openbmc_project/logging/enumerate", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -414,7 +415,7 @@ window.angular && (function (angular) { getAllSensorStatus: function(callback){ $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/sensors/enumerate", + url: DataService.getHost() + "/xyz/openbmc_project/sensors/enumerate", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -543,7 +544,7 @@ window.angular && (function (angular) { var deferred = $q.defer(); $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/software/enumerate", + url: DataService.getHost() + "/xyz/openbmc_project/software/enumerate", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -554,6 +555,9 @@ window.angular && (function (angular) { var content = JSON.parse(json); var data = []; var active = false; + var functional = false; + var ready = false; + var activationStatus = {active: false, ready: false, functional: false}; var isExtended = false; var bmcActiveVersion = ""; var hostActiveVersion = ""; @@ -588,7 +592,11 @@ window.angular && (function (angular) { for(var key in content.data){ if(content.data.hasOwnProperty(key) && content.data[key].hasOwnProperty('Version')){ + + functional = (content.data[key].Priority == 0); active = (/\.Active$/).test(content.data[key].Activation); + ready = (/\.Ready$/).test(content.data[key].Activation); + activationStatus = {functional: functional, active: active, ready: ready}; imageType = content.data[key].Purpose.split(".").pop(); isExtended = content.data[key].hasOwnProperty('ExtendedVersion') && content.data[key].ExtendedVersion != ""; if(isExtended){ @@ -596,7 +604,8 @@ window.angular && (function (angular) { } data.push(Object.assign({ path: key, - active: active, + functional: functional, + activationFlags: activationStatus, imageId: key.split("/").pop(), imageType: imageType, isExtended: isExtended, @@ -607,11 +616,11 @@ window.angular && (function (angular) { data: {key: key, value: content.data[key]} }, content.data[key])); - if(active && imageType == 'BMC'){ + if(functional && imageType == 'BMC'){ bmcActiveVersion = content.data[key].Version; } - if(active && imageType == 'Host'){ + if(functional && imageType == 'Host'){ hostActiveVersion = content.data[key].Version; } } @@ -629,12 +638,34 @@ window.angular && (function (angular) { return deferred.promise; }, - uploadImage: function(file, callback){ + changePriority: function(imageId, priority){ + var deferred = $q.defer(); + $http({ + method: 'PUT', + url: DataService.getHost() + "/xyz/openbmc_project/software/" + imageId + "/attr/Priority", + headers: { + 'Accept': 'application/octet-stream', + 'Content-Type': 'application/octet-stream' + }, + withCredentials: true, + data: JSON.stringify({"data": priority}) + }).success(function(response){ + var json = JSON.stringify(response); + var content = JSON.parse(json); + deferred.resolve(content); + }).error(function(error){ + console.log(error); + deferred.reject(error); + }); + + return deferred.promise; + }, + uploadImage: function(file){ + var deferred = $q.defer(); $http({ method: 'PUT', timeout: 5 * 60 * 1000, - //url: 'http://localhost:3002/upload', - url: SERVICE.API_CREDENTIALS.host + "/upload/image/", + url: DataService.getHost() + "/upload/image/", headers: { 'Accept': 'application/octet-stream', 'Content-Type': 'application/octet-stream' @@ -644,22 +675,44 @@ window.angular && (function (angular) { }).success(function(response){ var json = JSON.stringify(response); var content = JSON.parse(json); - if(callback){ - return callback(content); - } + deferred.resolve(content); }).error(function(error){ - if(callback){ - callback(error); - }else{ - console.log(error); - } + console.log(error); + deferred.reject(error); + }); + + return deferred.promise; + }, + downloadImage: function(host, filename){ + var deferred = $q.defer(); + $http({ + method: 'POST', + url: DataService.getHost() + "/org/openbmc/control/flash/bmc/action/updateViaTftp", + headers: { + 'Accept': 'application/json', + 'Content-Type': 'application/json' + }, + withCredentials: true, + data: JSON.stringify({"data": [host, filename]}), + responseType: 'arraybuffer' + }).success(function(response, status, headers){ + deferred.resolve({ + data: response, + status: status, + headers: headers + }); + }).error(function(error){ + console.log(error); + deferred.reject(error); }); + + return deferred.promise; }, getBMCEthernetInfo: function(){ var deferred = $q.defer(); $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc/ethernet", + url: DataService.getHost() + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc/ethernet", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -680,7 +733,7 @@ window.angular && (function (angular) { var deferred = $q.defer(); $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc", + url: DataService.getHost() + "/xyz/openbmc_project/inventory/system/chassis/motherboard/boxelder/bmc", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -699,7 +752,7 @@ window.angular && (function (angular) { getHardwares: function(callback){ $http({ method: 'GET', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/inventory/enumerate", + url: DataService.getHost() + "/xyz/openbmc_project/inventory/enumerate", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -815,7 +868,7 @@ window.angular && (function (angular) { logs.forEach(function(item){ promises.push($http({ method: 'POST', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/logging/entry/"+item.Id+"/action/Delete", + url: DataService.getHost() + "/xyz/openbmc_project/logging/entry/"+item.Id+"/action/Delete", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' @@ -840,7 +893,7 @@ window.angular && (function (angular) { logs.forEach(function(item){ promises.push($http({ method: 'PUT', - url: SERVICE.API_CREDENTIALS.host + "/xyz/openbmc_project/logging/entry/"+item.Id+"/attr/Resolved", + url: DataService.getHost() + "/xyz/openbmc_project/logging/entry/"+item.Id+"/attr/Resolved", headers: { 'Accept': 'application/json', 'Content-Type': 'application/json' diff --git a/app/common/services/constants.js b/app/common/services/constants.js index 2c48822..4852954 100644 --- a/app/common/services/constants.js +++ b/app/common/services/constants.js @@ -20,8 +20,8 @@ window.angular && (function (angular) { password: "testpass", }, API_CREDENTIALS: { - host: 'https://9.3.181.64', - mock_host: 'http://localhost:3000' + host_storage_key: 'API_HOST_KEY', + default_protocol: 'https' }, API_RESPONSE: { ERROR_STATUS: 'error', @@ -109,7 +109,15 @@ window.angular && (function (angular) { 'xyz.openbmc_project.Sensor.Value.Unit.Joules', 'xyz.openbmc_project.Sensor.Value.Unit.Meters' ], - SENSOR_SORT_ORDER_DEFAULT: 8 + SENSOR_SORT_ORDER_DEFAULT: 8, + FIRMWARE: { + FALLBACK_DOWNLOAD_FILENAME: 'firmware_download.tar', + TYPES: { + Functional: 'Functional', + Active: 'Active', + Ready: 'Ready' + } + } }; }); diff --git a/app/common/services/dataService.js b/app/common/services/dataService.js index 00ea1ba..51e67bf 100644 --- a/app/common/services/dataService.js +++ b/app/common/services/dataService.js @@ -20,7 +20,6 @@ window.angular && (function (angular) { this.server_status = -2; this.chassis_state = 'On'; this.LED_state = Constants.LED_STATE_TEXT.off; - this.server_id = Constants.API_CREDENTIALS.host.replace(/[^\d]+/m,""); this.last_updated = new Date(); this.loading = false; @@ -35,6 +34,35 @@ window.angular && (function (angular) { this.mac_address = ""; this.remote_window_active = false; + this.getServerId = function(){ + return this.host.replace(/[^\d]+/m,""); + } + + this.reloadServerId = function(){ + this.server_id = this.getServerId(); + } + + this.getHost = function(){ + if(sessionStorage.getItem(Constants.API_CREDENTIALS.host_storage_key) !== null){ + return sessionStorage.getItem(Constants.API_CREDENTIALS.host_storage_key); + }else{ + return Constants.API_CREDENTIALS.default_protocol + "://" + + window.location.hostname + ':' + + window.location.port; + } + } + + this.setHost = function(hostWithPort){ + hostWithPort = hostWithPort.replace(/^https?\:\/\//ig, ''); + var hostURL = Constants.API_CREDENTIALS.default_protocol + "://" + hostWithPort; + sessionStorage.setItem(Constants.API_CREDENTIALS.host_storage_key, hostURL); + this.host = hostURL; + this.reloadServerId(); + } + + this.host = this.getHost(); + this.server_id = this.getServerId(); + this.setNetworkInfo = function(data){ this.hostname = data.hostname; this.mac_address = data.mac_address; diff --git a/app/common/services/userModel.js b/app/common/services/userModel.js index 747b288..a3fc277 100644 --- a/app/common/services/userModel.js +++ b/app/common/services/userModel.js @@ -40,6 +40,7 @@ window.angular && (function (angular) { if(response && response.status == APIUtils.API_RESPONSE.SUCCESS_STATUS){ sessionStorage.removeItem('LOGIN_ID'); + sessionStorage.removeItem(APIUtils.HOST_SESSION_STORAGE_KEY); callback(true); }else if(response.status == APIUtils.API_RESPONSE.ERROR_STATUS){ callback(false); diff --git a/app/configuration/controllers/firmware-controller.html b/app/configuration/controllers/firmware-controller.html index 1f67caa..c305047 100644 --- a/app/configuration/controllers/firmware-controller.html +++ b/app/configuration/controllers/firmware-controller.html @@ -1,3 +1,4 @@ +<loader loading="loading"></loader> <div class="row column"> <h1>Firmware</h1> <div class="column small-12 page-header"> @@ -34,14 +35,14 @@ <div class="row"> <div class="column small-12 large-4"> <label for="tftp-ip">TFTP Server IP address</label> - <input name="tftp-ip" id="tftp-ip" type="number"/> + <input name="tftp-ip" id="tftp-ip" type="text" ng-model="download_host"/> </div> <div class="column small-12 large-4"> <label for="tftp-file-name">File name</label> - <input name="tftp-file-name" id="tftp-file-name" type="text"/> + <input name="tftp-file-name" id="tftp-file-name" type="text" ng-model="download_filename"/> </div> <div class="column small-12 large-4"> - <input type="submit" value="Download firmware" class="inline button btn-primary float-right"/> + <input type="button" value="Download firmware" class="inline button btn-primary float-right" ng-click="download()"/> </div> </div> <div class="inline uploading" ng-show="downloading">Downloading in progress...</div> @@ -67,6 +68,23 @@ </div> </section> +<section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': confirm_priority}"> + <div class="modal__tftp-unreachable" role="document"> + <div class="screen-reader-offscreen modal-description">Update image priority</div><!-- accessibility only; used for screen readers --> + <div class="page-header "> + <span class="icon icon__warning inline"><span class="accessible-text" role="alert">Warning</span></span> + <h1 class="modal-title h4 inline">Change image priority</h1> + </div> + <div class="modal__content"> + <p>Change firmware {{priority_image_id}} priority?</p> + </div> + <div class="modal__button-wrapper"> + <button class="inline btn-secondary" ng-click="confirm_priority=false;">Cancel</button> + <button class="inline btn-primary" ng-click="confirmChangePriority()">Continue</button> + </div> + </div> +</section> + <section class="modal" aria-hidden="true" aria-labelledby="modalTitle" aria-describedby="modalDescription" role="dialog" ng-class="{'active': confirm_delete}"> <div class="modal__tftp-unreachable" role="document"> <div class="screen-reader-offscreen modal-description">Delete firmware image</div><!-- accessibility only; used for screen readers --> diff --git a/app/configuration/controllers/firmware-controller.js b/app/configuration/controllers/firmware-controller.js index 66c4297..50df4f0 100644 --- a/app/configuration/controllers/firmware-controller.js +++ b/app/configuration/controllers/firmware-controller.js @@ -19,7 +19,8 @@ window.angular && (function (angular) { 'dataService', '$location', '$anchorScroll', - function ($scope, $window, APIUtils, dataService, $location, $anchorScroll) { + 'Constants', + function ($scope, $window, APIUtils, dataService, $location, $anchorScroll, Constants) { $scope.dataService = dataService; //Scroll to target anchor @@ -37,6 +38,10 @@ window.angular && (function (angular) { $scope.preserve_settings_confirm = false; $scope.delete_image_id = ""; $scope.activate_image_id = ""; + $scope.priority_image_id = ""; + $scope.priority_from = -1; + $scope.priority_to = -1; + $scope.confirm_priority = false; $scope.file_empty = true; $scope.uploading = false; @@ -73,7 +78,7 @@ window.angular && (function (angular) { } $scope.confirmUpload = function(){ $scope.uploading = true; - APIUtils.uploadImage($scope.file, function(response){ + APIUtils.uploadImage($scope.file).then(function(response){ $scope.uploading = false; if(response.status == 'error'){ $scope.displayError({ @@ -89,6 +94,69 @@ window.angular && (function (angular) { $scope.confirm_upload_image = false; } + $scope.download = function(){ + $scope.downloading = true; + APIUtils.downloadImage($scope.download_host, $scope.download_filename).then(function(response){ + var data = response.data; + $scope.downloading = false; + var headers = response.headers(); + + var filename = headers['x-filename']; + var contentType = headers['content-type']; + + if(!headers['x-filename']){ + filename = Constants.FIRMWARE.FALLBACK_DOWNLOAD_FILENAME; + } + + var linkElement = document.createElement('a'); + try { + var blob = new Blob([data], { type: contentType }); + var url = window.URL.createObjectURL(blob); + + linkElement.setAttribute('href', url); + linkElement.setAttribute("download", filename); + + var clickEvent = new MouseEvent("click", { + "view": window, + "bubbles": true, + "cancelable": false + }); + linkElement.dispatchEvent(clickEvent); + } catch (ex) { + console.log(ex); + } + }); + } + + $scope.changePriority = function(imageId, from, to){ + $scope.priority_image_id = imageId; + $scope.priority_from = from; + $scope.priority_to = to; + + if((from + to) == 1){ + $scope.confirm_priority = true; + }else{ + $scope.confirmChangePriority(); + } + } + + $scope.confirmChangePriority = function(){ + $scope.loading = true; + APIUtils.changePriority($scope.priority_image_id, $scope.priority_to).then(function(response){ + $scope.loading = false; + if(response.status == 'error'){ + $scope.displayError({ + modal_title: response.data.description, + title: response.data.description, + desc: response.data.exception, + type: 'Error' + }); + }else{ + $scope.loadFirmwares(); + } + }); + $scope.confirm_priority = false; + } $scope.deleteImage = function(imageId){ $scope.delete_image_id = imageId; $scope.confirm_delete = true; diff --git a/app/login/controllers/login-controller.html b/app/login/controllers/login-controller.html index 162ede3..77ca583 100644 --- a/app/login/controllers/login-controller.html +++ b/app/login/controllers/login-controller.html @@ -9,23 +9,19 @@ <div class="row"> <div class="columns large-6 login__desc"> <h1>OpenBMC for IBM Power Systems</h1> - <ul class="login__server-info"> - <li><p class="login__info-label">API version</p><p>X.XX.XXX</p></li> - <li><p class="login__info-label">Server ID</p><p>XXXXXXXXXXXXXXXX</p></li> - <li><p class="login__info-label">Server model</p><p>Power XX-XXXXX</p></li> - <li><p class="login__info-label">Server power</p><p class="status-light__disabled">Indeterminate</p></li> - <li><p class="login__info-label">Status message</p><!--<p>BMC was reset by user</p>--></li> - </ul> </div> <div class="columns large-6 disabled"> <form id="login__form" action=""> + <label >Host</label> + <input type="text" ng-model="host" required ng-class="{error: error}" autofocus ng-keydown="tryLogin(host, username, password, $event)" ng-disabled="dataService.loading"> + <label for="username">Username</label> - <input type="text" id="username" name="username" required ng-model="username" ng-class="{error: error}" ng-keydown="tryLogin(username, password, $event)" ng-disabled="dataService.loading" autofocus> + <input type="text" id="username" name="username" required ng-model="username" ng-class="{error: error}" ng-keydown="tryLogin(host, username, password, $event)" ng-disabled="dataService.loading"> <label for="password">Password</label> - <input type="password" id="password" name="password" class="" required ng-model="password" ng-keydown="tryLogin(username, password, $event)" ng-disabled="dataService.loading"> + <input type="password" id="password" name="password" class="" required ng-model="password" ng-keydown="tryLogin(host, username, password, $event)" ng-disabled="dataService.loading"> - <input id="login__submit" class="btn-primary submit" type="button" value="Log in" role="button" ng-click="login(username, password)" ng-class="{error: error}" ng-disabled="dataService.loading"> + <input id="login__submit" class="btn-primary submit" type="button" value="Log in" role="button" ng-click="login(host, username, password)" ng-class="{error: error}" ng-disabled="dataService.loading"> <p class="login__error-msg" role="alert" ng-if="error">Incorrect username or password</p> <p class="login__error-msg" role="alert" ng-if="server_unreachable">Server unreachable</p> diff --git a/app/login/controllers/login-controller.js b/app/login/controllers/login-controller.js index d8e8951..79ee477 100644 --- a/app/login/controllers/login-controller.js +++ b/app/login/controllers/login-controller.js @@ -21,6 +21,7 @@ window.angular && (function (angular) { '$routeParams', function($scope, $window, APIUtils, dataService, userModel, $routeParams){ $scope.dataService = dataService; + $scope.host = $scope.dataService.host.replace(/^https?\:\/\//ig, ''); if($routeParams.fake_login && $routeParams.fake_login === 'fake_login'){ @@ -28,19 +29,22 @@ window.angular && (function (angular) { $window.location.hash = '#/overview/server'; } - $scope.tryLogin = function(username, password, event){ + $scope.tryLogin = function(host, username, password, event){ if(event.keyCode === 13){ - $scope.login(username, password); + $scope.login(host, username, password); } }; - $scope.login = function(username, password){ + $scope.login = function(host, username, password){ $scope.error = false; $scope.server_unreachable = false; if(!username || username == "" || - !password || password == ""){ + !password || password == "" || + !host || host == "" + ){ return false; }else{ + $scope.dataService.setHost(host); userModel.login(username, password, function(status, unreachable){ if(status){ $scope.$emit('user-logged-in',{}); |