diff --git a/nezha-fronted/src/components/common/language/cn.js b/nezha-fronted/src/components/common/language/cn.js index 32b58e0b4..da6d3b214 100644 --- a/nezha-fronted/src/components/common/language/cn.js +++ b/nezha-fronted/src/components/common/language/cn.js @@ -1129,6 +1129,7 @@ const cn = { defaultEndpointSet: '默认的Endpoint设置', relation: '模块关联的Endpoint将默认配置以下端口/路径/参数' }, + type: '类型', version: '版本', walk: 'Walk', maxRepetitions: '最大迭代次数', @@ -1139,6 +1140,7 @@ const cn = { authProtocol: '认证协议', privProtocol: '隐私协议', contextName: '内容名称', + alerts: 'Alerts', privPassword: '隐私密码' }, endpoint: { @@ -1163,7 +1165,20 @@ const cn = { stateInfo_230010: 'Prometheus服务可用', stateInfo_230011: 'Endpoint 连接错误', alerts: '告警', - labels: '标签' + labels: '标签', + pattern: 'Name pattern', + credentials: '资格证书', + scrape_interval: '时间间隔', + scrape_interval_placeholder: '默认全局时间间隔', + scrape_timeout: '超时时间', + scrape_timeout_placeholder: '默认全局超时时间', + type: '类型', + bearer_token: 'Token', + username: '用户名', + password: '密码', + authTypeNull: '无', + authTypeWord: '用户名密码', + authTypeToken: 'Token', }, metrics: { metrics: '指标', diff --git a/nezha-fronted/src/components/common/language/en.js b/nezha-fronted/src/components/common/language/en.js index 2c6a84b8e..2f7a55b34 100644 --- a/nezha-fronted/src/components/common/language/en.js +++ b/nezha-fronted/src/components/common/language/en.js @@ -1132,6 +1132,7 @@ const en = { createModule: 'New module', // "新增组件" version: 'Version', walk: 'Walk', + type: 'Type', maxRepetitions: 'Max repetitions', retries: 'Retries', timeout: 'Timeout', @@ -1141,6 +1142,7 @@ const en = { privProtocol: 'Priv protocol', contextName: 'Context name', privPassword: 'Priv password', + alerts: 'Alerts', tip: { defaultEndpointSet: 'Default endpoint settings', // "默认的Endpoint设置" relation: 'Module associated Endpoint will configure the following ports/paths/parameters by default'// "组件关联的Endpoint将默认配置以下端口/路径/参数" @@ -1168,7 +1170,20 @@ const en = { stateInfo_230010: 'Promserver can be used', stateInfo_230011: 'Endpoint connection refused', alerts: 'Alerts', - labels: 'Labels' + labels: 'Labels', + pattern: 'Name pattern', + credentials: 'Credentials', + scrape_interval: 'Scrape interval', + scrape_interval_placeholder: 'default global scrape interval', + scrape_timeout: 'Scrape timeout', + scrape_timeout_placeholder: 'default global scrape timeout', + type: 'Type', + bearer_token: 'Token', + username: 'Username', + password: 'Password', + authTypeNull: 'None', + authTypeWord: 'Username and password', + authTypeToken: 'Token', }, metrics: { metrics: 'Metrics', // "指标" diff --git a/nezha-fronted/src/components/common/popBox/selectWalk.vue b/nezha-fronted/src/components/common/popBox/selectWalk.vue index fc4a796e3..5ad5c94e7 100644 --- a/nezha-fronted/src/components/common/popBox/selectWalk.vue +++ b/nezha-fronted/src/components/common/popBox/selectWalk.vue @@ -22,18 +22,20 @@ :default-checked-keys="currentWalk" >
- - - - - - - - - + + + + + + + + + + + - {{data.name}} + {{data.data.name}}
@@ -64,6 +66,9 @@ export default { computed: { getClass () { return (value) => { + if (!value) { + return '' + } return this.currentWalk.indexOf(value) == -1 ? '' : 'walk-active' } }, @@ -98,7 +103,8 @@ export default { show () { this.popBox.show = true }, - hideDetail () { + hideDetail (data,num) { + console.log(data,num) this.tempWalk.detailShow = false }, showDetail (data, e) { diff --git a/nezha-fronted/src/components/common/project/topologyL5.vue b/nezha-fronted/src/components/common/project/topologyL5.vue index 4c3fa269a..4466b033f 100644 --- a/nezha-fronted/src/components/common/project/topologyL5.vue +++ b/nezha-fronted/src/components/common/project/topologyL5.vue @@ -113,7 +113,11 @@
{{topologyInfo.name}}
- + +
@@ -758,7 +757,7 @@ export default { if (this.fromPrev) { resolve(this.topoPrevDataS) } - this.$get('/project/topo', { projectId: this.obj.id }).then(res => { + this.$get('monitor/project/topo', { projectId: this.obj.id }).then(res => { let data = res.data.topo if (!res.data.topo || !data.pens) { data = { @@ -806,9 +805,17 @@ export default { item.image = this.iconArray.find(item1 => item1.id == item.data.imageId).image } if (item.type === 0) { - promiseArr.push(this.$get('/module/stat', { id: item.data.moduleId })) + // promiseArr.push(this.$get('/monitor/module/stat', { id: item.data.moduleId })) + item.data.state = {} + item.data.state.asset = false + item.data.state.endpoint = false + item.data.state.alert = false } else { - promiseArr.push({ type: 1 }) + // promiseArr.push({ type: 1 }) + item.data.state = {} + item.data.state.asset = false + item.data.state.endpoint = false + item.data.state.alert = false } }) @@ -1547,11 +1554,11 @@ export default { form.append('name', this.file.name.substring(0, this.file.name.lastIndexOf('.'))) } form.append('unit', this.uploadPic.unit) - this.$post('/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => { + this.$post('monitor/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => { if (res.code == 200) { this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') }) this.uploadPicShow = false - this.dealImg(`/project/topo/icon/${res.data.id}`).then((data) => { + this.dealImg(`monitor/project/topo/icon/${res.data.id}`).then((data) => { const group = this.tools.find(tool => tool.group === this.uploadPic.unit) if (group) { group.children.push({ @@ -1587,7 +1594,7 @@ export default { }, delImg (item) { - this.$delete('/project/topo/icon?ids=' + item.data.imageId).then(res => { + this.$delete('monitor/project/topo/icon?ids=' + item.data.imageId).then(res => { if (res.code == 200) { this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.addNodeInit() @@ -1599,7 +1606,7 @@ export default { addNodeInit (imgidList) { if (!this.fromOverView) { - this.$get('/project/topo/icon').then(res => { + this.$get('monitor/project/topo/icon').then(res => { this.imgageLoading = true // this.tools[1].children=[]; const imgArr = [] @@ -1607,7 +1614,7 @@ export default { res.data.list.forEach((item, index) => { item.imageName = item.name delete item.name - promiseArr.push(this.dealImg(`/project/topo/icon/${item.id}`)) + promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}`)) imgArr.push({ ...item }) }) Promise.all(promiseArr).then((res2) => { @@ -1651,7 +1658,7 @@ export default { const promiseArr = [] imgidList.forEach((item, index) => { if (item.data.imageId) { - promiseArr.push(this.dealImg(`/project/topo/icon/${item.data.imageId}`)) + promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}`)) } else { promiseArr.push('') } @@ -1832,7 +1839,7 @@ export default { if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) { getTopology(this.topologyIndex).data.scale = this.oldScale } - this.$put('/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => { + this.$put('monitor/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => { this.prevent_opt.save = false if (res.code === 200) { this.$message({ diff --git a/nezha-fronted/src/components/common/project/topologyPrev.vue b/nezha-fronted/src/components/common/project/topologyPrev.vue index 952d8ff20..a0d0f05d0 100644 --- a/nezha-fronted/src/components/common/project/topologyPrev.vue +++ b/nezha-fronted/src/components/common/project/topologyPrev.vue @@ -797,7 +797,7 @@ if (this.fromPrev) { resolve(this.topoPrevDataS) } - this.$get('/project/topo', { projectId: this.obj.id }).then(res => { + this.$get('monitor/project/topo', { projectId: this.obj.id }).then(res => { let data = res.data.topo if (!res.data.topo || !data.pens) { data = { @@ -1587,11 +1587,11 @@ form.append('name', this.file.name.substring(0, this.file.name.lastIndexOf('.'))) } form.append('unit', this.uploadPic.unit) - this.$post('/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => { + this.$post('monitor/project/topo/icon', form, { 'Content-Type': 'multipart/form-data' }).then(res => { if (res.code == 200) { this.$message({ duration: 2000, type: 'success', message: this.$t('tip.saveSuccess') }) this.uploadPicShow = false - this.dealImg(`/project/topo/icon/${res.data.id}`).then((data) => { + this.dealImg(`monitor/project/topo/icon/${res.data.id}`).then((data) => { const group = this.tools.find(tool => tool.group === this.uploadPic.unit) if (group) { group.children.push({ @@ -1627,7 +1627,7 @@ }, delImg (item) { - this.$delete('/project/topo/icon?ids=' + item.data.imageId).then(res => { + this.$delete('monitor/project/topo/icon?ids=' + item.data.imageId).then(res => { if (res.code == 200) { this.$message({ duration: 2000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.addNodeInit() @@ -1639,7 +1639,7 @@ addNodeInit (imgidList) { if (!this.fromOverView) { - this.$get('/project/topo/icon').then(res => { + this.$get('monitor/project/topo/icon').then(res => { this.imgageLoading = true // this.tools[1].children=[]; const imgArr = [] @@ -1647,7 +1647,7 @@ res.data.list.forEach((item, index) => { item.imageName = item.name delete item.name - promiseArr.push(this.dealImg(`/project/topo/icon/${item.id}`)) + promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.id}`)) imgArr.push({ ...item }) }) Promise.all(promiseArr).then((res2) => { @@ -1691,7 +1691,7 @@ const promiseArr = [] imgidList.forEach((item, index) => { if (item.data.imageId) { - promiseArr.push(this.dealImg(`/project/topo/icon/${item.data.imageId}`)) + promiseArr.push(this.dealImg(`monitor/project/topo/icon/${item.data.imageId}`)) } else { promiseArr.push('') } @@ -1872,7 +1872,7 @@ if (this.penToolTipScale == getTopology(this.topologyIndex).data.scale) { getTopology(this.topologyIndex).data.scale = this.oldScale } - this.$put('/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => { + this.$put('monitor/project/topo', { topo: JSON.stringify(topologyData), projectId: this.projectInfo.id }).then(res => { this.prevent_opt.save = false if (res.code === 200) { this.$message({ diff --git a/nezha-fronted/src/components/common/rightBox/moduleBox.vue b/nezha-fronted/src/components/common/rightBox/moduleBox.vue index 0e64d7be8..e9ad84287 100644 --- a/nezha-fronted/src/components/common/rightBox/moduleBox.vue +++ b/nezha-fronted/src/components/common/rightBox/moduleBox.vue @@ -16,27 +16,40 @@
- - - - - + + + + + + + + + + + -
-
-
HTTP
-
-
-
SNMP
-
-
+ + + + + + -
SNMP settings
+
SNMP settings +
@@ -67,239 +80,158 @@ - - - -
{{$t('project.module.version')}}
-
- - - - - - - - -
- - - -
{{$t('project.module.maxRepetitions')}}
-
- - - - - -
- - - -
{{$t('project.module.retries')}}
-
- - - - - -
- - - -
{{$t('project.module.timeout')}}
-
- - - - - - - -
- - - -
Auth
-
-
-
- - - -
{{$t('project.module.community')}}
-
- - - - - -
- - - - - - -
{{$t('project.module.contextName')}}
-
- - - - - -
+ + + + + +
-
- {{$t('project.module.tip.defaultEndpointSet')}} -
- {{$t('project.module.tip.relation')}} + +
Enpoint template + +
+ {{$t('project.module.tip.defaultEndpointSet')}} +
+ {{$t('project.module.tip.relation')}} +
+ +
+
+
+ + + + + + + + + + + + + + + + + + + + + +
+ + + + + + + + +
+
+ +
+
+ + + +
+ + + + + + + +
+ +
+
+
+ + + + = + + + + +
+
+
+
+
+ + + +
+ + + + + + + +
+ +
+
+
+ + + + = + + + + +
+
+
+
+
+ + + + + + + + + + + + + + + + + + + + + + + +
+ +
+ asd
- - - - - - - - - - -
- - - - - - - -
- -
-
-
- - - - = - - - - -
-
-
-
- - - -
- - - - - - - -
- -
-
-
- - - - = - - - - -
-
-
-
- - - - +
+
@@ -331,14 +263,21 @@ export default { data () { return { walkData: [], + activeName: 'Basic', expandedWalkData: [], + radio: 'password', editModule: {}, + restaurants: [ + { value: '{{module.name}}-{{asset.name}}' }, + { value: '{{module.name}}-{{asset.manageIp}}' } + ], + showAllBasicOption: false, rules: { name: [ { required: true, message: this.$t('validate.required'), trigger: 'blur' }, { validator: noSpecialChar, trigger: 'change' } ], - project: [ + projectId: [ { required: true, message: this.$t('validate.required'), trigger: 'change' } ], walk: [ @@ -366,7 +305,24 @@ export default { { validator: nzNumber, trigger: 'blur' } ] }, - projectList: [] + projectList: [], + credentialList: [], + typetList: [ + { + value: 'http', + name: 'HTTP' + }, + { + value: 'snmp', + name: 'SNMP' + } + ], + authType: 0, + authTypeList: [ + { name: this.$t('project.endpoint.authTypeNull'), value: 0 }, + { name: this.$t('project.endpoint.authTypeWord'), value: 1 }, + { name: this.$t('project.endpoint.authTypeToken'), value: 2 } + ] } }, methods: { @@ -437,11 +393,13 @@ export default { this.$get('mib/tree', { pageSize: -1, pageNo: 1 }).then(response => { if (response.code === 200) { const obj = JSON.parse(response.data) + console.log(obj) this.walkData = [] for (const item in obj) { setAttr(obj[item], 'detailShow', false) this.walkData.push({ name: item, detailShow: false, subTree: obj[item] }) } + console.log(this.walkData) } }) function setAttr (tree, name, value) { @@ -478,79 +436,26 @@ export default { this.editModule.port = 161 } }, - // 转化snmpParam属性 - parseSnmpParam (module) { - const snmpObj = { // 下划线命名是因为业务需求 - walk: module.walk, - version: module.version, // 2/3 - max_repetitions: module.max_repetitions ? module.max_repetitions : 25, - retries: module.retries ? module.retries : 3, - timeout: module.timeout ? module.timeout + 's' : '10s', // s - auth: { - community: module.community - } - } - if (module.version == 3) { - snmpObj.auth.username = module.username - snmpObj.auth.security_level = module.security_level - snmpObj.auth.context_name = module.context_name - } - if (module.security_level == 'authNoPriv' || module.security_level == 'authPriv') { - snmpObj.auth.password = module.password - snmpObj.auth.auth_protocol = module.auth_protocol - if (module.security_level != 'authNoPriv') { - snmpObj.auth.priv_password = module.priv_password - snmpObj.auth.priv_protocol = module.priv_protocol - } - } - module.snmpParam = JSON.stringify(snmpObj) - }, - // 回显时解析snmpParam - reparseSnmpParam (module) { - if (!module.snmpParam) { - return - } - const snmpObj = JSON.parse(module.snmpParam) - module.walk = snmpObj.walk - module.version = snmpObj.version - module.max_repetitions = snmpObj.max_repetitions - module.retries = snmpObj.retries - module.timeout = parseInt(snmpObj.timeout.replace('s', '')) - module.community = snmpObj.auth.community - if (snmpObj.version == 3) { - module.username = snmpObj.auth.username - module.security_level = snmpObj.auth.security_level - module.context_name = snmpObj.auth.context_name - } - if (snmpObj.auth.security_level == 'authNoPriv' || snmpObj.auth.security_level == 'authPriv') { - module.password = snmpObj.auth.password - module.auth_protocol = snmpObj.auth.auth_protocol - if (snmpObj.auth.security_level != 'authNoPriv') { - module.priv_password = snmpObj.auth.priv_password - module.priv_protocol = snmpObj.auth.priv_protocol - } - } - }, /* 保存 */ save () { - if (this.editModule.type.toLowerCase() == 'snmp') { - this.editModule.paramObj = []// 处理snmp可能会带有param的问题 + this.editModule.configs.param = this.paramToJson(this.editModule.configs.paramObj) + this.editModule.configs.labels = this.labelsToJson(this.editModule.configs.labelModule) + const params = { ...this.editModule } + params.configs.walk = params.walk + params.configs.prot = params.prot + params.configs = JSON.stringify(params.configs) + if (this.authType === 2 && !this.editModule.configs.bearer_token) { + this.$message.error("'token' is required") + } else if (this.authType === 1 && !(this.editModule.configs.basic_auth.username && this.editModule.configs.basic_auth.password)) { + this.$message.error("'username' and 'password' is required") + } else { + this.authType = 0 } - this.editModule.param = this.paramToJson(this.editModule.paramObj) - this.editModule.labels = this.labelsToJson(this.editModule.labelModule) this.$refs.moduleForm.validate((valid) => { if (valid) { this.prevent_opt.save = true - if (this.editModule.type.toLowerCase() == 'snmp') { - this.parseSnmpParam(this.editModule) - } else { - if (this.editModule.snmpParam) { - this.editModule.snmpParam = '' - } - } - this.editModule.projectId = this.editModule.project.id if (this.editModule.id) { - this.$put('module', this.editModule).then(response => { + this.$put('monitor/module', params).then(response => { if (response.code === 200) { this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') }) this.$store.commit('setReloadFacade') @@ -561,7 +466,7 @@ export default { this.prevent_opt.save = false }) } else { - this.$post('module', this.editModule).then(response => { + this.$post('monitor/module', params).then(response => { if (response.code === 200) { this.$message({ duration: 1000, type: 'success', message: this.$t('tip.saveSuccess') }) this.$store.commit('setReloadFacade') @@ -584,7 +489,7 @@ export default { cancelButtonText: this.$t('tip.no'), type: 'warning' }).then(() => { - this.$delete('module?ids=' + this.editModule.id).then(response => { + this.$delete('monitor/module?ids=' + this.editModule.id).then(response => { if (response.code === 200) { this.$message({ duration: 1000, type: 'success', message: this.$t('tip.deleteSuccess') }) this.$store.commit('setReloadFacade') @@ -598,33 +503,40 @@ export default { /* 获取project列表 */ getProjectList () { - this.$get('project', { pageSize: -1, pageNo: 1 }).then(response => { + this.$get('monitor/project', { pageSize: -1, pageNo: 1 }).then(response => { if (response.code === 200) { this.projectList = response.data.list } }) }, - + // get snmp + getCredential () { + this.$get('/snmp/credential', { pageSize: -1, pageNo: 1 }).then(response => { + if (response.code === 200) { + this.credentialList = response.data.list + } + }) + }, // 清除param clearAllParam () { - this.editModule.paramObj = [] + this.editModule.configs.paramObj = [] }, // 新增param addParam () { - this.editModule.paramObj.push({ key: '', value: '' }) + this.editModule.configs.paramObj.push({ key: '', value: '' }) }, // 移除单个param removeParam (index) { - this.editModule.paramObj.splice(index, 1) + this.editModule.configs.paramObj.splice(index, 1) }, // 新增label addLabel () { - this.editModule.labelModule.push({ key: '', value: '' }) + this.editModule.configs.labelModule.push({ key: '', value: '' }) }, // 移除单个Label removeLabel (index) { - this.editModule.labelModule.splice(index, 1) + this.editModule.configs.labelModule.splice(index, 1) }, // 将param转为json字符串格式 paramToJson (param) { @@ -651,6 +563,25 @@ export default { } else { return jsonString } + }, + // 输入建议 + querySearch (queryString, cb) { + const restaurants = this.restaurants + const results = queryString ? restaurants.filter(this.createFilter(queryString)) : restaurants + // 调用 callback 返回建议列表的数据 + cb(results) + }, + createFilter (queryString) { + return (restaurant) => { + return (restaurant.value.toLowerCase().indexOf(queryString.toLowerCase()) === 0) + } + }, + changeAuthType () { + this.editModule.configs.bearer_token = '' + this.editModule.configs.basic_auth = { + username: '', + password: '' + } } }, mounted () { @@ -658,6 +589,7 @@ export default { }, created () { this.getProjectList() + this.getCredential() }, computed: { mibName () { @@ -672,16 +604,30 @@ export default { deep: true, handler (n, o) { this.editModule = JSON.parse(JSON.stringify(n)) - if (n.id) { - this.reparseSnmpParam(this.editModule) + this.activeName = 'Basic' + + if (this.editModule.configs.bearer_token) { + this.authType = 2 + } else if (this.editModule.configs.basic_auth.username) { + this.authType = 1 } else { - if (n.type && n.type.toLowerCase() == 'snmp') { - this.$refs.selectWalk.show() - for (let i = 0; i < this.editModule.walk.length; i++) { - this.expandedWalkData.push(this.editModule.walk[i].substring(0, this.editModule.walk[i].lastIndexOf('.'))) - } + this.authType = 0 + } + if (n.type && n.type.toLowerCase() == 'snmp') { + this.$refs.selectWalk.show() + for (let i = 0; i < this.editModule.walk.length; i++) { + this.expandedWalkData.push(this.editModule.configs.walk[i].substring(0, this.editModule.configs.walk[i].lastIndexOf('.'))) } } + // if (n.id) { + // } else { + // if (n.type && n.type.toLowerCase() == 'snmp') { + // this.$refs.selectWalk.show() + // for (let i = 0; i < this.editModule.walk.length; i++) { + // this.expandedWalkData.push(this.editModule.walk[i].substring(0, this.editModule.walk[i].lastIndexOf('.'))) + // } + // } + // } } } } @@ -733,6 +679,40 @@ export default { color: #999999; line-height: 21px; } + .half-form-item { + width: calc(50% - 30px); + display: inline-block; + padding: 0 18px 0 8px; + } + /deep/ .el-tabs__item{ + width: 90px; + padding: 0; + text-align: center; + } + /deep/ .el-tabs__item.is-active{ + color: #FA901C + } + /deep/ .el-tabs__active-bar{ + background-color: #FA901C + } + /deep/ .el-radio-group{ + width: 100%; + } + /deep/ .el-radio{ + width: 100%; + } + /deep/ .el-autocomplete{ + width: 100%; + } + .need-rotate.nz-icon-drop-down{ + display: inline-block; + transition: transform .3s; + } + .need-rotate.nz-icon-drop-down.is-active{ + transform: rotate( + -180deg + ); + } diff --git a/nezha-fronted/src/components/page/monitor/project/projectList.vue b/nezha-fronted/src/components/page/monitor/project/projectList.vue index 1991679b9..1b0cfa1af 100644 --- a/nezha-fronted/src/components/page/monitor/project/projectList.vue +++ b/nezha-fronted/src/components/page/monitor/project/projectList.vue @@ -8,11 +8,11 @@ :layout="['searchInput', 'elementSet']" :search-msg="searchMsg">