summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDixsie Wolmers <dixsie@ibm.com>2020-12-07 22:12:53 +0300
committerDerick Montague <derick.montague@ibm.com>2020-12-16 02:11:26 +0300
commit8f030bac11637fcd0a005907b558d7accbff68bd (patch)
treef9eb7487b4b1578e17d74e8bfdae97622ce9fc3b
parent645250b918ccc1d3965824a1c259d0367f6691b1 (diff)
downloadwebui-vue-8f030bac11637fcd0a005907b558d7accbff68bd.tar.xz
Add security settings page
Adds ability to enable/disable: - SSH protocol - IPMI protocol Signed-off-by: Dixsie Wolmers <dixsie@ibm.com> Change-Id: I2430a46343dd8756ef75fcc3cb068df8d51dd415
-rw-r--r--src/components/AppNavigation/AppNavigationMixin.js5
-rw-r--r--src/locales/en-US.json29
-rw-r--r--src/router/routes.js9
-rw-r--r--src/store/index.js2
-rw-r--r--src/store/modules/Configuration/SecuritySettingsStore.js95
-rw-r--r--src/views/Configuration/SecuritySettings/SecuritySettings.vue125
-rw-r--r--src/views/Configuration/SecuritySettings/index.js2
7 files changed, 267 insertions, 0 deletions
diff --git a/src/components/AppNavigation/AppNavigationMixin.js b/src/components/AppNavigation/AppNavigationMixin.js
index f0691a57..b163d75e 100644
--- a/src/components/AppNavigation/AppNavigationMixin.js
+++ b/src/components/AppNavigation/AppNavigationMixin.js
@@ -108,6 +108,11 @@ const AppNavigationMixin = {
route: '/configuration/network-settings',
},
{
+ id: 'security-settings',
+ label: this.$t('appNavigation.securitySettings'),
+ route: '/configuration/security-settings',
+ },
+ {
id: 'snmp-settings',
label: this.$t('appNavigation.snmpSettings'),
route: '/snmp-settings',
diff --git a/src/locales/en-US.json b/src/locales/en-US.json
index fb0d45a4..0e28de51 100644
--- a/src/locales/en-US.json
+++ b/src/locales/en-US.json
@@ -110,6 +110,7 @@
"overview": "@:appPageTitle.overview",
"primaryNavigation": "Primary navigation",
"rebootBmc": "@:appPageTitle.rebootBmc",
+ "securitySettings": "@:appPageTitle.securitySettings",
"sensors": "@:appPageTitle.sensors",
"serialOverLan": "SOL console",
"serverLed": "@:appPageTitle.serverLed",
@@ -134,6 +135,7 @@
"pageNotFound": "Page not found",
"profileSettings": "Profile settings",
"rebootBmc": "Reboot BMC",
+ "securitySettings": "Security settings",
"sensors": "Sensors",
"serialOverLan": "Serial over LAN (SOL) console",
"serverLed": "Server LED",
@@ -546,6 +548,33 @@
"successRebootStart": "Rebooting BMC."
}
},
+ "pageSecuritySettings": {
+ "ipmi": "Network IPMI (out-of-band IPMI)",
+ "ipmiDescription": "Allow remote management of the platform via IPMI. Tools such as ipmitool require this setting to be enabled.",
+ "networkServices": "Network services",
+ "ssh": "SSH port 22 (BMC shell)",
+ "sshDescription": "SSH access to the BMC's command shell. Disabling this will disable users' ability to connect BMC shell via SSH.",
+ "modal": {
+ "disableMessage": {
+ "ipmi": "Are you sure you want to disable @:pageSecuritySettings.ipmi?",
+ "ssh": "Are you sure you want to disable @:pageSecuritySettings.ssh?"
+ },
+ "enableMessage": {
+ "ipmi": "Are you sure you want to enable @:pageSecuritySettings.ipmi?",
+ "ssh": "Are you sure you want to enable @:pageSecuritySettings.ssh?"
+ }
+ },
+ "toast": {
+ "errorIpmiDisabled": "Error disabling IPMI security setting.",
+ "errorIpmiEnabled":"Error enabling IPMI security setting.",
+ "errorSshDisabled":"Error disabling SSH security setting.",
+ "errorSshEnabled": "Error enabling SSH security setting.",
+ "successIpmiDisabled": "Successfully disabled IPMI security setting.",
+ "successIpmiEnabled": "Successfully enabled IPMI security setting.",
+ "successSshDisabled": "Successfully disabled SSH security setting.",
+ "successSshEnabled": "Successfully enabled SSH security setting."
+ }
+ },
"pageSensors": {
"exportFilePrefix": "sensors_",
"searchForSensors": "Search for sensors",
diff --git a/src/router/routes.js b/src/router/routes.js
index 3be1a1e4..a82833ad 100644
--- a/src/router/routes.js
+++ b/src/router/routes.js
@@ -17,6 +17,7 @@ import Overview from '@/views/Overview';
import PageNotFound from '@/views/PageNotFound';
import ProfileSettings from '@/views/ProfileSettings';
import RebootBmc from '@/views/Control/RebootBmc';
+import SecuritySettings from '@/views/Configuration/SecuritySettings';
import Sensors from '@/views/Health/Sensors';
import SerialOverLan from '@/views/Control/SerialOverLan';
import SerialOverLanConsole from '@/views/Control/SerialOverLan/SerialOverLanConsole';
@@ -163,6 +164,14 @@ const routes = [
},
},
{
+ path: '/configuration/security-settings',
+ name: 'security-settings',
+ component: SecuritySettings,
+ meta: {
+ title: i18n.t('appPageTitle.securitySettings'),
+ },
+ },
+ {
path: '/control/kvm',
name: 'kvm',
component: Kvm,
diff --git a/src/store/index.js b/src/store/index.js
index e6153b1b..b4a77d82 100644
--- a/src/store/index.js
+++ b/src/store/index.js
@@ -21,6 +21,7 @@ import FanStore from './modules/Health/FanStore';
import ChassisStore from './modules/Health/ChassisStore';
import BmcStore from './modules/Health/BmcStore';
import ProcessorStore from './modules/Health/ProcessorStore';
+import SecuritySettingsStore from './modules/Configuration/SecuritySettingsStore';
import WebSocketPlugin from './plugins/WebSocketPlugin';
import DateTimeStore from './modules/Configuration/DateTimeSettingsStore';
@@ -55,6 +56,7 @@ export default new Vuex.Store({
bmc: BmcStore,
processors: ProcessorStore,
virtualMedia: VirtualMediaStore,
+ securitySettings: SecuritySettingsStore,
},
plugins: [WebSocketPlugin],
});
diff --git a/src/store/modules/Configuration/SecuritySettingsStore.js b/src/store/modules/Configuration/SecuritySettingsStore.js
new file mode 100644
index 00000000..5a885425
--- /dev/null
+++ b/src/store/modules/Configuration/SecuritySettingsStore.js
@@ -0,0 +1,95 @@
+import api from '@/store/api';
+import i18n from '@/i18n';
+
+const SecuritySettingsStore = {
+ namespaced: true,
+ state: {
+ sshProtocolEnabled: false,
+ ipmiProtocolEnabled: false,
+ },
+ getters: {
+ sshProtocolEnabled: (state) => state.sshProtocolEnabled,
+ ipmiProtocolEnabled: (state) => state.ipmiProtocolEnabled,
+ },
+ mutations: {
+ setSshProtocolEnabled: (state, sshProtocolEnabled) =>
+ (state.sshProtocolEnabled = sshProtocolEnabled),
+ setIpmiProtocolEnabled: (state, ipmiProtocolEnabled) =>
+ (state.ipmiProtocolEnabled = ipmiProtocolEnabled),
+ },
+ actions: {
+ async getNetworkProtocolStatus({ commit }) {
+ return await api
+ .get('/redfish/v1/Managers/bmc/NetworkProtocol')
+ .then((response) => {
+ const sshProtocol = response.data.SSH.ProtocolEnabled;
+ const ipmiProtocol = response.data.IPMI.ProtocolEnabled;
+ commit('setSshProtocolEnabled', sshProtocol);
+ commit('setIpmiProtocolEnabled', ipmiProtocol);
+ })
+ .catch((error) => console.log(error));
+ },
+ async saveIpmiProtocolState({ commit }, protocolEnabled) {
+ commit('setIpmiProtocolEnabled', protocolEnabled);
+ const ipmi = {
+ IPMI: {
+ ProtocolEnabled: protocolEnabled,
+ },
+ };
+ return await api
+ .patch('/redfish/v1/Managers/bmc/NetworkProtocol', ipmi)
+ .then(() => {
+ if (protocolEnabled) {
+ return i18n.t('pageSecuritySettings.toast.successIpmiEnabled');
+ } else {
+ return i18n.t('pageSecuritySettings.toast.successIpmiDisabled');
+ }
+ })
+ .catch((error) => {
+ console.log(error);
+ commit('setIpmiProtocolEnabled', !protocolEnabled);
+ if (protocolEnabled) {
+ throw new Error(
+ i18n.t('pageSecuritySettings.toast.errorIpmiEnabled')
+ );
+ } else {
+ throw new Error(
+ i18n.t('pageSecuritySettings.toast.errorIpmiDisabled')
+ );
+ }
+ });
+ },
+ async saveSshProtocolState({ commit }, protocolEnabled) {
+ commit('setSshProtocolEnabled', protocolEnabled);
+ const ssh = {
+ SSH: {
+ ProtocolEnabled: protocolEnabled,
+ },
+ };
+ return await api
+ .patch('/redfish/v1/Managers/bmc/NetworkProtocol', ssh)
+ .then(() => {
+ if (protocolEnabled) {
+ return i18n.t('pageSecuritySettings.toast.successSshEnabled');
+ } else {
+ return i18n.t('pageSecuritySettings.toast.successSshDisabled');
+ }
+ })
+ .catch((error) => {
+ console.log(error);
+ commit('setSshProtocolEnabled', !protocolEnabled);
+ if (protocolEnabled) {
+ throw new Error(
+ i18n.t('pageSecuritySettings.toast.errorSshEnabled')
+ );
+ } else {
+ throw new Error(
+ i18n.t('pageSecuritySettings.toast.errorSshDisabled')
+ );
+ }
+ });
+ },
+ },
+};
+
+export default SecuritySettingsStore;
diff --git a/src/views/Configuration/SecuritySettings/SecuritySettings.vue b/src/views/Configuration/SecuritySettings/SecuritySettings.vue
new file mode 100644
index 00000000..d665a7f5
--- /dev/null
+++ b/src/views/Configuration/SecuritySettings/SecuritySettings.vue
@@ -0,0 +1,125 @@
+<template>
+ <b-container fluid="xl">
+ <page-title />
+ <b-row>
+ <b-col lg="8" 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="securitySettings-checkbox-switchSshProtocol"
+ 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="securitySettings-checkbox-switchIpmiProtocol"
+ 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/Configuration/SecuritySettings/index.js b/src/views/Configuration/SecuritySettings/index.js
new file mode 100644
index 00000000..5ec2b615
--- /dev/null
+++ b/src/views/Configuration/SecuritySettings/index.js
@@ -0,0 +1,2 @@
+import SecuritySettings from './SecuritySettings.vue';
+export default SecuritySettings;