Add boot option override and TPM enable toggle

- Adds ability to set a bootsource override to allowable target value
- Adds ability to enable or disable TPM required policy
- Replaces power operations confirm directive with bootstrap modal

Tested: Confirmed override settings saved to redfish but unable to verify
if settings are automatically set to disabled by petitboot after a
one time boot. Passes DAP.

Resolves openbmc/phosphor-webui#82
Resolves openbmc/phosphor-webui#90

Signed-off-by: Dixsie Wolmers <dixsiew@gmail.com>
Change-Id: If0ffd6f9328939d70c7958ee11fb90bd20a1e685
Signed-off-by: Gunnar Mills <gmills@us.ibm.com>
diff --git a/app/assets/icons/icon-pending.svg b/app/assets/icons/icon-pending.svg
new file mode 100644
index 0000000..5d48c00
--- /dev/null
+++ b/app/assets/icons/icon-pending.svg
@@ -0,0 +1 @@
+<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path id="pending-a" d="M13.12,14.13l.15-.13-.7-.91a6.89,6.89,0,0,0,1.56-2,6.79,6.79,0,0,0,.71-3,6.88,6.88,0,0,0-6.9-6.86V0A8,8,0,0,1,16,8a7.92,7.92,0,0,1-.84,3.56A8,8,0,0,1,13.12,14.13Zm-2.28,1.34a8.08,8.08,0,0,1-2.9.53V14.86a6.93,6.93,0,0,0,2.53-.48ZM3.48,13.22a6.92,6.92,0,0,0,2.08,1.19l-.39,1.07a8.07,8.07,0,0,1-2.4-1.39Zm-2.33-4A6.77,6.77,0,0,0,2,11.43L1,12A7.9,7.9,0,0,1,0,9.38ZM5.54,1.58a6.91,6.91,0,0,0-2.06,1.2L2.77,1.9A8.07,8.07,0,0,1,5.15.5ZM2,4.57a6.77,6.77,0,0,0-.79,2.22L0,6.59A7.9,7.9,0,0,1,1,4Zm8.24,7L7,8.38V3H8.14V7.9L11,10.76Z"/></svg>
\ No newline at end of file
diff --git a/app/common/services/api-utils.js b/app/common/services/api-utils.js
index 27b122d..ba48a49 100644
--- a/app/common/services/api-utils.js
+++ b/app/common/services/api-utils.js
@@ -679,6 +679,45 @@
             data: JSON.stringify({'data': state})
           })
         },
+        getBootOptions: function() {
+          return $http({
+                   method: 'GET',
+                   url: DataService.getHost() + '/redfish/v1/Systems/system',
+                   withCredentials: true
+                 })
+              .then(function(response) {
+                return response.data;
+              });
+        },
+        saveBootSettings: function(data) {
+          return $http({
+            method: 'PATCH',
+            url: DataService.getHost() + '/redfish/v1/Systems/system',
+            withCredentials: true,
+            data: data
+          });
+        },
+        getTPMStatus: function() {
+          return $http({
+                   method: 'GET',
+                   url: DataService.getHost() +
+                       '/xyz/openbmc_project/control/host0/TPMEnable',
+                   withCredentials: true
+                 })
+              .then(function(response) {
+                return response.data;
+              });
+        },
+        saveTPMEnable: function(data) {
+          return $http({
+            method: 'PUT',
+            url: DataService.getHost() +
+                '/xyz/openbmc_project/control/host0/TPMEnable/attr/TPMEnable',
+            withCredentials: true,
+            data: JSON.stringify({'data': data})
+          })
+        },
+
         bmcReboot: function() {
           return $http({
             method: 'PUT',
diff --git a/app/common/services/constants.js b/app/common/services/constants.js
index ae82e76..37dd29f 100644
--- a/app/common/services/constants.js
+++ b/app/common/services/constants.js
@@ -113,11 +113,11 @@
               'Time out. Did not download image in allotted time.',
         },
         POWER_OP: {
-          POWER_ON_FAILED: 'Power On Failed',
-          WARM_REBOOT_FAILED: 'Warm Reboot Failed',
-          COLD_REBOOT_FAILED: 'Cold Reboot Failed',
-          ORDERLY_SHUTDOWN_FAILED: 'Orderly Shutdown Failed',
-          IMMEDIATE_SHUTDOWN_FAILED: 'Immediate Shutdown Failed',
+          POWER_ON_FAILED: 'Power on failed.',
+          WARM_REBOOT_FAILED: 'Warm reboot failed.',
+          COLD_REBOOT_FAILED: 'Cold reboot failed.',
+          ORDERLY_SHUTDOWN_FAILED: 'Orderly shutdown failed.',
+          IMMEDIATE_SHUTDOWN_FAILED: 'Immediate shutdown failed.',
         },
         SENSOR: {
           NO_SENSOR_DATA: 'There are no sensors found.',
diff --git a/app/common/styles/elements/modals.scss b/app/common/styles/elements/modals.scss
index 0e21a39..450a26b 100644
--- a/app/common/styles/elements/modals.scss
+++ b/app/common/styles/elements/modals.scss
@@ -107,6 +107,15 @@
 }
 .uib-modal__content {
   padding: 1em;
+  .modal-header {
+    display: block;
+  }
+  .btn--close {
+    padding: 0;
+    svg {
+      height: 1.6em;
+    }
+  }
 }
 
 .uib-modal {
@@ -118,4 +127,4 @@
       height: 2em;
     }
   }
-}
\ No newline at end of file
+}
diff --git a/app/server-control/controllers/power-operations-controller.html b/app/server-control/controllers/power-operations-controller.html
index ddf8bda..2ef5323 100644
--- a/app/server-control/controllers/power-operations-controller.html
+++ b/app/server-control/controllers/power-operations-controller.html
@@ -1,58 +1,172 @@
 <loader loading="dataService.loading || loading"></loader>
-<div id="power-operations">
-    <div class="row column">
-        <h1>Server power operations</h1>
-        <div class="power__current-status page-header">
-            <h2 class="inline">Current status</h2>
-            <div class="power__status-log inline float-right">Last power operation at <span class="courier-bold">{{powerTime | localeDate}}</span></div>
-        </div>
+<div id="power-operations" class="power-operations">
+  <div class="row column">
+    <h1>Server power operations</h1>
+    <div class="power__current-status page-header">
+      <h2 class="inline">Current status</h2>
+      <div class="power__status-log inline float-right">
+        Last power operation at
+        <span class="courier-bold">{{ powerTime | localeDate }}</span>
+      </div>
     </div>
-    <div class="row column">
-        <div id="power-indicator-bar" class="power__indicator-bar" ng-class="{'power__state-on': dataService.server_state == 'Running', 'power__state-off': dataService.server_state == 'Off', 'power__state-indet': dataService.server_state == 'Standby', 'power__state-error': dataService.server_state == 'Quiesced'}">
-            <p class="inline">{{dataService.hostname}} - {{dataService.server_id}}</p>
-            <h3 class="power__state inline no-margin h3"><span>{{dataService.server_state | quiescedToError}}</span></h3>
-        </div>
+  </div>
+  <!-- Power Indicator Bar -->
+  <div class="row column">
+    <div id="power-indicator-bar" class="power__indicator-bar"
+      ng-class="{'power__state-on': dataService.server_state == 'Running', 'power__state-off': dataService.server_state == 'Off', 'power__state-indet': dataService.server_state == 'Standby', 'power__state-error': dataService.server_state == 'Quiesced'}">
+      <p class="inline">
+        {{ dataService.hostname }} - {{ dataService.server_id }}
+      </p>
+      <h3 class="power__state inline no-margin h3">
+        <span>{{ dataService.server_state | quiescedToError }}</span>
+      </h3>
     </div>
-    <div class="row column">
-        <div class="row column">
-            <h3 class="subhead">Select a power operation</h3>
+  </div>
+  <div class="row column">
+    <!-- Boot Settings Column -->
+    <div class="large-4 columns boot-options-wrapper">
+      <form id="host-boot-settings" name="hostBootSettings" class="host-boot-settings" novalidate>
+        <h2 class="subhead boot-options">Host OS boot settings</h2>
+        <div class="boot-settings-form">
+          <div class="boot-options">
+            <label for="boot-selected">
+              Boot setting override</label>
+            <select id="boot-selected" name="bootSelected" id="boot-selected" ng-disabled="dataService.server_unreachable || bootOverrideError"
+              ng-model="boot.BootSourceOverrideTarget">
+              <option class="courier-bold" value="{{bootSource}}" ng-repeat="bootSource in bootSources">
+                {{ bootSource }}
+              </option>
+            </select>
+          <div class="boot-options one-time-boot-setting">
+            <div class="align-self-center">
+              <label class="control-check" id="one-time-label"> <span class="inline boot-checkbox">Enable one time boot</span>
+                <input type="checkbox" name="oneTime"
+                  ng-disabled="dataService.server_unreachable || bootOverrideError || boot.BootSourceOverrideTarget =='None' " ng-model="boot.oneTimeBootEnabled"
+                  ng-change="oneTimeBootEnabled" />
+                <span class="control__indicator"> </span>
+              </label>
+            </div>
+          </div>
         </div>
-        <div ng-if="operationPending">
-            <span class="inactive-message">There are no power operations to display while a power operation is in progress. When complete, any new power operations will be displayed here.</span>
-        </div>
-        <div ng-if="!operationPending">
-            <!-- Power on displays only when server is shutdown -->
-            <div class="row column power-option" ng-hide="dataService.server_state == 'Running' || dataService.server_state == 'Quiesced' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || confirm || dataService.loading, transitionAll: confirm}">
-                <button id="power__power-on" class="btn  btn-secondary" ng-click="powerOn()" role="button" ng-disabled="dataService.server_unreachable">
-                    <icon file="icon-power.svg"></icon>Power on
+          <!-- TPM Required -->
+          <div class="boot-options one-time-boot-setting">
+            <div class="boot-options">
+              <h3 class="content-label">
+                TPM required policy</h3>
+              <p> Enable to ensure the system only boots when the TPM is functional. </p>
+              <!-- Toggle component -->
+              <div class="toggle-container">
+                  <div class="toggle">
+                    <input
+                      id="toggle__switch-round"
+                      class="toggle-switch toggle-switch__round-flat"
+                      name="toggle"
+                      type="checkbox"
+                      tabindex="0"
+                      ng-model="TPMToggle.TPMEnable"
+                      ng-disabled="dataService.server_unreachable"
+                    />
+                    <label for="toggle__switch-round" tabindex="0"
+                      >TPM required policy is {{ TPMToggle.TPMEnable ? "On" : "Off" }}</label
+                    >
+                  </div>
+                  <span>
+                    {{ TPMToggle.TPMEnable ? "On" : "Off" }}
+                  </span>
+                </div>
+            </div>
+          </div>
+          <!-- form actions -->
+          <div class="boot-form-actions">
+            <button type="submit" class="btn btn-primary" ng-click="saveBootSettings();saveTPMPolicy();hostBootSettings.$setPristine()" ng-disabled="dataService.server_unreachable || hostBootSettings.$pristine;">
+              Save
+            </button>
+            <button type="reset" class="btn btn-secondary" ng-disabled="dataService.server_unreachable || hostBootSettings.$pristine" ng-click="resetForm();hostBootSettings.$setPristine()">
+              Cancel
+            </button>
+          </div>
+      </form>
+    </div>
+  </div>
+  <!-- Power Operations Column -->
+  <div class="large-8 columns operations-wrapper">
+    <h2 class="subhead boot-operations">Operations</h2>
+    <!-- Pending one time boot alert -->
+    <div class="alert-warning"
+      ng-if="boot.oneTimeBootEnabled" ng-hide="dataService.server_state == 'Unreachable'">
+      <div class="pending-icon">
+        <icon file="icon-pending.svg"></icon>
+      </div>
+      <p class="alert-pending">
+        Pending one time boot. Next boot will be performed with the
+        specified one time boot settings. Subsequent boots will be performed
+        with the default settings.
+      </p>
+    </div>
+    <!-- Pending reboot warning -->
+    <p ng-show="operationPending">
+      There are no power operations to display while power operation is in
+      progress. When complete, any new power operations will be displayed
+      here.
+    </p>
+    <div ng-show="!operationPending">
+    <!-- Power on displays only when server is off -->
+    <div class="row column" ng-show="dataService.server_state == 'Off'"
+      ng-class="{disabled: dataService.server_unreachable}">
+      <button id="power__power-on" class="btn btn-primary inline" ng-click="powerOn()" role="button"
+        ng-disabled="dataService.server_unreachable">
+        Power on
+      </button>
+    </div>
+    <!-- Reboot/shutdown column -->
+    <div
+      ng-show="dataService.server_state !== 'Off'">
+      <div class="reboot__operations">
+        <form id="reboot-form" name="rebootForm" class="reboot-form">
+          <fieldset>
+            <legend class="boot-operations">Reboot server</legend>
+              <label class="control-radio">Orderly - OS shuts down, then server reboots
+                <input type="radio" name="radioReboot"
+                  ng-model="defaultRebootSetting" value="warm-reboot" />
+                <span class="control__indicator control__indicator-on"></span>
+              </label>
+              <label class="control-radio">Immediate - Server reboots without OS shutting down; may cause data corruption
+                <input type="radio" name="radioReboot"
+                   ng-model="defaultRebootSetting" value="cold-reboot" />
+                <span class="control__indicator control__indicator-on"></span>
+              </label>
+            </fieldset>
+              <div>
+                <button class="btn-primary" ng-click="rebootConfirmModal()" type="submit" ng-disabled="dataService.server_unreachable">
+                  Reboot
                 </button>
-                <p class="inline">Attempts to power on the server</p>
+              </div>
+        </form>
+      </div>
+      <!-- Shutdown Field Row -->
+      <div class="shutdown__operations">
+        <form id="shutdown-form" name="shutdownForm" class="shutdown-form">
+          <fieldset>
+            <legend class="boot-operations">Shutdown server</legend>
+            <label class="control-radio">Orderly - OS shuts down, then server shuts down
+              <input type="radio" name="radioShutdown" ng-model="defaultShutdownSetting"
+                value='warm-shutdown' />
+              <span class="control__indicator control__indicator-on"></span>
+            </label>
+            <label class="control-radio">Immediate - Server shuts down without OS shutting down; may cause data corruption
+              <input type="radio" name="radioShutdown" ng-model="defaultShutdownSetting"
+                value='cold-shutdown' />
+              <span class="control__indicator control__indicator-on"></span>
+            </label>
+           </fieldset>
+            <div>
+              <button class="btn-primary" ng-click="shutdownConfirmModal()" type="submit" ng-disabled="dataService.server_unreachable">
+                Shut down
+              </button>
             </div>
-            <!-- Power reboot/shutdown options : when server is off all of these are hidden. When one option is selected, the others are disabled. -->
-            <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmWarmReboot) || dataService.loading, transitionAll: confirm && confirmWarmReboot}">
-                <button id="power__warm-boot" class="btn btn-secondary" ng-click="warmRebootConfirm()" role="button" ng-disabled="dataService.server_unreachable">
-                    <icon file="icon-restart.svg"></icon>Warm reboot</button>
-                <p class="inline">Attempts to perform an orderly shutdown before restarting the server</p>
-                <confirm title="warm reboot" confirm="confirmWarmReboot" ng-show="confirmWarmReboot" callback="warmReboot"></confirm>
-            </div>
-            <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmColdReboot) || dataService.loading, transitionAll: confirm && confirmColdReboot}">
-                <button id="power__cold-boot" class="btn  btn-secondary" ng-click="coldRebootConfirm()" role="button" ng-disabled="dataService.server_unreachable">
-                    <icon file="icon-restart.svg"></icon>Cold reboot</button>
-                <p class="inline">Shuts down the server immediately, then restarts it</p>
-                <confirm title="cold reboot" confirm="confirmColdReboot" ng-show="confirmColdReboot" cancel="coldbootCancel" callback="coldReboot"></confirm>
-            </div>
-            <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmOrderlyShutdown) || dataService.loading, transitionAll: confirm && confirmOrderlyShutdown}">
-                <button id="power__soft-shutdown" class="btn  btn-secondary" ng-click="orderlyShutdownConfirm()" role="button" ng-disabled="dataService.server_unreachable">
-                    <icon file="icon-power.svg"></icon>Orderly shutdown</button>
-                <p class="inline">Attempts to stop all software on the server before removing power</p>
-                <confirm title="orderly shutdown" confirm="confirmOrderlyShutdown" ng-show="confirmOrderlyShutdown" cancel="orderlyShutdownCancel" callback="orderlyShutdown"></confirm>
-            </div>
-            <div class="column power-option" ng-hide="dataService.server_state == 'Off' || dataService.server_state == 'Unreachable'" ng-class="{disabled: dataService.server_unreachable || (confirm && !confirmImmediateShutdown) || dataService.loading, transitionAll: confirm && confirmImmediateShutdown}">
-                <button id="power__hard-shutdown" class="btn btn-secondary" ng-click="immediateShutdownConfirm()" role="button" ng-disabled="dataService.server_unreachable">
-                    <icon file="icon-power.svg"></icon>Immediate shutdown</button>
-                <p class="inline">Removes power from the server without waiting for software to stop</p>
-                <confirm title="immediate shutdown" confirm="confirmImmediateShutdown" ng-show="confirmImmediateShutdown" cancel="immediatelyShutdownCancel" callback="immediateShutdown"></confirm>
-            </div>
-        </div>
+        </form>
+      </div>
     </div>
-</div>
+  </div>
+  </div>
+</div>
\ No newline at end of file
diff --git a/app/server-control/controllers/power-operations-controller.js b/app/server-control/controllers/power-operations-controller.js
index 986ac3b..89376c6 100644
--- a/app/server-control/controllers/power-operations-controller.js
+++ b/app/server-control/controllers/power-operations-controller.js
@@ -11,18 +11,20 @@
 
   angular.module('app.serverControl').controller('powerOperationsController', [
     '$scope', 'APIUtils', 'dataService', 'Constants', '$interval', '$q',
-    'toastService',
+    'toastService', '$uibModal',
     function(
-        $scope, APIUtils, dataService, Constants, $interval, $q, toastService) {
+        $scope, APIUtils, dataService, Constants, $interval, $q, toastService,
+        $uibModal) {
       $scope.dataService = dataService;
-      // Is a || of the other 4 "confirm" variables to ensure only
-      // one confirm is shown at a time.
-      $scope.confirm = false;
-      $scope.confirmWarmReboot = false;
-      $scope.confirmColdReboot = false;
-      $scope.confirmOrderlyShutdown = false;
-      $scope.confirmImmediateShutdown = false;
       $scope.loading = true;
+      $scope.oneTimeBootEnabled = false;
+      $scope.bootOverrideError = false;
+      $scope.bootSources = [];
+      $scope.boot = {};
+      $scope.defaultRebootSetting = 'warm-reboot';
+      $scope.defaultShutdownSetting = 'warm-shutdown';
+
+      $scope.activeModal;
 
       // When a power operation is in progress, set to true,
       // when a power operation completes (success/fail) set to false.
@@ -30,6 +32,11 @@
       // in markup.
       $scope.operationPending = false;
 
+      const modalTemplate = require('./power-operations-modal.html');
+
+      const powerOperations =
+          {WARM_REBOOT: 0, COLD_REBOOT: 1, WARM_SHUTDOWN: 2, COLD_SHUTDOWN: 3};
+
       /**
        * Checks the host status provided by the dataService using an
        * interval timer
@@ -39,7 +46,7 @@
        * @returns {Promise} : returns a deferred promise that will be fulfilled
        * if the status is met or be rejected if the timeout is reached
        */
-      var checkHostStatus =
+      const checkHostStatus =
           (statusType, timeout = 300000, error = 'Time out.') => {
             const deferred = $q.defer();
             const start = new Date();
@@ -58,54 +65,11 @@
             return deferred.promise;
           };
 
-      APIUtils.getLastPowerTime()
-          .then(
-              function(data) {
-                if (data.data == 0) {
-                  $scope.powerTime = 'not available';
-                } else {
-                  $scope.powerTime = data.data;
-                }
-              },
-              function(error) {
-                console.log(JSON.stringify(error));
-              })
-          .finally(function() {
-            $scope.loading = false;
-          });
-
-      $scope.toggleState = function() {
-        dataService.server_state =
-            (dataService.server_state == 'Running') ? 'Off' : 'Running';
-      };
-
-      /**
-       * Initiate Power on
-       */
-      $scope.powerOn = () => {
-        $scope.operationPending = true;
-        dataService.setUnreachableState();
-        APIUtils.hostPowerOn()
-            .then(() => {
-              // Check for on state
-              return checkHostStatus(
-                  Constants.HOST_STATE_TEXT.on, Constants.TIMEOUT.HOST_ON,
-                  Constants.MESSAGES.POLL.HOST_ON_TIMEOUT);
-            })
-            .catch((error) => {
-              console.log(error);
-              toastService.error(Constants.MESSAGES.POWER_OP.POWER_ON_FAILED);
-            })
-            .finally(() => {
-              $scope.operationPending = false;
-            })
-      };
-
       /**
        * Initiate Orderly reboot
        * Attempts to stop all software
        */
-      $scope.warmReboot = () => {
+      const warmReboot = () => {
         $scope.operationPending = true;
         dataService.setUnreachableState();
         APIUtils.hostReboot()
@@ -121,30 +85,21 @@
                   Constants.HOST_STATE_TEXT.on, Constants.TIMEOUT.HOST_ON,
                   Constants.MESSAGES.POLL.HOST_ON_TIMEOUT);
             })
-            .catch((error) => {
+            .catch(error => {
               console.log(error);
               toastService.error(
                   Constants.MESSAGES.POWER_OP.WARM_REBOOT_FAILED);
             })
             .finally(() => {
               $scope.operationPending = false;
-            })
-      };
-
-      $scope.warmRebootConfirm = function() {
-        if ($scope.confirm) {
-          // If another "confirm" is already shown return
-          return;
-        }
-        $scope.confirm = true;
-        $scope.confirmWarmReboot = true;
+            });
       };
 
       /**
        * Initiate Immediate reboot
        * Does not attempt to stop all software
        */
-      $scope.coldReboot = () => {
+      const coldReboot = () => {
         $scope.operationPending = true;
         dataService.setUnreachableState();
         APIUtils.chassisPowerOff()
@@ -164,29 +119,21 @@
                   Constants.HOST_STATE_TEXT.on, Constants.TIMEOUT.HOST_ON,
                   Constants.MESSAGES.POLL.HOST_ON_TIMEOUT);
             })
-            .catch((error) => {
+            .catch(error => {
               console.log(error);
               toastService.error(
                   Constants.MESSAGES.POWER_OP.COLD_REBOOT_FAILED);
             })
             .finally(() => {
               $scope.operationPending = false;
-            })
-      };
-
-      $scope.coldRebootConfirm = function() {
-        if ($scope.confirm) {
-          return;
-        }
-        $scope.confirm = true;
-        $scope.confirmColdReboot = true;
+            });
       };
 
       /**
        * Initiate Orderly shutdown
        * Attempts to stop all software
        */
-      $scope.orderlyShutdown = () => {
+      const orderlyShutdown = () => {
         $scope.operationPending = true;
         dataService.setUnreachableState();
         APIUtils.hostPowerOff()
@@ -196,29 +143,21 @@
                   Constants.HOST_STATE_TEXT.off, Constants.TIMEOUT.HOST_OFF,
                   Constants.MESSAGES.POLL.HOST_OFF_TIMEOUT);
             })
-            .catch((error) => {
+            .catch(error => {
               console.log(error);
               toastService.error(
                   Constants.MESSAGES.POWER_OP.ORDERLY_SHUTDOWN_FAILED);
             })
             .finally(() => {
               $scope.operationPending = false;
-            })
-      };
-
-      $scope.orderlyShutdownConfirm = function() {
-        if ($scope.confirm) {
-          return;
-        }
-        $scope.confirm = true;
-        $scope.confirmOrderlyShutdown = true;
+            });
       };
 
       /**
        * Initiate Immediate shutdown
        * Does not attempt to stop all software
        */
-      $scope.immediateShutdown = () => {
+      const immediateShutdown = () => {
         $scope.operationPending = true;
         dataService.setUnreachableState();
         APIUtils.chassisPowerOff()
@@ -232,23 +171,236 @@
             .then(() => {
               dataService.setPowerOffState();
             })
-            .catch((error) => {
+            .catch(error => {
               console.log(error);
               toastService.error(
                   Constants.MESSAGES.POWER_OP.IMMEDIATE_SHUTDOWN_FAILED);
             })
             .finally(() => {
               $scope.operationPending = false;
-            })
+            });
       };
 
-      $scope.immediateShutdownConfirm = function() {
-        if ($scope.confirm) {
-          return;
-        }
-        $scope.confirm = true;
-        $scope.confirmImmediateShutdown = true;
+      /**
+       * Initiate Power on
+       */
+      $scope.powerOn = () => {
+        $scope.operationPending = true;
+        dataService.setUnreachableState();
+        APIUtils.hostPowerOn()
+            .then(() => {
+              // Check for on state
+              return checkHostStatus(
+                  Constants.HOST_STATE_TEXT.on, Constants.TIMEOUT.HOST_ON,
+                  Constants.MESSAGES.POLL.HOST_ON_TIMEOUT);
+            })
+            .catch(error => {
+              console.log(error);
+              toastService.error(Constants.MESSAGES.POWER_OP.POWER_ON_FAILED);
+            })
+            .finally(() => {
+              $scope.operationPending = false;
+            });
       };
+
+      /*
+       *  Power operations modal
+       */
+      const initPowerOperation = function(powerOperation) {
+        switch (powerOperation) {
+          case powerOperations.WARM_REBOOT:
+            warmReboot();
+            break;
+          case powerOperations.COLD_REBOOT:
+            coldReboot();
+            break;
+          case powerOperations.WARM_SHUTDOWN:
+            orderlyShutdown();
+            break;
+          case powerOperations.COLD_SHUTDOWN:
+            immediateShutdown();
+            break;
+          default:
+            // do nothing
+        }
+      };
+
+      const powerOperationModal = function() {
+        $uibModal
+            .open({
+              template: modalTemplate,
+              windowTopClass: 'uib-modal',
+              scope: $scope,
+              ariaLabelledBy: 'modal-operation'
+            })
+            .result
+            .then(function(activeModal) {
+              initPowerOperation(activeModal);
+            })
+            .finally(function() {
+              $scope.activeModal = undefined;
+            });
+      };
+
+      $scope.rebootConfirmModal = function() {
+        if ($scope.rebootForm.radioReboot.$modelValue == 'warm-reboot') {
+          $scope.activeModal = powerOperations.WARM_REBOOT;
+        } else if ($scope.rebootForm.radioReboot.$modelValue == 'cold-reboot') {
+          $scope.activeModal = powerOperations.COLD_REBOOT;
+        }
+        powerOperationModal();
+      };
+
+      $scope.shutdownConfirmModal = function() {
+        if ($scope.shutdownForm.radioShutdown.$modelValue == 'warm-shutdown') {
+          $scope.activeModal = powerOperations.WARM_SHUTDOWN;
+        } else if (
+            $scope.shutdownForm.radioShutdown.$modelValue == 'cold-shutdown') {
+          $scope.activeModal = powerOperations.COLD_SHUTDOWN;
+        }
+        powerOperationModal();
+      };
+
+      $scope.resetForm = function() {
+        $scope.boot = angular.copy($scope.originalBoot);
+        $scope.TPMToggle = angular.copy($scope.originalTPMToggle);
+      };
+
+      /*
+       *   Get boot settings
+       */
+      const loadBootSettings = function() {
+        APIUtils.getBootOptions()
+            .then(function(response) {
+              const boot = response.Boot;
+              const BootSourceOverrideEnabled =
+                  boot['BootSourceOverrideEnabled'];
+              const BootSourceOverrideTarget = boot['BootSourceOverrideTarget'];
+              const bootSourceValues =
+                  boot['BootSourceOverrideTarget@Redfish.AllowableValues'];
+
+              $scope.bootSources = bootSourceValues;
+
+              $scope.boot = {
+                BootSourceOverrideEnabled: BootSourceOverrideEnabled,
+                BootSourceOverrideTarget: BootSourceOverrideTarget
+              };
+
+              if (BootSourceOverrideEnabled == 'Once') {
+                $scope.boot.oneTimeBootEnabled = true;
+              }
+
+              $scope.originalBoot = angular.copy($scope.boot);
+            })
+            .catch(function(error) {
+              $scope.bootOverrideError = true;
+              toastService.error('Unable to get boot override values.');
+              console.log(
+                  'Error loading boot settings:', JSON.stringify(error));
+            });
+        $scope.loading = false;
+      };
+
+      /*
+       *   Get TPM status
+       */
+      const loadTPMStatus = function() {
+        APIUtils.getTPMStatus()
+            .then(function(response) {
+              $scope.TPMToggle = response.data;
+              $scope.originalTPMToggle = angular.copy($scope.TPMToggle);
+            })
+            .catch(function(error) {
+              toastService.error('Unable to get TPM policy status.');
+              console.log('Error loading TPM status', JSON.stringify(error));
+            });
+        $scope.loading = false;
+      };
+
+      /*
+       *   Save boot settings
+       */
+      $scope.saveBootSettings = function() {
+        if ($scope.hostBootSettings.bootSelected.$dirty ||
+            $scope.hostBootSettings.oneTime.$dirty) {
+          const data = {};
+          data.Boot = {};
+
+          let isOneTimeBoot = $scope.boot.oneTimeBootEnabled;
+          let overrideTarget = $scope.boot.BootSourceOverrideTarget || 'None';
+          let overrideEnabled = 'Disabled';
+
+          if (isOneTimeBoot) {
+            overrideEnabled = 'Once';
+          } else if (overrideTarget !== 'None') {
+            overrideEnabled = 'Continuous';
+          }
+
+          data.Boot.BootSourceOverrideEnabled = overrideEnabled;
+          data.Boot.BootSourceOverrideTarget = overrideTarget;
+
+          APIUtils.saveBootSettings(data).then(
+              function(response) {
+                $scope.originalBoot = angular.copy($scope.boot);
+                toastService.success('Successfully updated boot settings.');
+              },
+              function(error) {
+                toastService.error('Unable to save boot settings.');
+                console.log(JSON.stringify(error));
+              });
+        }
+      };
+
+      /*
+       *   Save TPM required policy
+       */
+      $scope.saveTPMPolicy = function() {
+        if ($scope.hostBootSettings.toggle.$dirty) {
+          const tpmEnabled = $scope.TPMToggle.TPMEnable;
+
+          if (tpmEnabled === undefined) {
+            return;
+          }
+
+          APIUtils.saveTPMEnable(tpmEnabled)
+              .then(
+                  function(response) {
+                    $scope.originalTPMToggle = angular.copy($scope.TPMToggle);
+                    toastService.success(
+                        'Sucessfully updated TPM required policy.');
+                  },
+                  function(error) {
+                    toastService.error('Unable to update TPM required policy.');
+                    console.log(JSON.stringify(error));
+                  });
+        }
+      };
+
+      /*
+       *   Emitted every time the view is reloaded
+       */
+      $scope.$on('$viewContentLoaded', function() {
+        APIUtils.getLastPowerTime()
+            .then(
+                function(data) {
+                  if (data.data == 0) {
+                    $scope.powerTime = 'not available';
+                  } else {
+                    $scope.powerTime = data.data;
+                  }
+                },
+                function(error) {
+                  toastService.error(
+                      'Unable to get last power operation time.');
+                  console.log(JSON.stringify(error));
+                })
+            .finally(function() {
+              $scope.loading = false;
+            });
+
+        loadBootSettings();
+        loadTPMStatus();
+      });
     }
   ]);
 })(angular);
diff --git a/app/server-control/controllers/power-operations-modal.html b/app/server-control/controllers/power-operations-modal.html
new file mode 100644
index 0000000..3524b4c
--- /dev/null
+++ b/app/server-control/controllers/power-operations-modal.html
@@ -0,0 +1,48 @@
+<!-- Shutdown and Reboot modal -->
+<div class="uib-modal__content">
+  <button
+    aria-label="Close"
+    type="button"
+    class="btn  btn--close  float-right"
+    ng-click="$dismiss()"
+  >
+    <icon file="icon-close.svg"></icon>
+  </button>
+  <div class="modal-header" id="modal-operation">
+    <h3>
+      <div class="icon__warning inline" aria-label="Warning"></div>
+      {{
+        activeModal === 2 || activeModal === 3
+          ? "Server shutdown will cause outage"
+          : "Server reboot will cause outage"
+      }}
+    </h3>
+  </div>
+  <div class="modal-body">
+    <p ng-if="activeModal === 2 || activeModal === 3">
+      Are you sure you want to
+      {{ activeModal === 2 ? "orderly" : "immediate" }}
+      shutdown?
+    </p>
+    <p ng-if="activeModal === 0 || activeModal === 1">
+      Are you sure you want to
+      {{ activeModal === 0 ? "orderly" : "immediate" }}
+      reboot?
+    </p>
+  </div>
+  <div class="modal-footer">
+    <!-- Power operation confirm buttons -->
+    <button
+      type="submit"
+      class="btn btn-primary"
+      ng-click="$close(activeModal)"
+    >
+      <span ng-if="activeModal === 0 || activeModal === 1">Reboot</span>
+      <span ng-if="activeModal === 2 || activeModal === 3">Shutdown</span>
+    </button>
+    <!-- Cancel modal power confirmation -->
+    <button type="button" class="btn btn-secondary" ng-click="$dismiss()">
+      Cancel
+    </button>
+  </div>
+</div>
diff --git a/app/server-control/styles/power-operations.scss b/app/server-control/styles/power-operations.scss
index fbc5a7f..6a29dfd 100644
--- a/app/server-control/styles/power-operations.scss
+++ b/app/server-control/styles/power-operations.scss
@@ -1,7 +1,6 @@
 // Power Operations SCSS
 
-#power-operations {
-
+.power-operations {
   // Power Current status wrapper
   .power__current-status {
     border-bottom: 1px solid $border-color-01;
@@ -11,9 +10,9 @@
   // Power state indicator on/off
   .power__state {
     font-weight: 700;
-    margin-top: -.3em;
+    margin-top: -0.3em;
     span:before {
-      content: '';
+      content: "";
       position: absolute;
       @extend .icon__off;
       margin-left: -25px;
@@ -24,16 +23,16 @@
   .power__indicator-bar {
     font-weight: bold;
     width: 100%;
-    padding: 1em 2em .7em;
+    padding: 1em 2em 0.7em;
     margin-bottom: 3em;
     background-size: 200% 100%;
-    background-image: linear-gradient(to right, darken($background-02,3%) 50%, $accent-02--02 50%);
+    background-image: linear-gradient(to right, darken($background-02, 3%) 50%, $accent-02--02 50%);
     background-position: 0;
     transition: background-position 2s ease;
     overflow: hidden;
-    display:flex;
+    display: flex;
     justify-content: space-between;
-    align-items:center;
+    align-items: center;
     p {
       padding: 0;
       margin: 0;
@@ -43,8 +42,8 @@
       background-position: -100%;
       .power__state {
         span:before {
-          content: '';
-         @extend .icon__good;
+          content: "";
+          @extend .icon__good;
         }
       }
     }
@@ -53,7 +52,7 @@
       color: $primary-dark;
       .power__state {
         span:before {
-          content: '';
+          content: "";
           @extend .icon__off;
         }
       }
@@ -64,7 +63,7 @@
       .power__state {
         span:before {
           color: $status-warn;
-          content: '';
+          content: "";
           @extend .icon__warning;
         }
       }
@@ -74,28 +73,92 @@
       color: $primary-dark;
       .power__state {
         span:before {
-          content: '';
+          content: "";
           @extend .icon__critical;
         }
       }
     }
   }
 
-  // Power button options
-  .power-option {
-    padding: 1.8em 0 1em 0;
-    position: relative;
-    overflow: hidden;
-    min-height: 1px;
-    min-width: 100%;
-    .btn {
-      margin-bottom: .5em;
-      margin-right: 1em;
-      min-width: 240px;
+  .boot-options,
+  .boot-operations {
+    margin-bottom: 1em;
+  }
+
+  .boot-options {
+    .control-check {
+      padding-top: 4px;
     }
-    @include mediaQuery(x-small){
-      padding: 1.8em 0 1em 0;
+    .boot-checkbox {
+      padding-left: 2em;
+      text-transform: none;
+      font-weight: 400;
+      font-size: 16px;
+      color: $primary-dark;
     }
   }
 
+  .boot-options-wrapper {
+    padding: 0 2em 2em 0;
+  }
+
+  .operations-wrapper {
+    .reboot__operations,
+    .shutdown__operations {
+      margin-bottom: 1.5em;
+      .control-radio {
+        padding: 0.3em 1em 0 2em;
+        text-transform: none;
+        font-weight: 400;
+        font-size: 16px;
+        color: $primary-dark;
+      }
+    }
+
+    .alert-warning {
+      border: 1px solid $accent-03--01;
+      padding: 1em;
+      margin-bottom: 1em;
+      display: flex;
+      align-items: center;
+      .pending-icon {
+        padding: 0 1em 0 0;
+      }
+      .alert-pending {
+        margin-top: 0.3em;
+        margin-bottom: 0;
+      }
+    }
+  }
+
+  .boot-settings-form {
+    background-color: $base-02--06;
+    padding: 2em;
+    .boot-form-actions {
+      margin-bottom: 4em;
+    }
+    .btn {
+      display: block;
+      float: right;
+      margin: 0.5em 0 0 1em;
+    }
+  }
+
+  .control-radio .control__indicator-on {
+    width: 20px;
+    height: 20px;
+    top: 3px;
+    left: 3px;
+  }
+
+  .control-radio .control__indicator-on:after {
+    top: 3px;
+    left: 3px;
+    width: 10px;
+    height: 10px;
+  }
+
+  .icon__warning {
+    width: 24px;
+  }
 } //end power-operations
diff --git a/app/server-health/styles/log.scss b/app/server-health/styles/log.scss
index 60bbba9..301dc2c 100644
--- a/app/server-health/styles/log.scss
+++ b/app/server-health/styles/log.scss
@@ -312,7 +312,6 @@
   }
 }
 
-/*p*/
 .event__description {
   margin-bottom: 0;
   line-height: 1.7;