add pam.d directory file analytic function

(cherry picked from commit dd2fca3e3cd87d0b21dd43d8f82de6d13302f11e)
This commit is contained in:
smjiao 2023-11-07 18:38:11 +08:00 committed by openeuler-sync-bot
parent aeb30ee8bd
commit 864f6553da
2 changed files with 482 additions and 1 deletions

View File

@ -0,0 +1,477 @@
From 6a26eeb0692833c657d92206dc06533a73200011 Mon Sep 17 00:00:00 2001
From: smjiao <smjiao@isoftstone.com>
Date: Tue, 7 Nov 2023 17:24:13 +0800
Subject: [PATCH] add pam.d directory file analytic function
---
src/api/management.js | 12 +-
src/vendor/ant-design-pro/utils/request.js | 2 +-
.../TranscationDomainConfigurations.vue | 54 +++---
.../components/AddConfigurationDrawer.vue | 171 ++++++++++++++----
4 files changed, 176 insertions(+), 63 deletions(-)
diff --git a/src/api/management.js b/src/api/management.js
index 09f9b4a..15f9ea1 100644
--- a/src/api/management.js
+++ b/src/api/management.js
@@ -5,7 +5,8 @@ const api = {
getManagementConf: '/management/getManagementConf', // 读取业务域配置信息
queryManageConfChange: '/management/queryManageConfChange', // 读取业务域配置日志信息
deleteManagementConf: '/management/deleteManagementConf', // 删除业务域配置
- querySupportedConfs: '/confs/querySupportedConfs' // 查询可供选择的配置文件列表
+ querySupportedConfs: '/confs/querySupportedConfs', // 查询可供选择的配置文件列表
+ uploadManagementConf: '/management/uploadManagementConf' // 从本地导入文件 新增/更新配置
};
export default api;
@@ -59,3 +60,12 @@ export function querySupportedConfs(parameter) {
}
});
}
+
+export function uploadManagementConf(file) {
+ return request({
+ url: api.uploadManagementConf,
+ method: 'post',
+ data: file,
+ headers: { 'Content-Type': 'application/x-www-form-urlencoded' }
+ });
+}
diff --git a/src/vendor/ant-design-pro/utils/request.js b/src/vendor/ant-design-pro/utils/request.js
index c3307ce..c8015c1 100644
--- a/src/vendor/ant-design-pro/utils/request.js
+++ b/src/vendor/ant-design-pro/utils/request.js
@@ -83,7 +83,7 @@ request.interceptors.request.use(config => {
const userName = localStorage.getItem('user_name')
userName && localStorage.setItem('user_name', userName);
}
- if (config.url === '/vulnerability/cve/advisory/upload' || config.url === '/vulnerability/cve/unaffected/upload') {
+ if (config.url === '/vulnerability/cve/advisory/upload' || config.url === '/vulnerability/cve/unaffected/upload' || config.url === '/management/uploadManagementConf') {
config.headers['Content-Type'] = 'application/x-www-form-urlencoded'
} else {
config.headers['Content-Type'] = 'application/json'
diff --git a/src/views/configuration/TranscationDomainConfigurations.vue b/src/views/configuration/TranscationDomainConfigurations.vue
index 7882254..d090493 100644
--- a/src/views/configuration/TranscationDomainConfigurations.vue
+++ b/src/views/configuration/TranscationDomainConfigurations.vue
@@ -12,7 +12,7 @@
<div slot="message">
<span>{{ `已选择` + selectedRowKeys.length + `项` }}</span>
<a
- v-if="selectedRowKeys.length > 0"
+ v-if="selectedRowKeys.length > 0"
@click="deleteConfigBash(selectedRowKeys, selectedRows)">
批量删除
</a>
@@ -33,9 +33,9 @@
</a-col>
</a-row>
<a-table
- rowKey="filePath"
- :columns="columns"
- :data-source="tableData"
+ rowKey="filePath"
+ :columns="columns"
+ :data-source="tableData"
:pagination="pagination"
:row-selection="rowSelection"
@change="handleTableChange"
@@ -48,12 +48,12 @@
<a-divider type="vertical" />
<a @click="showConfigChange(record)">配置变更日志</a>
<a-divider type="vertical" />
- <a @click="showEditDrawer(record)">编辑配置&emsp;&emsp;</a>
+ <a @click="showEditDrawer(record)">编辑配置</a>
<a-divider type="vertical" />
<a-popconfirm
- title="你确定删除这行配置吗?"
- ok-text="确认"
- cancel-text="取消"
+ title="你确定删除这行配置吗?"
+ ok-text="确认"
+ cancel-text="取消"
@confirm="deleteConfig(record)">
<a-icon slot="icon" type="close-circle" style="color: red" />
<a>删除</a>
@@ -61,10 +61,10 @@
</span>
</a-table>
<a-drawer
- title="配置文件内容"
- :width="720"
- placement="right"
- :visible="configContentVisible"
+ title="配置文件内容"
+ :width="720"
+ placement="right"
+ :visible="configContentVisible"
:body-style="{paddingBottom: '80px'}"
@close="closeConfigContent">
<a-descriptions :column="1" layout="horizontal">
@@ -81,10 +81,10 @@
</a-descriptions>
</a-drawer>
<a-drawer
- title="配置日志"
- :width="1080"
- placement="right"
- :visible="configChangeVisible"
+ title="配置日志"
+ :width="1080"
+ placement="right"
+ :visible="configChangeVisible"
:body-style="{paddingBottom: '80px'}"
@close="closeConfigChange">
<a-spin :spinning="logIsLoading">
@@ -103,8 +103,8 @@
</div>
<p class="pLog">变更历史:</p>
<a-table
- rowKey="changeId"
- :columns="confChangeColumns"
+ rowKey="changeId"
+ :columns="confChangeColumns"
:data-source="manageConfChange[0].changeLog"
:expandIconAsCell="false"
:expandIconColumnIndex="4"
@@ -125,11 +125,11 @@
</div>
</a-card>
<domain-selection-modal
- :showDomainSelection="choiceDomainNameModalVisible"
+ :showDomainSelection="choiceDomainNameModalVisible"
@cancel="handleDomainSelectCancel" />
<add-configuration-drawer
- :isEdit="true"
- :visibleControl="editConfVisible"
+ :isEdit="true"
+ :visibleControl="editConfVisible"
:domainName="domainName"
:editFilePath="editFilePath"
@ok="onEditConfsOk"
@@ -225,18 +225,24 @@ export default {
{
dataIndex: 'filePath',
key: 'filePath',
- title: '配置文件'
+ title: '配置文件',
+ width: '20%'
},
{
key: 'contents',
title: '配置详情',
- scopedSlots: {customRender: 'contents'}
+ scopedSlots: {customRender: 'contents'},
+ width: '50%',
+ ellipsis: true,
+ customRender: (text, record) => <a-tooltip placement="topLeft"
+ title={record.contents}>{record.contents}</a-tooltip>
},
{
key: 'operation',
title: '操作',
scopedSlots: {customRender: 'action'},
- width: 240
+ width: '30%',
+ align: 'center'
}
];
},
diff --git a/src/views/configuration/components/AddConfigurationDrawer.vue b/src/views/configuration/components/AddConfigurationDrawer.vue
index d6880de..a6aee2f 100644
--- a/src/views/configuration/components/AddConfigurationDrawer.vue
+++ b/src/views/configuration/components/AddConfigurationDrawer.vue
@@ -7,8 +7,8 @@
</slot>
</div>
<a-drawer :title="isEdit ? '编辑配置' : '新增配置'" :width="720"
- :visible="isEdit ? visibleControl : visible" :body-style="{paddingBottom: '80px'}"
- @close="handleCancel">
+ :visible="isEdit ? visibleControl : visible" :body-style="{paddingBottom: '80px'}"
+ @close="handleCancel">
<a-form :form="form" :label-col="{span: 5}" :wrapper-col="{span: 18}">
<a-form-item label="所属业务域">
<a-input disabled v-decorator="['domainName', {initialValue: domainName}]" />
@@ -16,13 +16,15 @@
<div class="conf-form-item" v-for="(key, index) in formList" :key="key">
<span v-if="!isEdit">
<a-icon class="dynamic-delete-button" type="minus-circle-o"
- @click="removeConfForm(index)" v-if="formList.length > 1" />
+ @click="removeConfForm(index)" v-if="formList.length > 1" />
新增配置{{ index + 1 }}
</span>
<a-form-item label="配置路径">
<a-select
v-decorator="[`confFiles[${key}].filePath`, {rules: [{required: true, message: '请输入配置路径'}]}]"
- placeholder="请选择配置路径" :disabled="isEdit" show-search>
+ placeholder="请选择配置路径" :disabled="isEdit" show-search @change="value => {
+ pathSelectionChange(key,value)
+ }">
<a-select-option v-for="item in supportedConfList" :value="item" :key="item">
{{ item }}
</a-select-option>
@@ -30,7 +32,8 @@
</a-form-item>
<a-form-item>
<span slot="label">
- <a-tooltip title="配置来源二选一,推荐使用手动输入">
+ <a-tooltip title="配置来源三选一,推荐使用手动输入"
+ v-if="editFilePath!== '/etc/pam.d' && tempPath[key] !== '/etc/pam.d'">
<a-icon type="question-circle-o" />
</a-tooltip>
&nbsp;配置来源
@@ -40,26 +43,47 @@
formSelectionChange(key, value);
}
">
- <a-select-option value="manuel">手动输入</a-select-option>
+ <a-select-option value="manuel" v-if="editFilePath!== '/etc/pam.d' && tempPath[key] !== '/etc/pam.d'">
+ 手动输入
+ </a-select-option>
<a-select-option value="auto">从主机导入</a-select-option>
+ <a-select-option value="file" v-if="editFilePath!== '/etc/pam.d' && tempPath[key] !== '/etc/pam.d'">
+ 从本地导入
+ </a-select-option>
</a-select>
</a-form-item>
<a-form-item label="配置内容" v-if="formSelections[key] === 'manuel'">
<a-textarea placeholder="请输入配置内容" :rows="8"
- v-decorator="[`confFiles[${key}].contents`, {rules: [{required: true, message: '请输入内容'}]}]" />
+ v-decorator="[`confFiles[${key}].contents`, {rules: [{required: true, message: '请输入内容'}]}]" />
</a-form-item>
<a-form-item label="选择主机" v-else-if="formSelections[key] === 'auto'">
<a-select placeholder="请选择文件所在主机"
- v-decorator="[`confFiles[${key}].hostId`, {rules: [{required: true, message: '请选择主机'}]}]">
+ v-decorator="[`confFiles[${key}].hostId`, {rules: [{required: true, message: '请选择主机'}]}]">
<a-spin v-if="hostListLoading" slot="notFoundContent" size="small" />
<a-select-option v-for="host in hostList" :value="host.hostId" :key="host.hostId">
{{ host.ip }}
</a-select-option>
</a-select>
</a-form-item>
+ <a-form-item label="选择文件" html-for={null} v-else-if="formSelections[key] === 'file'">
+ <a-upload :file-list="fileDataList" :remove="removeFile" :before-upload="preUpload"
+ v-decorator="['file',{rules: [{required: true, message: '请选择文件'}]}]">
+ <div style="display:flex;">
+ <div style="flex">
+ <a-button>
+ <a-icon type="upload"/>
+ 选择文件
+ </a-button>
+ </div>
+ </div>
+ </a-upload>
+ <div class="upload-tip">
+ <p>文件大小不超过1MB</p>
+ </div>
+ </a-form-item>
</div>
</a-form>
- <a-button type="dashed" style="width: 100%" @click="addConfForm()" v-if="!isEdit">
+ <a-button type="dashed" style="width: 100%" @click="addConfForm()" v-if="formSelections[0] !== 'file' && !isEdit">
<a-icon type="plus" /> 新增配置
</a-button>
<div class="areaButton">
@@ -71,7 +95,7 @@
</template>
<script>
-import {addManagementConf, querySupportedConfs} from '@/api/management';
+import {addManagementConf, querySupportedConfs, uploadManagementConf} from '@/api/management';
import {domainHostList} from '@/api/configuration';
// 弹窗添加主机组
export default {
@@ -114,8 +138,10 @@ export default {
formList: [0],
formSelections: {0: 'manuel'},
submitIsLoading: false,
- supportedConfList: []
- };
+ supportedConfList: [],
+ fileDataList: [],
+ tempPath: {0: ''} // 配置路径值
+ }
},
watch: {
visibleControl: function () {
@@ -123,6 +149,9 @@ export default {
if (this.isEdit && this.visibleControl === true) {
this.getHostList();
this.resetData();
+ if (this.editFilePath === '/etc/pam.d') {
+ this.formSelections = {0: 'auto'}
+ }
setTimeout(function () {
_this.form.setFieldsValue({confFiles: [{filePath: _this.editFilePath}]});
}, 100);
@@ -143,6 +172,7 @@ export default {
this.formKey += 1;
this.formList.push(this.formKey);
this.formSelections[this.formKey] = 'manuel';
+ this.tempPath[this.formKey] = '';
},
removeConfForm(idx) {
const listTemp = this.formList;
@@ -154,11 +184,21 @@ export default {
temp[key] = value;
this.formSelections = Object.assign({}, temp);
},
+ pathSelectionChange(key, value) {
+ const temp = this.tempPath;
+ temp[key] = value;
+ this.tempPath = Object.assign({}, temp);
+ if (this.tempPath[key] === '/etc/pam.d') {
+ this.formSelections[key] = 'auto'
+ }
+ },
resetData() {
this.form.resetFields();
this.formKey = 0;
this.formList = [0];
this.formSelections = {0: 'manuel'};
+ this.fileDataList = []
+ this.tempPath = {0: ''};
},
showModal() {
this.resetData();
@@ -170,33 +210,62 @@ export default {
this.visible = false;
this.$emit('cancel');
},
+ // 上传文件 添加配置
+ uploadManagementConf(formData) {
+ const _this = this
+ uploadManagementConf(formData).then((res) => {
+ if (res.code === 200) {
+ _this.$message.success(res.msg)
+ } else if (res.code === 206) {
+ _this.$message.warning(res.msg)
+ }
+ _this.visible = false
+ _this.$emit('ok')
+ }).catch(function (err) {
+ _this.$message.error(err.response.message || err.response.data.detail || err.response.data.msg);
+ }).finally(function () {
+ _this.submitIsLoading = false
+ })
+ },
+ // 添加配置
+ addManagementConf(params) {
+ const _this = this
+ addManagementConf(params).then(function (res) {
+ if (res.code === 200) {
+ _this.$message.success(res.msg)
+ } else if (res.code === 206) {
+ _this.$message.warning(res.msg)
+ }
+ _this.visible = false
+ _this.$emit('ok')
+ }).catch(function (err) {
+ _this.$message.error(err.response.message || err.response.data.detail || err.response.data.msg);
+ }).finally(function () {
+ _this.submitIsLoading = false
+ })
+ },
handleOk() {
- const _this = this;
this.form.validateFields((err, values) => {
if (!err) {
- const params = {
- domainName: _this.domainName,
- confFiles: values.confFiles.filter((conf) => conf)
- };
- this.submitIsLoading = true;
- addManagementConf(params)
- .then(function (res) {
- if (res.code === 200) {
- _this.$message.success(res.msg);
- } else if (res.code === 206) {
- _this.$message.warning(res.msg);
- }
- _this.visible = false;
- _this.$emit('ok');
- })
- .catch(function (err) {
- _this.$message.error(err.response.message || err.response.data.detail || err.response.data.msg);
+ if (this.formSelections[0] === 'file') {
+ const formData = new FormData()
+ formData.append('filePath', values.confFiles[0].filePath)
+ formData.append('domainName', this.domainName)
+ this.fileDataList.forEach((file) => {
+ formData.append('file', file);
})
- .finally(function () {
- _this.submitIsLoading = false;
- });
+ this.submitIsLoading = true
+ this.uploadManagementConf(formData)
+ } else {
+ const params = {
+ domainName: this.domainName,
+ confFiles: values.confFiles.filter((conf) => conf)
+ }
+ this.submitIsLoading = true
+ this.addManagementConf(params)
+ }
}
- });
+ })
},
getHostList() {
const _this = this;
@@ -206,21 +275,49 @@ export default {
_this.hostList = res;
})
.catch(function (err) {
- if (err.response.code !== '400') {
- _this.$message.error(err.response.message || err.response.data.detail);
- } else {
+ _this.$message.error(err.response.data.msg || err.response.data.detail);
+ if (err.response.data.code === 400) {
_this.hostList = [];
}
})
.finally(function () {
_this.hostListLoading = false;
});
+ },
+ removeFile(file) {
+ const index = this.fileDataList.indexOf(file);
+ const newFileDataList = this.fileDataList.slice();
+ newFileDataList.splice(index, 1);
+ this.fileDataList = newFileDataList;
+ },
+ preUpload(file) {
+ this.fileDataList = [file];
+ // 读取文件大小
+ const fileSize = file.size;
+ if (fileSize / 1024 / 1024 > 1) {
+ this.$message.error('文件大于1M!');
+ this.removeFile(file);
+ return false;
+ }
+ return false;
}
}
};
</script>
<style lang="less" scoped>
+.upload-tip {
+ left: 150px;
+ top: 0px;
+ position: absolute;
+ font-size: 15px;
+ line-height: 18px;
+ width: 170px;
+
+ p {
+ margin-bottom: 5px;
+ }
+}
.areaButton {
position: absolute;
right: 0;
--
2.38.1.windows.1

View File

@ -2,7 +2,7 @@
Name: aops-hermes
Version: v1.3.3
Release: 11
Release: 12
Summary: Web for an intelligent diagnose frame
License: MulanPSL2
URL: https://gitee.com/openeuler/%{name}
@ -21,6 +21,7 @@ Patch0010: 0010-Optimize-host-scanning-polling-logic.patch
Patch0011: 0011-Add-null-judgment-for-generating-cve-and-repo-tasks.patch
Patch0012: 0012-Fix-Upload-host-logic.patch
Patch0013: 0013-Fix-the-issue-of-incorrect-parameter.patch
Patch0014: 0014-add-pam.d-directory-file-analytic-function.patch
BuildRequires: nodejs node-gyp nodejs-yarn
@ -56,6 +57,9 @@ cp -r deploy/aops-hermes.service %{buildroot}/usr/lib/systemd/system/
%changelog
* Tue Nov 7 2023 smjiao<smjiao@isoftstone.com> - v1.3.3-12
- add pam.d directory file analytic function
* Mon Oct 30 2023 wangkunlong<505997900@qq.com> - v1.3.3-11
- Fix the issue of incorrect parameter transmission for batch adding hosts