IA update: Update configuration to settings

This is the fourth update to information architecture changes and has
the following changes:

- The configuration section is updated to settings
- The date and time settings page is updated to date and time
- The network settings page is updated to network
- The power restore policy page in operations section is moved to
settings section

Signed-off-by: Sandeepa Singh <sandeepa.singh@ibm.com>
Change-Id: I6f5ab25f5227530be430bd39a4d9629b3bf09d8b
diff --git a/src/views/Settings/DateTime/DateTime.vue b/src/views/Settings/DateTime/DateTime.vue
new file mode 100644
index 0000000..e62e344
--- /dev/null
+++ b/src/views/Settings/DateTime/DateTime.vue
@@ -0,0 +1,405 @@
+<template>
+  <b-container fluid="xl">
+    <page-title />
+    <b-row>
+      <b-col md="8" xl="6">
+        <alert variant="info" class="mb-4">
+          <span>
+            {{ $t('pageDateTime.alert.message') }}
+            <b-link to="/profile-settings">
+              {{ $t('pageDateTime.alert.link') }}</b-link
+            >
+          </span>
+        </alert>
+      </b-col>
+    </b-row>
+    <page-section>
+      <b-row>
+        <b-col lg="3">
+          <dl>
+            <dt>{{ $t('pageDateTime.form.date') }}</dt>
+            <dd v-if="bmcTime">{{ bmcTime | formatDate }}</dd>
+            <dd v-else>--</dd>
+          </dl>
+        </b-col>
+        <b-col lg="3">
+          <dl>
+            <dt>{{ $t('pageDateTime.form.time.label') }}</dt>
+            <dd v-if="bmcTime">{{ bmcTime | formatTime }}</dd>
+            <dd v-else>--</dd>
+          </dl>
+        </b-col>
+      </b-row>
+    </page-section>
+    <page-section :section-title="$t('pageDateTime.configureSettings')">
+      <b-form novalidate @submit.prevent="submitForm">
+        <b-form-group
+          label="Configure date and time"
+          :disabled="loading"
+          label-sr-only
+        >
+          <b-form-radio
+            v-model="form.configurationSelected"
+            value="manual"
+            data-test-id="dateTime-radio-configureManual"
+          >
+            {{ $t('pageDateTime.form.manual') }}
+          </b-form-radio>
+          <b-row class="mt-3 ml-3">
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.date')"
+                label-for="input-manual-date"
+              >
+                <b-form-text id="date-format-help">YYYY-MM-DD</b-form-text>
+                <b-input-group>
+                  <b-form-input
+                    id="input-manual-date"
+                    v-model="form.manual.date"
+                    :state="getValidationState($v.form.manual.date)"
+                    :disabled="ntpOptionSelected"
+                    data-test-id="dateTime-input-manualDate"
+                    class="form-control-with-button"
+                    @blur="$v.form.manual.date.$touch()"
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div v-if="!$v.form.manual.date.pattern">
+                      {{ $t('global.form.invalidFormat') }}
+                    </div>
+                    <div v-if="!$v.form.manual.date.required">
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                  <b-form-datepicker
+                    v-model="form.manual.date"
+                    class="btn-datepicker btn-icon-only"
+                    button-only
+                    right
+                    :hide-header="true"
+                    :locale="locale"
+                    :label-help="
+                      $t('global.calendar.useCursorKeysToNavigateCalendarDates')
+                    "
+                    :title="$t('global.calendar.selectDate')"
+                    :disabled="ntpOptionSelected"
+                    button-variant="link"
+                    aria-controls="input-manual-date"
+                  >
+                    <template #button-content>
+                      <icon-calendar />
+                      <span class="sr-only">
+                        {{ $t('global.calendar.selectDate') }}
+                      </span>
+                    </template>
+                  </b-form-datepicker>
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.time.timezone', { timezone })"
+                label-for="input-manual-time"
+              >
+                <b-form-text id="time-format-help">HH:MM</b-form-text>
+                <b-input-group>
+                  <b-form-input
+                    id="input-manual-time"
+                    v-model="form.manual.time"
+                    :state="getValidationState($v.form.manual.time)"
+                    :disabled="ntpOptionSelected"
+                    data-test-id="dateTime-input-manualTime"
+                    @blur="$v.form.manual.time.$touch()"
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div v-if="!$v.form.manual.time.pattern">
+                      {{ $t('global.form.invalidFormat') }}
+                    </div>
+                    <div v-if="!$v.form.manual.time.required">
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+          </b-row>
+          <b-form-radio
+            v-model="form.configurationSelected"
+            value="ntp"
+            data-test-id="dateTime-radio-configureNTP"
+          >
+            NTP
+          </b-form-radio>
+          <b-row class="mt-3 ml-3">
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.ntpServers.server1')"
+                label-for="input-ntp-1"
+              >
+                <b-input-group>
+                  <b-form-input
+                    id="input-ntp-1"
+                    v-model="form.ntp.firstAddress"
+                    :state="getValidationState($v.form.ntp.firstAddress)"
+                    :disabled="manualOptionSelected"
+                    data-test-id="dateTime-input-ntpServer1"
+                    @blur="$v.form.ntp.firstAddress.$touch()"
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div v-if="!$v.form.ntp.firstAddress.required">
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.ntpServers.server2')"
+                label-for="input-ntp-2"
+              >
+                <b-input-group>
+                  <b-form-input
+                    id="input-ntp-2"
+                    v-model="form.ntp.secondAddress"
+                    :disabled="manualOptionSelected"
+                    data-test-id="dateTime-input-ntpServer2"
+                  />
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+            <b-col sm="6" lg="4" xl="3">
+              <b-form-group
+                :label="$t('pageDateTime.form.ntpServers.server3')"
+                label-for="input-ntp-3"
+              >
+                <b-input-group>
+                  <b-form-input
+                    id="input-ntp-3"
+                    v-model="form.ntp.thirdAddress"
+                    :disabled="manualOptionSelected"
+                    data-test-id="dateTime-input-ntpServer3"
+                  />
+                </b-input-group>
+              </b-form-group>
+            </b-col>
+          </b-row>
+          <b-button
+            variant="primary"
+            type="submit"
+            data-test-id="dateTime-button-saveSettings"
+          >
+            {{ $t('global.action.saveSettings') }}
+          </b-button>
+        </b-form-group>
+      </b-form>
+    </page-section>
+  </b-container>
+</template>
+
+<script>
+import Alert from '@/components/Global/Alert';
+import IconCalendar from '@carbon/icons-vue/es/calendar/20';
+import PageTitle from '@/components/Global/PageTitle';
+import PageSection from '@/components/Global/PageSection';
+
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import LocalTimezoneLabelMixin from '@/components/Mixins/LocalTimezoneLabelMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+
+import { mapState } from 'vuex';
+import { requiredIf, helpers } from 'vuelidate/lib/validators';
+
+const isoDateRegex = /([12]\d{3}-(0[1-9]|1[0-2])-(0[1-9]|[12]\d|3[01]))/;
+const isoTimeRegex = /^(0[0-9]|1[0-9]|2[0-3]):[0-5][0-9]$/;
+
+export default {
+  name: 'DateTime',
+  components: { Alert, IconCalendar, PageTitle, PageSection },
+  mixins: [
+    BVToastMixin,
+    LoadingBarMixin,
+    LocalTimezoneLabelMixin,
+    VuelidateMixin,
+  ],
+  beforeRouteLeave(to, from, next) {
+    this.hideLoader();
+    next();
+  },
+  data() {
+    return {
+      locale: this.$store.getters['global/languagePreference'],
+      form: {
+        configurationSelected: 'manual',
+        manual: {
+          date: '',
+          time: '',
+        },
+        ntp: { firstAddress: '', secondAddress: '', thirdAddress: '' },
+      },
+      loading,
+    };
+  },
+  validations() {
+    return {
+      form: {
+        manual: {
+          date: {
+            required: requiredIf(function () {
+              return this.form.configurationSelected === 'manual';
+            }),
+            pattern: helpers.regex('pattern', isoDateRegex),
+          },
+          time: {
+            required: requiredIf(function () {
+              return this.form.configurationSelected === 'manual';
+            }),
+            pattern: helpers.regex('pattern', isoTimeRegex),
+          },
+        },
+        ntp: {
+          firstAddress: {
+            required: requiredIf(function () {
+              return this.form.configurationSelected === 'ntp';
+            }),
+          },
+        },
+      },
+    };
+  },
+  computed: {
+    ...mapState('dateTime', ['ntpServers', 'isNtpProtocolEnabled']),
+    bmcTime() {
+      return this.$store.getters['global/bmcTime'];
+    },
+    ntpOptionSelected() {
+      return this.form.configurationSelected === 'ntp';
+    },
+    manualOptionSelected() {
+      return this.form.configurationSelected === 'manual';
+    },
+    isUtcDisplay() {
+      return this.$store.getters['global/isUtcDisplay'];
+    },
+    timezone() {
+      if (this.isUtcDisplay) {
+        return 'UTC';
+      }
+      return this.localOffset();
+    },
+  },
+  watch: {
+    ntpServers() {
+      this.setNtpValues();
+    },
+    manualDate() {
+      this.emitChange();
+    },
+    bmcTime() {
+      this.form.manual.date = this.$options.filters.formatDate(
+        this.$store.getters['global/bmcTime']
+      );
+      this.form.manual.time = this.$options.filters
+        .formatTime(this.$store.getters['global/bmcTime'])
+        .slice(0, 5);
+    },
+  },
+  created() {
+    this.startLoader();
+    this.setNtpValues();
+    Promise.all([
+      this.$store.dispatch('global/getBmcTime'),
+      this.$store.dispatch('dateTime/getNtpData'),
+    ]).finally(() => this.endLoader());
+  },
+  methods: {
+    emitChange() {
+      if (this.$v.$invalid) return;
+      this.$v.$reset(); //reset to re-validate on blur
+      this.$emit('change', {
+        manualDate: this.manualDate ? new Date(this.manualDate) : null,
+      });
+    },
+    setNtpValues() {
+      this.form.configurationSelected = this.isNtpProtocolEnabled
+        ? 'ntp'
+        : 'manual';
+      [
+        this.form.ntp.firstAddress = '',
+        this.form.ntp.secondAddress = '',
+        this.form.ntp.thirdAddress = '',
+      ] = [this.ntpServers[0], this.ntpServers[1], this.ntpServers[2]];
+    },
+    submitForm() {
+      this.$v.$touch();
+      if (this.$v.$invalid) return;
+      this.startLoader();
+
+      let dateTimeForm = {};
+      let isNTPEnabled = this.form.configurationSelected === 'ntp';
+
+      if (!isNTPEnabled) {
+        const isUtcDisplay = this.$store.getters['global/isUtcDisplay'];
+        let date;
+
+        dateTimeForm.ntpProtocolEnabled = false;
+
+        if (isUtcDisplay) {
+          // Create UTC Date
+          date = this.getUtcDate(this.form.manual.date, this.form.manual.time);
+        } else {
+          // Create local Date
+          date = new Date(`${this.form.manual.date} ${this.form.manual.time}`);
+        }
+
+        dateTimeForm.updatedDateTime = date.toISOString();
+      } else {
+        dateTimeForm.ntpProtocolEnabled = true;
+
+        dateTimeForm.ntpServersArray = [
+          this.form.ntp.firstAddress,
+          this.form.ntp.secondAddress,
+          this.form.ntp.thirdAddress,
+        ];
+      }
+
+      this.$store
+        .dispatch('dateTime/updateDateTime', dateTimeForm)
+        .then((success) => {
+          this.successToast(success);
+          if (!isNTPEnabled) return;
+          // Shift address up if second address is empty
+          // to avoid refreshing after delay when updating NTP
+          if (!this.form.ntp.secondAddress && this.form.ntp.thirdAddres) {
+            this.form.ntp.secondAddress = this.form.ntp.thirdAddres;
+            this.form.ntp.thirdAddress = '';
+          }
+        })
+        .then(() => {
+          this.$store.dispatch('global/getBmcTime');
+        })
+        .catch(({ message }) => this.errorToast(message))
+        .finally(() => {
+          this.$v.form.$reset();
+          this.endLoader();
+        });
+    },
+    getUtcDate(date, time) {
+      // Split user input string values to create
+      // a UTC Date object
+      const datesArray = date.split('-');
+      const timeArray = time.split(':');
+      let utcDate = Date.UTC(
+        datesArray[0], // User input year
+        //UTC expects zero-index month value 0-11 (January-December)
+        //for reference https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Date/UTC#Parameters
+        parseInt(datesArray[1]) - 1, // User input month
+        datesArray[2], // User input day
+        timeArray[0], // User input hour
+        timeArray[1] // User input minute
+      );
+      return new Date(utcDate);
+    },
+  },
+};
+</script>
diff --git a/src/views/Settings/DateTime/index.js b/src/views/Settings/DateTime/index.js
new file mode 100644
index 0000000..2df21ea
--- /dev/null
+++ b/src/views/Settings/DateTime/index.js
@@ -0,0 +1,2 @@
+import DateTime from './DateTime.vue';
+export default DateTime;
diff --git a/src/views/Settings/Network/Network.vue b/src/views/Settings/Network/Network.vue
new file mode 100644
index 0000000..ab5003f
--- /dev/null
+++ b/src/views/Settings/Network/Network.vue
@@ -0,0 +1,664 @@
+<template>
+  <b-container fluid="xl">
+    <page-title :description="$t('pageNetwork.pageDescription')" />
+    <page-section :section-title="$t('pageNetwork.interface')">
+      <b-row>
+        <b-col lg="3">
+          <b-form-group
+            label-for="interface-select"
+            :label="$t('pageNetwork.form.networkInterface')"
+          >
+            <b-form-select
+              id="interface-select"
+              v-model="selectedInterfaceIndex"
+              :disabled="loading"
+              data-test-id="network-select-interface"
+              :options="interfaceSelectOptions"
+              @change="selectInterface"
+            >
+            </b-form-select>
+          </b-form-group>
+        </b-col>
+      </b-row>
+    </page-section>
+    <b-form novalidate @submit.prevent="submitForm">
+      <b-form-group :disabled="loading">
+        <page-section :section-title="$t('pageNetwork.system')">
+          <b-row>
+            <b-col lg="3">
+              <b-form-group
+                :label="$t('pageNetwork.form.defaultGateway')"
+                label-for="default-gateway"
+              >
+                <b-form-input
+                  id="default-gateway"
+                  v-model.trim="form.gateway"
+                  data-test-id="network-input-gateway"
+                  type="text"
+                  :state="getValidationState($v.form.gateway)"
+                  @change="$v.form.gateway.$touch()"
+                />
+                <b-form-invalid-feedback role="alert">
+                  <div v-if="!$v.form.gateway.required">
+                    {{ $t('global.form.fieldRequired') }}
+                  </div>
+                  <div v-if="!$v.form.gateway.ipAddress">
+                    {{ $t('global.form.invalidFormat') }}
+                  </div>
+                </b-form-invalid-feedback>
+              </b-form-group>
+            </b-col>
+            <b-col lg="3">
+              <b-form-group
+                :label="$t('pageNetwork.form.hostname')"
+                label-for="hostname-field"
+              >
+                <b-form-input
+                  id="hostname-field"
+                  v-model.trim="form.hostname"
+                  data-test-id="network-input-hostname"
+                  type="text"
+                  :state="getValidationState($v.form.hostname)"
+                  @change="$v.form.hostname.$touch()"
+                />
+                <b-form-invalid-feedback role="alert">
+                  <div v-if="!$v.form.hostname.required">
+                    {{ $t('global.form.fieldRequired') }}
+                  </div>
+                  <div v-if="!$v.form.hostname.validateHostname">
+                    {{
+                      $t('global.form.lengthMustBeBetween', { min: 1, max: 64 })
+                    }}
+                  </div>
+                </b-form-invalid-feedback>
+              </b-form-group>
+            </b-col>
+            <b-col lg="3">
+              <b-form-group
+                :label="$t('pageNetwork.form.macAddress')"
+                label-for="mac-address"
+              >
+                <b-form-input
+                  id="mac-address"
+                  v-model.trim="form.macAddress"
+                  data-test-id="network-input-macAddress"
+                  type="text"
+                  :state="getValidationState($v.form.macAddress)"
+                  @change="$v.form.macAddress.$touch()"
+                />
+                <b-form-invalid-feedback role="alert">
+                  <div v-if="!$v.form.macAddress.required">
+                    {{ $t('global.form.fieldRequired') }}
+                  </div>
+                  <div v-if="!$v.form.macAddress.macAddress">
+                    {{ $t('global.form.invalidFormat') }}
+                  </div>
+                </b-form-invalid-feedback>
+              </b-form-group>
+            </b-col>
+          </b-row>
+        </page-section>
+        <page-section :section-title="$t('pageNetwork.ipv4')">
+          <b-form-group :label="$t('pageNetwork.ipv4Configuration')">
+            <b-form-text id="enable-secure-help-block">
+              {{ $t('pageNetwork.ipv4Helper') }}
+            </b-form-text>
+            <b-form-radio
+              v-model="form.dhcpEnabled"
+              name="dhcp-radio"
+              :value="true"
+              @change="onChangeIpv4Config"
+            >
+              {{ $t('pageNetwork.dhcp') }}
+            </b-form-radio>
+            <b-form-radio
+              v-model="form.dhcpEnabled"
+              name="static-radio"
+              :value="false"
+              @change="onChangeIpv4Config"
+            >
+              {{ $t('pageNetwork.static') }}
+            </b-form-radio>
+          </b-form-group>
+          <b-row>
+            <b-col lg="9" class="mb-3">
+              <h3 class="h4">
+                {{ $t('pageNetwork.dhcp') }}
+              </h3>
+              <b-table
+                responsive="md"
+                hover
+                :fields="ipv4DhcpTableFields"
+                :items="form.ipv4DhcpTableItems"
+                :empty-text="$t('global.table.emptyMessage')"
+                class="mb-0"
+                show-empty
+              >
+                <template #cell(Address)="{ item, index }">
+                  <b-form-input
+                    v-model.trim="item.Address"
+                    :data-test-id="`network-input-dhcpIpv4-${index}`"
+                    :aria-label="
+                      $t('pageNetwork.table.dhcpIpv4AddressRow') +
+                      ' ' +
+                      (index + 1)
+                    "
+                    readonly
+                  />
+                </template>
+                <template #cell(SubnetMask)="{ item, index }">
+                  <b-form-input
+                    v-model.trim="item.SubnetMask"
+                    :data-test-id="`network-input-subnetMask-${index}`"
+                    :aria-label="
+                      $t('pageNetwork.table.dhcpIpv4SubnetRow') +
+                      ' ' +
+                      (index + 1)
+                    "
+                    readonly
+                  />
+                </template>
+                <template #cell(actions)="{ item, index }">
+                  <table-row-action
+                    v-for="(action, actionIndex) in item.actions"
+                    :key="actionIndex"
+                    :value="action.value"
+                    :title="action.title"
+                    :enabled="false"
+                    @click-table-action="
+                      onDeleteIpv4StaticTableRow($event, index)
+                    "
+                  >
+                    <template #icon>
+                      <icon-trashcan v-if="action.value === 'delete'" />
+                    </template>
+                  </table-row-action>
+                </template>
+              </b-table>
+            </b-col>
+            <b-col lg="9" class="mb-3">
+              <h3 class="h4">
+                {{ $t('pageNetwork.static') }}
+              </h3>
+              <b-table
+                responsive="md"
+                hover
+                :fields="ipv4StaticTableFields"
+                :items="form.ipv4StaticTableItems"
+                :empty-text="$t('global.table.emptyMessage')"
+                class="mb-0"
+                show-empty
+              >
+                <template #cell(Address)="{ item, index }">
+                  <b-form-input
+                    v-model.trim="item.Address"
+                    :data-test-id="`network-input-staticIpv4-${index}`"
+                    :aria-label="
+                      $t('pageNetwork.table.staticIpv4AddressRow') +
+                      ' ' +
+                      (index + 1)
+                    "
+                    :state="
+                      getValidationState(
+                        $v.form.ipv4StaticTableItems.$each.$iter[index].Address
+                      )
+                    "
+                    @change="
+                      $v.form.ipv4StaticTableItems.$each.$iter[
+                        index
+                      ].Address.$touch()
+                    "
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div
+                      v-if="
+                        !$v.form.ipv4StaticTableItems.$each.$iter[index].Address
+                          .required
+                      "
+                    >
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                    <div
+                      v-if="
+                        !$v.form.ipv4StaticTableItems.$each.$iter[index].Address
+                          .ipAddress
+                      "
+                    >
+                      {{ $t('global.form.invalidFormat') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                </template>
+                <template #cell(SubnetMask)="{ item, index }">
+                  <b-form-input
+                    v-model.trim="item.SubnetMask"
+                    :data-test-id="`network-input-subnetMask-${index}`"
+                    :aria-label="
+                      $t('pageNetwork.table.staticIpv4SubnetRow') +
+                      ' ' +
+                      (index + 1)
+                    "
+                    :state="
+                      getValidationState(
+                        $v.form.ipv4StaticTableItems.$each.$iter[index]
+                          .SubnetMask
+                      )
+                    "
+                    @change="
+                      $v.form.ipv4StaticTableItems.$each.$iter[
+                        index
+                      ].SubnetMask.$touch()
+                    "
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div
+                      v-if="
+                        !$v.form.ipv4StaticTableItems.$each.$iter[index]
+                          .SubnetMask.required
+                      "
+                    >
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                    <div
+                      v-if="
+                        !$v.form.ipv4StaticTableItems.$each.$iter[index]
+                          .SubnetMask.ipAddress
+                      "
+                    >
+                      {{ $t('global.form.invalidFormat') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                </template>
+                <template #cell(actions)="{ item, index }">
+                  <table-row-action
+                    v-for="(action, actionIndex) in item.actions"
+                    :key="actionIndex"
+                    :value="action.value"
+                    :title="action.title"
+                    @click-table-action="
+                      onDeleteIpv4StaticTableRow($event, index)
+                    "
+                  >
+                    <template #icon>
+                      <icon-trashcan v-if="action.value === 'delete'" />
+                    </template>
+                  </table-row-action>
+                </template>
+              </b-table>
+              <b-button variant="link" @click="addIpv4StaticTableRow">
+                <icon-add />
+                {{ $t('pageNetwork.table.addStaticIpv4Address') }}
+              </b-button>
+            </b-col>
+          </b-row>
+        </page-section>
+        <page-section :section-title="$t('pageNetwork.staticDns')">
+          <b-row>
+            <b-col lg="4" class="mb-3">
+              <b-table
+                responsive
+                hover
+                :fields="dnsTableFields"
+                :items="form.dnsStaticTableItems"
+                :empty-text="$t('global.table.emptyMessage')"
+                class="mb-0"
+                show-empty
+              >
+                <template #cell(address)="{ item, index }">
+                  <b-form-input
+                    v-model.trim="item.address"
+                    :data-test-id="`network-input-dnsAddress-${index}`"
+                    :aria-label="
+                      $t('pageNetwork.table.staticDnsRow') + ' ' + (index + 1)
+                    "
+                    :state="
+                      getValidationState(
+                        $v.form.dnsStaticTableItems.$each.$iter[index].address
+                      )
+                    "
+                    @change="
+                      $v.form.dnsStaticTableItems.$each.$iter[
+                        index
+                      ].address.$touch()
+                    "
+                  />
+                  <b-form-invalid-feedback role="alert">
+                    <div
+                      v-if="
+                        !$v.form.dnsStaticTableItems.$each.$iter[index].address
+                          .required
+                      "
+                    >
+                      {{ $t('global.form.fieldRequired') }}
+                    </div>
+                    <div
+                      v-if="
+                        !$v.form.dnsStaticTableItems.$each.$iter[index].address
+                          .ipAddress
+                      "
+                    >
+                      {{ $t('global.form.invalidFormat') }}
+                    </div>
+                  </b-form-invalid-feedback>
+                </template>
+                <template #cell(actions)="{ item, index }">
+                  <table-row-action
+                    v-for="(action, actionIndex) in item.actions"
+                    :key="actionIndex"
+                    :value="action.value"
+                    :title="action.title"
+                    @click-table-action="onDeleteDnsTableRow($event, index)"
+                  >
+                    <template #icon>
+                      <icon-trashcan v-if="action.value === 'delete'" />
+                    </template>
+                  </table-row-action>
+                </template>
+              </b-table>
+              <b-button variant="link" @click="addDnsTableRow">
+                <icon-add /> {{ $t('pageNetwork.table.addDns') }}
+              </b-button>
+            </b-col>
+          </b-row>
+        </page-section>
+        <b-button
+          variant="primary"
+          type="submit"
+          data-test-id="network-button-saveNetworkSettings"
+        >
+          {{ $t('global.action.saveSettings') }}
+        </b-button>
+      </b-form-group>
+    </b-form>
+  </b-container>
+</template>
+
+<script>
+import IconTrashcan from '@carbon/icons-vue/es/trash-can/20';
+import IconAdd from '@carbon/icons-vue/es/add--alt/20';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+import LoadingBarMixin, { loading } from '@/components/Mixins/LoadingBarMixin';
+import PageSection from '@/components/Global/PageSection';
+import PageTitle from '@/components/Global/PageTitle';
+import TableRowAction from '@/components/Global/TableRowAction';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin';
+import { mapState } from 'vuex';
+import {
+  required,
+  helpers,
+  ipAddress,
+  macAddress,
+} from 'vuelidate/lib/validators';
+
+// Hostname pattern
+const validateHostname = helpers.regex('validateHostname', /^\S{0,64}$/);
+
+export default {
+  name: 'Network',
+  components: {
+    PageTitle,
+    PageSection,
+    TableRowAction,
+    IconTrashcan,
+    IconAdd,
+  },
+  mixins: [BVToastMixin, VuelidateMixin, LoadingBarMixin],
+  beforeRouteLeave(to, from, next) {
+    this.hideLoader();
+    next();
+  },
+  data() {
+    return {
+      ipv4DhcpTableFields: [
+        {
+          key: 'Address',
+          label: this.$t('pageNetwork.table.ipAddress'),
+        },
+        {
+          key: 'SubnetMask',
+          label: this.$t('pageNetwork.table.subnet'),
+        },
+        { key: 'actions', label: '', tdClass: 'text-right' },
+      ],
+      ipv4StaticTableFields: [
+        {
+          key: 'Address',
+          label: this.$t('pageNetwork.table.ipAddress'),
+        },
+        {
+          key: 'SubnetMask',
+          label: this.$t('pageNetwork.table.subnet'),
+        },
+        { key: 'actions', label: '', tdClass: 'text-right' },
+      ],
+      dnsTableFields: [
+        {
+          key: 'address',
+          label: this.$t('pageNetwork.table.ipAddress'),
+        },
+        { key: 'actions', label: '', tdClass: 'text-right' },
+      ],
+      selectedInterfaceIndex: 0,
+      selectedInterface: {},
+      form: {
+        dhcpEnabled: null,
+        gateway: '',
+        hostname: '',
+        macAddress: '',
+        ipv4StaticTableItems: [],
+        ipv4DhcpTableItems: [],
+        dnsStaticTableItems: [],
+      },
+      loading,
+    };
+  },
+  validations() {
+    return {
+      form: {
+        gateway: { required, ipAddress },
+        hostname: { required, validateHostname },
+        ipv4StaticTableItems: {
+          $each: {
+            Address: {
+              required,
+              ipAddress,
+            },
+            SubnetMask: {
+              required,
+              ipAddress,
+            },
+          },
+        },
+        macAddress: { required, macAddress: macAddress() },
+        dnsStaticTableItems: {
+          $each: {
+            address: {
+              required,
+              ipAddress,
+            },
+          },
+        },
+      },
+    };
+  },
+  computed: {
+    ...mapState('network', [
+      'ethernetData',
+      'interfaceOptions',
+      'defaultGateway',
+    ]),
+    interfaceSelectOptions() {
+      return this.interfaceOptions.map((option, index) => {
+        return {
+          text: option,
+          value: index,
+        };
+      });
+    },
+  },
+  watch: {
+    ethernetData: function () {
+      this.selectInterface();
+    },
+  },
+  created() {
+    this.startLoader();
+    this.$store
+      .dispatch('network/getEthernetData')
+      .finally(() => this.endLoader());
+  },
+  methods: {
+    selectInterface() {
+      this.selectedInterface = this.ethernetData[this.selectedInterfaceIndex];
+      this.getIpv4DhcpTableItems();
+      this.getIpv4StaticTableItems();
+      this.getDnsStaticTableItems();
+      this.getInterfaceSettings();
+    },
+    getInterfaceSettings() {
+      this.form.gateway = this.defaultGateway;
+      this.form.hostname = this.selectedInterface.HostName;
+      this.form.macAddress = this.selectedInterface.MACAddress;
+      this.form.dhcpEnabled = this.selectedInterface.DHCPv4.DHCPEnabled;
+    },
+    onChangeIpv4Config(value) {
+      this.form.dhcpEnabled = value;
+    },
+    getDnsStaticTableItems() {
+      const dns = this.selectedInterface.StaticNameServers || [];
+      this.form.dnsStaticTableItems = dns.map((server) => {
+        return {
+          address: server,
+          actions: [
+            {
+              value: 'delete',
+              enabled: this.form.dhcpEnabled,
+              title: this.$t('pageNetwork.table.deleteDns'),
+            },
+          ],
+        };
+      });
+    },
+    addDnsTableRow() {
+      this.$v.form.dnsStaticTableItems.$touch();
+      this.form.dnsStaticTableItems.push({
+        address: '',
+        actions: [
+          {
+            value: 'delete',
+            enabled: this.form.dhcpEnabled,
+            title: this.$t('pageNetwork.table.deleteDns'),
+          },
+        ],
+      });
+    },
+    deleteDnsTableRow(index) {
+      this.$v.form.dnsStaticTableItems.$touch();
+      this.form.dnsStaticTableItems.splice(index, 1);
+    },
+    onDeleteDnsTableRow(action, row) {
+      this.deleteDnsTableRow(row);
+    },
+    getIpv4DhcpTableItems() {
+      const addresses = this.selectedInterface.IPv4Addresses || [];
+      this.form.ipv4DhcpTableItems = addresses
+        .filter((ipv4) => ipv4.AddressOrigin === 'DHCP')
+        .map((ipv4) => {
+          return {
+            Address: ipv4.Address,
+            SubnetMask: ipv4.SubnetMask,
+            actions: [
+              {
+                value: 'delete',
+                enabled: false,
+                title: this.$t('pageNetwork.table.deleteDhcpIpv4'),
+              },
+            ],
+          };
+        });
+    },
+    getIpv4StaticTableItems() {
+      const addresses = this.selectedInterface.IPv4StaticAddresses || [];
+      this.form.ipv4StaticTableItems = addresses.map((ipv4) => {
+        return {
+          Address: ipv4.Address,
+          SubnetMask: ipv4.SubnetMask,
+          actions: [
+            {
+              value: 'delete',
+              enabled: this.form.dhcpEnabled,
+              title: this.$t('pageNetwork.table.deleteStaticIpv4'),
+            },
+          ],
+        };
+      });
+    },
+    addIpv4StaticTableRow() {
+      this.$v.form.ipv4StaticTableItems.$touch();
+      this.form.ipv4StaticTableItems.push({
+        Address: '',
+        SubnetMask: '',
+        actions: [
+          {
+            value: 'delete',
+            enabled: this.form.dhcpEnabled,
+            title: this.$t('pageNetwork.table.deleteStaticIpv4'),
+          },
+        ],
+      });
+    },
+    deleteIpv4StaticTableRow(index) {
+      this.$v.form.ipv4StaticTableItems.$touch();
+      this.form.ipv4StaticTableItems.splice(index, 1);
+    },
+    onDeleteIpv4StaticTableRow(action, row) {
+      this.deleteIpv4StaticTableRow(row);
+    },
+    submitForm() {
+      this.$v.$touch();
+      if (this.$v.$invalid) return;
+      this.startLoader();
+      let networkInterfaceSelected = this.selectedInterface;
+      let selectedInterfaceIndex = this.selectedInterfaceIndex;
+      let interfaceId = networkInterfaceSelected.Id;
+      let isDhcpEnabled = this.form.dhcpEnabled;
+      let macAddress = this.form.macAddress;
+      let hostname = this.form.hostname;
+      let networkSettingsForm = {
+        interfaceId,
+        hostname,
+        macAddress,
+        selectedInterfaceIndex,
+      };
+      // Enabling DHCP without any available IP addresses will bring network down
+      if (this.form.ipv4DhcpTableItems.length) {
+        networkSettingsForm.isDhcpEnabled = isDhcpEnabled;
+      } else {
+        networkSettingsForm.isDhcpEnabled = false;
+        this.errorToast(this.$t('pageNetwork.toast.errorSaveDhcpSettings'));
+      }
+      networkSettingsForm.staticIpv4 = this.form.ipv4StaticTableItems.map(
+        (updateIpv4) => {
+          delete updateIpv4.actions;
+          updateIpv4.Gateway = this.form.gateway;
+          return updateIpv4;
+        }
+      );
+      networkSettingsForm.staticNameServers = this.form.dnsStaticTableItems.map(
+        (updateDns) => {
+          return updateDns.address;
+        }
+      );
+      this.$store
+        .dispatch('network/updateInterfaceSettings', networkSettingsForm)
+        .then((success) => {
+          this.successToast(success);
+        })
+        .catch(({ message }) => this.errorToast(message))
+        .finally(() => {
+          this.$v.form.$reset();
+          this.endLoader();
+        });
+    },
+  },
+};
+</script>
diff --git a/src/views/Settings/Network/index.js b/src/views/Settings/Network/index.js
new file mode 100644
index 0000000..97bf039
--- /dev/null
+++ b/src/views/Settings/Network/index.js
@@ -0,0 +1,2 @@
+import Network from './Network.vue';
+export default Network;
diff --git a/src/views/Settings/PowerRestorePolicy/PowerRestorePolicy.vue b/src/views/Settings/PowerRestorePolicy/PowerRestorePolicy.vue
new file mode 100644
index 0000000..8589aed
--- /dev/null
+++ b/src/views/Settings/PowerRestorePolicy/PowerRestorePolicy.vue
@@ -0,0 +1,80 @@
+<template>
+  <b-container fluid="xl">
+    <page-title :description="$t('pagePowerRestorePolicy.description')" />
+
+    <b-row>
+      <b-col sm="8" md="6" xl="12">
+        <b-form-group :label="$t('pagePowerRestorePolicy.powerPoliciesLabel')">
+          <b-form-radio
+            v-for="policy in powerRestorePolicies"
+            :key="policy.state"
+            v-model="currentPowerRestorePolicy"
+            :value="policy.state"
+            name="power-restore-policy"
+          >
+            {{ policy.desc }}
+          </b-form-radio>
+        </b-form-group>
+      </b-col>
+    </b-row>
+
+    <b-button variant="primary" type="submit" @click="submitForm">
+      {{ $t('global.action.saveSettings') }}
+    </b-button>
+  </b-container>
+</template>
+
+<script>
+import PageTitle from '@/components/Global/PageTitle';
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import VuelidateMixin from '@/components/Mixins/VuelidateMixin.js';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+
+export default {
+  name: 'PowerRestorePolicy',
+  components: { PageTitle },
+  mixins: [VuelidateMixin, BVToastMixin, LoadingBarMixin],
+  beforeRouteLeave(to, from, next) {
+    this.hideLoader();
+    next();
+  },
+  data() {
+    return {
+      policyValue: null,
+    };
+  },
+  computed: {
+    powerRestorePolicies() {
+      return this.$store.getters['powerPolicy/powerRestorePolicies'];
+    },
+    currentPowerRestorePolicy: {
+      get() {
+        return this.$store.getters['powerPolicy/powerRestoreCurrentPolicy'];
+      },
+      set(policy) {
+        this.policyValue = policy;
+      },
+    },
+  },
+  created() {
+    this.startLoader();
+    Promise.all([
+      this.$store.dispatch('powerPolicy/getPowerRestorePolicies'),
+      this.$store.dispatch('powerPolicy/getPowerRestoreCurrentPolicy'),
+    ]).finally(() => this.endLoader());
+  },
+  methods: {
+    submitForm() {
+      this.startLoader();
+      this.$store
+        .dispatch(
+          'powerPolicy/setPowerRestorePolicy',
+          this.policyValue || this.currentPowerRestorePolicy
+        )
+        .then((message) => this.successToast(message))
+        .catch(({ message }) => this.errorToast(message))
+        .finally(() => this.endLoader());
+    },
+  },
+};
+</script>
diff --git a/src/views/Settings/PowerRestorePolicy/index.js b/src/views/Settings/PowerRestorePolicy/index.js
new file mode 100644
index 0000000..fab0d47
--- /dev/null
+++ b/src/views/Settings/PowerRestorePolicy/index.js
@@ -0,0 +1,2 @@
+import PowerRestorePolicy from './PowerRestorePolicy.vue';
+export default PowerRestorePolicy;
diff --git a/src/views/Settings/SecuritySettings/SecuritySettings.vue b/src/views/Settings/SecuritySettings/SecuritySettings.vue
new file mode 100644
index 0000000..ec8d258
--- /dev/null
+++ b/src/views/Settings/SecuritySettings/SecuritySettings.vue
@@ -0,0 +1,125 @@
+<template>
+  <b-container fluid="xl">
+    <page-title />
+    <b-row>
+      <b-col md="8">
+        <page-section
+          :section-title="$t('pageSecuritySettings.networkServices')"
+        >
+          <b-row class="setting-section">
+            <b-col class="d-flex align-items-center justify-content-between">
+              <dl class="mr-3 w-75">
+                <dt>{{ $t('pageSecuritySettings.ssh') }}</dt>
+                <dd>
+                  {{ $t('pageSecuritySettings.sshDescription') }}
+                </dd>
+              </dl>
+              <b-form-checkbox
+                id="sshSwitch"
+                v-model="sshProtocolState"
+                data-test-id="security-toggle-bmcShell"
+                switch
+                @change="changeSshProtocolState"
+              >
+                <span class="sr-only">
+                  {{ $t('pageSecuritySettings.ssh') }}
+                </span>
+                <span v-if="sshProtocolState">
+                  {{ $t('global.status.enabled') }}
+                </span>
+                <span v-else>{{ $t('global.status.disabled') }}</span>
+              </b-form-checkbox>
+            </b-col>
+          </b-row>
+          <b-row class="setting-section">
+            <b-col class="d-flex align-items-center justify-content-between">
+              <dl class="mt-3 mr-3 w-75">
+                <dt>{{ $t('pageSecuritySettings.ipmi') }}</dt>
+                <dd>
+                  {{ $t('pageSecuritySettings.ipmiDescription') }}
+                </dd>
+              </dl>
+              <b-form-checkbox
+                id="ipmiSwitch"
+                v-model="ipmiProtocolState"
+                data-test-id="security-toggle-networkIpmi"
+                switch
+                @change="changeIpmiProtocolState"
+              >
+                <span class="sr-only">
+                  {{ $t('pageSecuritySettings.ipmi') }}
+                </span>
+                <span v-if="ipmiProtocolState">
+                  {{ $t('global.status.enabled') }}
+                </span>
+                <span v-else>{{ $t('global.status.disabled') }}</span>
+              </b-form-checkbox>
+            </b-col>
+          </b-row>
+        </page-section>
+      </b-col>
+    </b-row>
+  </b-container>
+</template>
+
+<script>
+import PageSection from '@/components/Global/PageSection';
+import PageTitle from '@/components/Global/PageTitle';
+
+import LoadingBarMixin from '@/components/Mixins/LoadingBarMixin';
+import BVToastMixin from '@/components/Mixins/BVToastMixin';
+
+export default {
+  name: 'SecuritySettings',
+  components: { PageTitle, PageSection },
+  mixins: [LoadingBarMixin, BVToastMixin],
+  beforeRouteLeave(to, from, next) {
+    this.hideLoader();
+    next();
+  },
+  computed: {
+    sshProtocolState: {
+      get() {
+        return this.$store.getters['securitySettings/sshProtocolEnabled'];
+      },
+      set(newValue) {
+        return newValue;
+      },
+    },
+    ipmiProtocolState: {
+      get() {
+        return this.$store.getters['securitySettings/ipmiProtocolEnabled'];
+      },
+      set(newValue) {
+        return newValue;
+      },
+    },
+  },
+  created() {
+    this.startLoader();
+    this.$store
+      .dispatch('securitySettings/getNetworkProtocolStatus')
+      .finally(() => this.endLoader());
+  },
+  methods: {
+    changeIpmiProtocolState(state) {
+      this.$store
+        .dispatch('securitySettings/saveIpmiProtocolState', state)
+        .then((message) => this.successToast(message))
+        .catch(({ message }) => this.errorToast(message));
+    },
+    changeSshProtocolState(state) {
+      this.$store
+        .dispatch('securitySettings/saveSshProtocolState', state)
+        .then((message) => this.successToast(message))
+        .catch(({ message }) => this.errorToast(message));
+    },
+  },
+};
+</script>
+
+<style lang="scss" scoped>
+.setting-section {
+  border-bottom: 1px solid gray('300');
+}
+</style>
diff --git a/src/views/Settings/SecuritySettings/index.js b/src/views/Settings/SecuritySettings/index.js
new file mode 100644
index 0000000..5ec2b61
--- /dev/null
+++ b/src/views/Settings/SecuritySettings/index.js
@@ -0,0 +1,2 @@
+import SecuritySettings from './SecuritySettings.vue';
+export default SecuritySettings;