From 47560ba21c70c0b9c400473ce60de4dd5858b2b6 Mon Sep 17 00:00:00 2001 From: Darren Satkunas Date: Thu, 8 Dec 2022 06:51:10 -0800 Subject: [PATCH] feature(admin(js,vue)): add system service button, add rsyslog system service button to syslog forwarders, fixes #6532 --- .../new/BaseButtonSystemService.vue | 227 ++++++++++++++++++ .../root/src/components/new/index.js | 2 + .../root/src/store/modules/cluster.js | 93 ++++++- .../_components/AlertServices.vue | 42 ++++ .../syslogForwarders/_components/TheView.js | 27 ++- .../syslogForwarders/_components/index.js | 2 + .../_components/BaseSystemService.vue | 158 ++++++++++++ 7 files changed, 537 insertions(+), 14 deletions(-) create mode 100644 html/pfappserver/root/src/components/new/BaseButtonSystemService.vue create mode 100644 html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/AlertServices.vue create mode 100644 html/pfappserver/root/src/views/Status/services/_components/BaseSystemService.vue diff --git a/html/pfappserver/root/src/components/new/BaseButtonSystemService.vue b/html/pfappserver/root/src/components/new/BaseButtonSystemService.vue new file mode 100644 index 000000000000..508992fe124a --- /dev/null +++ b/html/pfappserver/root/src/components/new/BaseButtonSystemService.vue @@ -0,0 +1,227 @@ + + diff --git a/html/pfappserver/root/src/components/new/index.js b/html/pfappserver/root/src/components/new/index.js index 0b893f4359d2..e3ebc55a7a05 100644 --- a/html/pfappserver/root/src/components/new/index.js +++ b/html/pfappserver/root/src/components/new/index.js @@ -6,6 +6,7 @@ import BaseButtonRefresh from './BaseButtonRefresh' import BaseButtonSave from './BaseButtonSave' import BaseButtonSaveSearch from './BaseButtonSaveSearch' import BaseButtonService from './BaseButtonService' +import BaseButtonSystemService from './BaseButtonSystemService' import BaseButtonUpload from './BaseButtonUpload' import BaseContainerLoading from './BaseContainerLoading' import BaseCsvImport from './BaseCsvImport' @@ -150,6 +151,7 @@ export { BaseButtonSave, BaseButtonSaveSearch, BaseButtonService, + BaseButtonSystemService, BaseButtonUpload, // containers diff --git a/html/pfappserver/root/src/store/modules/cluster.js b/html/pfappserver/root/src/store/modules/cluster.js index 9839049161b3..af8f22c33b25 100644 --- a/html/pfappserver/root/src/store/modules/cluster.js +++ b/html/pfappserver/root/src/store/modules/cluster.js @@ -106,6 +106,17 @@ const api = (state, server = store.state.system.hostname) => { }) }) }, + systemService: id => { + return apiCall.getQuiet(['system_service', id, 'status'], { headers }).then(response => { + return response.data + }).catch(error => { + // 500 response error w/ not running + if (error.response && (!['ERR_BAD_RESPONSE'].includes(error.code) || ![500].includes(error.response.status))) { + throw error + } + return error.response.data + }) + }, restartSystem: id => { return apiCall.postQuiet(['system_service', id, 'restart'], { async: true }, { headers }) .then(response => { @@ -196,6 +207,33 @@ const getters = { } }, sorted) }, {}) + }, + systemServicesByServer: state => { + return Object.entries(state.servers).reduce((sorted, [server, {system_services = {}}]) => { + return Object.entries(system_services).reduce((sorted, [id, service]) => { + return { + ...sorted, + [id]: { + servers: { + ...((id in sorted) ? sorted[id].servers : {} ), + [server]: { + ...service, + isDisabling: service.status === types.DISABLING, + isEnabling: service.status === types.ENABLING, + isRestarting: service.status === types.RESTARTING, + isStarting: service.status === types.STARTING, + isStopping: service.status === types.STOPPING, + } + }, + hasAlive: Object.values(state.servers).findIndex(({ services: { [id]: service } }) => service && service.alive && service.pid) > -1, + hasDead: Object.values(state.servers).findIndex(({ services: { [id]: service } }) => service && !(service.alive || service.pid)) > -1, + hasEnabled: Object.values(state.servers).findIndex(({ services: { [id]: service } }) => service && service.enabled) > -1, + hasDisabled: Object.values(state.servers).findIndex(({ services: { [id]: service } }) => service && !service.enabled) > -1, + isProtected: !!protectedServices.find(listed => listed === id), + } + } + }, sorted) + }, {}) } } @@ -471,42 +509,68 @@ const actions = { }) }, - restartSystemService: ({ state, commit }, { id, server = store.state.system.hostname }) => { + getSystemService: ({ state, commit }, { server, id }) => { + commit('SYSTEM_SERVICE_REQUEST', { server, id }) + return api(state, server).systemService(id).then(service => { + commit('SYSTEM_SERVICE_SUCCESS', { server, id, service }) + return state.servers[server].services[id] + }).catch(err => { + const { response: { data: { message: error } = {} } = {} } = err + commit('SYSTEM_SERVICE_ERROR', { server, id, error }) + throw err + }) + }, + getSystemServiceCluster: ({ state, dispatch }, id) => { + return dispatch('getConfig').then(() => { + let promises = [] + Object.keys(state.servers).map(server => { + promises.push(dispatch('getSystemService', { server, id })) + }) + return Promise.all(promises).then(servers => { + return servers.reduce((assoc, service, index) => { + const server = Object.keys(state.servers)[index] + return { ...assoc, [server]: state.servers[server].system_services[id] } + }, {}) + }) + }) + }, + restartSystemService: ({ state, commit, dispatch }, { id, server = store.state.system.hostname }) => { commit('SYSTEM_SERVICE_REQUEST', { server, id }) commit('SYSTEM_SERVICE_RESTARTING', { server, id }) return api(state, server).restartSystem(id).then(response => { commit('SYSTEM_SERVICE_RESTARTED', { server, id, response }) - return state.servers[server].services[id] + return state.servers[server].system_services[id] }).catch(err => { const { response: { data: error } = {} } = err commit('SYSTEM_SERVICE_ERROR', { server, id, error }) throw err - }) + }).finally(() => dispatch('getSystemService', { server, id })) }, - startSystemService: ({ state, commit }, { id, server = store.state.system.hostname }) => { + startSystemService: ({ state, commit, dispatch }, { id, server = store.state.system.hostname }) => { commit('SYSTEM_SERVICE_REQUEST', { server, id }) commit('SYSTEM_SERVICE_STARTING', { server, id }) return api(state, server).startSystem(id).then(response => { commit('SYSTEM_SERVICE_STARTED', { server, id, response }) - return state.servers[server].services[id] + return state.servers[server].system_services[id] }).catch(err => { const { response: { data: error } = {} } = err commit('SYSTEM_SERVICE_ERROR', { server, id, error }) throw err - }) + }).finally(() => dispatch('getSystemService', { server, id })) }, - stopSystemService: ({ state, commit }, { id, server = store.state.system.hostname }) => { + stopSystemService: ({ state, commit, dispatch }, { id, server = store.state.system.hostname }) => { commit('SYSTEM_SERVICE_REQUEST', { server, id }) commit('SYSTEM_SERVICE_STOPPING', { server, id }) return api(state, server).stopSystem(id).then(response => { commit('SYSTEM_SERVICE_STOPPED', { server, id, response }) - return state.servers[server].services[id] + return state.servers[server].system_services[id] }).catch(err => { const { response: { data: error } = {} } = err commit('SYSTEM_SERVICE_ERROR', { server, id, error }) throw err - }) + }).finally(() => dispatch('getSystemService', { server, id })) }, + updateSystemd: ({ state, commit }, { id, server = store.state.system.hostname }) => { commit('SYSTEMD_REQUEST', { server, id }) return api(state, server).updateSystemd(id).then(response => { @@ -640,9 +704,18 @@ const mutations = { SYSTEM_SERVICE_REQUEST: (state, { server, id }) => { state.status = types.LOADING Vue.set(state.servers, server, state.servers[server] || { services: {}, system_services: {} }) - Vue.set(state.servers[server].system_services, id, state.servers[server].services[id] || {}) + Vue.set(state.servers[server].system_services, id, state.servers[server].system_services[id] || {}) Vue.set(state.servers[server].system_services[id], 'status', types.LOADING) }, + SYSTEM_SERVICE_SUCCESS: (state, { server, id, service }) => { + service.id = id + service.pid = parseInt(service.pid) + service.alive = !!(service.pid) + service.message = '' + state.status = types.SUCCESS + state.message = '' + Vue.set(state.servers[server].system_services, id, { ...state.servers[server].system_services[id], ...service, status: types.SUCCESS }) + }, SYSTEM_SERVICE_RESTARTING: (state, { server, id }) => { state.status = types.LOADING Vue.set(state.servers[server].system_services[id], 'status', types.RESTARTING) diff --git a/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/AlertServices.vue b/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/AlertServices.vue new file mode 100644 index 000000000000..da310eae01dd --- /dev/null +++ b/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/AlertServices.vue @@ -0,0 +1,42 @@ + + + diff --git a/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/TheView.js b/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/TheView.js index e35e28224e69..fc91f061b9e8 100644 --- a/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/TheView.js +++ b/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/TheView.js @@ -1,6 +1,6 @@ import { + AlertServices, BaseView, - FormButtonBar, TheForm } from './' @@ -10,6 +10,8 @@ const components = { TheForm } +import { computed } from '@vue/composition-api' +import { renderHOCWithScopedSlots } from '@/components/new/' import { useViewCollectionItem, useViewCollectionItemProps } from '../../_composables/useViewCollectionItem' import * as collection from '../_composables/useCollection' @@ -18,14 +20,31 @@ const props = { ...collection.useItemProps } -const setup = (props, context) => useViewCollectionItem(collection, props, context) +const setup = (props, context) => { + + const viewCollectionItem = useViewCollectionItem(collection, props, context) + const { + isLoading, + isModified + } = viewCollectionItem + + const scopedSlotProps = computed(() => ({ ...props, isLoading: isLoading.value, isModified: isModified.value })) + + return { + ...viewCollectionItem, + scopedSlotProps + } +} + +const render = renderHOCWithScopedSlots(BaseView, { components, props, setup }, { + buttonsPrepend: AlertServices +}) // @vue/component export default { name: 'the-view', extends: BaseView, inheritAttrs: false, - components, props, - setup + render } diff --git a/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/index.js b/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/index.js index 8239d1e1e07a..ec65549bc336 100644 --- a/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/index.js +++ b/html/pfappserver/root/src/views/Configuration/syslogForwarders/_components/index.js @@ -7,6 +7,7 @@ import { BaseFormGroupInputNumber, BaseFormGroupToggleDisabledEnabled } from '@/components/new/' +import AlertServices from './AlertServices' import TheForm from './TheForm' import TheView from './TheView' @@ -21,6 +22,7 @@ export { BaseFormGroupInputNumber as FormGroupPort, BaseFormGroupChosenOne as FormGroupProto, + AlertServices, TheForm, TheView } diff --git a/html/pfappserver/root/src/views/Status/services/_components/BaseSystemService.vue b/html/pfappserver/root/src/views/Status/services/_components/BaseSystemService.vue new file mode 100644 index 000000000000..2e8c3e46cd09 --- /dev/null +++ b/html/pfappserver/root/src/views/Status/services/_components/BaseSystemService.vue @@ -0,0 +1,158 @@ + +