feat: 数据库创建/删除

develop
时启龙 2024-09-06 14:25:39 +08:00
parent b3818e1135
commit 1ffb6347a6
15 changed files with 288 additions and 3256 deletions

View File

@ -1,113 +0,0 @@
<template>
<el-dialog title="白名单列表" :close-on-click-modal="false" :visible.sync="dialog.visible" append-to-body width="800px">
<cb-form ref="addFormRef" :model="addData" label-width="120px">
<cb-advance-table ref="tableRef" row-key="id" :search-configs="searchConfigs" :data="list" :params="params" :columns="columns" :get-list="getList" :total="total" :loading="loading" @selection-change="handleSelectionChange">
<template #action>
<el-button type="primary" :disabled="!selectionIps.length" @click="handleDelete" icon="el-icon-delete">移除</el-button>
</template>
</cb-advance-table>
</cb-form>
<div slot="footer" class="dialog-footer">
<el-button type="ghost" @click.native="dialog.visible = false">取消</el-button>
<el-button type="primary" @click.native="addSubmit" :loading="loading">确定</el-button>
</div>
</el-dialog>
</template>
<script lang="ts">
import { computed, defineComponent, ref, watch } from 'vue'
import { Message } from 'element-ui'
import { getSecurityIps, modifySecurityIps } from '@/views/resource/ctstack/services/database/common'
import { handleSearchParam } from '@cmp/cmp-element'
import useTable from '@cmp/cmp-common/hooks/useTable'
import { columns, searchConfigs as searchConfig } from './config'
export default defineComponent({
props: {
dialog: {
type: Object,
default: () => {}
},
url: {
type: String,
required: true
}
},
setup(props: any, context: any) {
const { record } = props.dialog
const addData = ref({
...record
})
const { list, total, params, loading, getList } = useTable({
getService: getSecurityIps(props.url)
})
const addFormRef = ref(null)
function addSubmit() {
//
const { validate } = (addFormRef.value || context.refs.addFormRef) as HTMLFormElement
validate(async (valid: boolean) => {
if (valid) {
loading.value = true
const { instanceType, productType } = addData.value
// const data = await modifyRedisConfig({
// ...addData.value,
// storageType: productType === 'Tair' && instanceType === 'tair_essd' ? 'essd_pl1' : ''
// })
// loading.value = false
// if (data.success) {
// Message({
// message: data.message,
// type: 'success'
// })
// context.emit('getData')
// ;(props.dialog as Base.IDialog).visible = false
// }
;(props.dialog as Base.IDialog).visible = false
}
})
}
const searchConfigs = ref([...searchConfig]) as any
searchConfigs.value[0].initValue = addData.value.instanceId
async function handleDelete() {
const params: any = {
id: addData.value.id,
securityIps: selectionIps.value,
modifyMode: 'Delete'
}
if (total.value === params.securityIps.length) return Message.error('不能将所选IP地址置空')
const res = await modifySecurityIps(props.url, params)
if (res.success) {
Message.success(res.message)
;(context.refs.tableRef as any).clearSelection()
context.emit('getData')
getList()
}
}
const selectionIps = ref([])
function handleSelectionChange(selection: any) {
selectionIps.value = selection.map((item: any) => item.securityIp)
}
return {
loading,
list,
total,
params,
getList,
addFormRef,
addData,
addSubmit,
columns,
searchConfigs,
handleDelete,
selectionIps,
handleSelectionChange
}
}
})
</script>
<style lang="scss"></style>

View File

@ -1,14 +0,0 @@
export const columns = [
{
type: 'selection',
reserveSelection: true
},
{
label: 'IP地址',
prop: 'securityIp'
}
]
export const searchConfigs: Base.ISearchConfig[] = [
{ type: 'Const', value: 'instanceId', initValue: '' },
{ type: 'Input', label: 'IP地址', value: 'securityIp' }
]

View File

@ -1,42 +0,0 @@
<template>
<div>
<el-dropdown-item :disabled="disabled" @click.native="handleOpen"> 白名单列表 </el-dropdown-item>
<Dialog v-if="addData.visible" :url="url" :dialog="addData" @getData="$emit('getData')"></Dialog>
</div>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import Dialog from './List.vue'
export default defineComponent({
components: { Dialog },
props: {
disabled: {
type: Boolean,
default: false
},
record: {
type: Object,
default: () => {}
},
url: {
type: String,
required: true
}
},
setup(props: any, context: any) {
const addData = ref({
record: { ...props.record },
visible: false
})
function handleOpen() {
addData.value.visible = true
}
return {
addData,
handleOpen
}
}
})
</script>
<style lang="scss"></style>

View File

@ -1,135 +0,0 @@
<template>
<el-dialog title="修改权限" :close-on-click-modal="false" :visible.sync="dialog.visible" width="1100px" append-to-body>
<cb-form ref="addFormRef" :model="addData" label-width="140px">
<cb-form-item label-width="0">
<el-transfer
style="text-align: left; display: inline-block"
v-model="addData.checkedUseRoleIds"
filterable
:titles="['未选择', '已选择']"
:format="{
noChecked: '${total}',
hasChecked: '${checked}/${total}'
}"
:props="{ key: 'name', label: 'name' }"
:data="list"
>
<span slot-scope="{ option }">
<span style="margin-right: 10px">{{ option.name }}</span>
<el-radio-group v-model="option.role" class="role-group">
<el-radio label="ReadWrite">读写</el-radio>
<el-radio label="ReadOnly">只读</el-radio>
<el-radio label="DDLOnly">DDL</el-radio>
<el-radio label="DMLOnly">DML</el-radio>
</el-radio-group>
</span>
</el-transfer>
</cb-form-item>
</cb-form>
<div slot="footer" class="dialog-footer">
<el-button type="ghost" @click.native="dialog.visible = false">取消</el-button>
<el-button type="primary" @click.native="addSubmit" :loading="loading">确定</el-button>
</div>
</el-dialog>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { Message } from 'element-ui'
import { handleSearchParam } from '@cmp/cmp-element'
import { getRdsDbs, authRdsUser } from '@/views/resource/ctstack/services/database/rds'
export default defineComponent({
props: {
dialog: {
type: Object
}
},
setup(props: any, context: any) {
const { record } = props.dialog
const addData = ref({
...record,
checkedUseRoleIds: record.privileges && JSON.parse(record.privileges).map((item: any) => item.name),
privileges: record.privileges ? JSON.parse(record.privileges) : []
})
const list = ref([])
const { vendorId, rdsId } = addData.value
;(async () => {
const res = await getRdsDbs(rdsId, { params: handleSearchParam({ vendorId, rdsId }) })
if (res.success) {
const { checkedUseRoleIds, privileges } = addData.value
console.log(privileges)
list.value = res.data.rows.map((item: any) => {
if (checkedUseRoleIds.includes(item.name)) {
const { accountPrivilege = '' } = privileges.find((role: any) => role.name === item.name) || {}
return {
...item,
role: accountPrivilege
}
} else {
return {
role: 'ReadWrite',
...item
}
}
})
}
})()
const loading = ref(false)
const addFormRef = ref(null)
function addSubmit() {
//
const { validate } = (addFormRef.value || context.refs.addFormRef) as HTMLFormElement
validate(async (valid: boolean) => {
if (valid) {
loading.value = true
const { rdsId, id, checkedUseRoleIds: checkedUserIds, username } = addData.value
const userRoles = list.value
.filter((item: any) => checkedUserIds.includes(item.name))
.map(({ name, role }: any) => {
return {
name,
accountPrivilege: role
}
})
const data = await authRdsUser({ rdsId, userId: id, id, username, privileges: userRoles })
loading.value = false
if (data.success) {
Message({
message: data.message,
type: 'success'
})
context.emit('getData')
;(props.dialog as Base.IDialog).visible = false
}
}
})
}
return {
loading,
addFormRef,
addData,
addSubmit,
list
}
}
})
</script>
<style lang="scss" scoped>
.slider-wrapper {
display: flex;
::v-deep .el-slider__marks-text {
white-space: nowrap;
}
}
::v-deep .el-transfer-panel:nth-child(1) .role-group {
display: none;
}
::v-deep .el-transfer-panel:nth-child(3) {
width: 600px;
}
</style>

View File

@ -1,76 +0,0 @@
/** * Created by HaijunZhang on 2019/4/28. */
<template>
<el-row :gutter="20">
<el-col :span="24">
<cb-form-item label="所属地域:" prop="regionId" validate="required">
<el-radio-group v-model="addData.regionId" @change="getZoneList">
<el-radio-button :label="item.regionId" v-for="item in regionList" :key="item.regionId">{{ item.name }}</el-radio-button>
</el-radio-group>
</cb-form-item>
</el-col>
<el-col :span="24">
<cb-form-item label="可用区:" prop="zone" validate="required">
<el-radio-group v-model="addData.zone" class="simple-radio">
<el-radio-button :label="item.zoneId" v-for="item in zoneList" :key="item.zoneId">{{ item.name }}</el-radio-button>
</el-radio-group>
</cb-form-item>
</el-col>
</el-row>
</template>
<script>
import { computed, defineComponent, reactive, ref, Ref, toRefs } from 'vue'
import { getRegion, getZone } from 'services/platform/index'
export default {
props: {
addData: {
type: Object,
required: true
}
},
setup(props, { root: { $set } }) {
const regionList = ref([])
const zoneList = ref([])
async function getRegionList() {
const res = await getRegion({ vendorId: props.addData.vendorId })
if (res.success) {
regionList.value = res.data
if (!props.addData.regionId) {
$set(props.addData, 'regionId', res.data[0].regionId)
}
getZoneList()
}
}
getRegionList()
async function getZoneList(rgId) {
// rgId
if (props.addData.zone && rgId) props.addData.zone = ''
const { vendorId, regionId } = props.addData
const res = await getZone({ vendorId, regionId })
if (res.success) {
zoneList.value = res.data
if (!props.addData.zone) {
$set(props.addData, 'zone', res.data[0].zoneId)
}
}
}
return {
regionList,
zoneList,
getZoneList
}
}
}
</script>
<style scoped>
.el-radio-button {
margin-bottom: 8px;
}
::v-deep .el-radio-button__inner {
border-left: solid 1px #dcdfe6;
}
.el-icon-question {
color: #bbbbbd;
margin-left: 10px;
}
</style>

View File

@ -1,225 +0,0 @@
<template>
<cb-card-layout title="授权数据库">
<el-row :gutter="10" class="m-b">
<el-col :span="8">
<el-card style="height: 408px">
<div slot="header">
<span>未授权数据库</span>
</div>
<el-form :inline="true">
<el-form-item>
<el-input placeholder="名称" v-model="listQuery.name"> </el-input>
</el-form-item>
<el-form-item>
<el-button type="ghost" icon="el-icon-search" @click="handleSearch"></el-button>
</el-form-item>
</el-form>
<cb-table ref="userTable" :small="true" :data="list" :params="params" :get-list="getList" :total="total" @selection-change="selectionChange">
<el-table-column type="selection" :selectable="selectAble" width="60"> </el-table-column>
<el-table-column show-overflow-tooltip label="名称" prop="name"> </el-table-column>
<el-pagination class="pull-right m-t-sm" slot="pagination" background :page-size="params.rows" :pager-count="5" layout="prev, pager, next" @current-change="getList" :current-page.sync="params.page" :total="total"> </el-pagination>
</cb-table>
</el-card>
</el-col>
<el-col :span="2">
<div>
<div style="height: 204px; line-height: 330px">
<el-button type="primary" size="mini" :disabled="leftSlection.length === 0" @click="addUser"><i class="el-icon-right"></i></el-button>
</div>
<div style="height: 204px">
<el-button type="primary" size="mini" @click="removeUser" :disabled="rightSlection.length === 0"><i class="el-icon-back"></i></el-button>
</div>
</div>
</el-col>
<el-col :span="14">
<el-card style="height: 408px">
<div slot="header">
<span class="">已授权数据库</span>
<span class="pull-right">
全部设 <el-button class="m-r" type="text" @click="setAuth">{{ buttonName }}</el-button>
</span>
</div>
<cb-smart-table :data="selectUserList" :rows="5" @selection-change="selectionChangeCheck">
<el-table-column type="selection" width="60"> </el-table-column>
<el-table-column show-overflow-tooltip label="名称" prop="name"> </el-table-column>
<el-table-column show-overflow-tooltip label="权限" prop="name" width="400px">
<template slot-scope="scope">
<el-radio-group v-model="scope.row.accountPrivilege">
<el-radio label="ReadWrite">读写(DDL+DML)</el-radio>
<el-radio label="ReadOnly">只读</el-radio>
<el-radio label="DDLOnly">仅DDL</el-radio>
<el-radio label="DMLOnly">仅DML</el-radio>
</el-radio-group>
</template>
</el-table-column>
</cb-smart-table>
</el-card>
</el-col>
</el-row>
</cb-card-layout>
</template>
<script>
import { handleSearchParam } from '@cmp/cmp-element'
import { getRdsDbs } from 'views/resource/ctstack/services/database/rds.js'
export default {
props: {
dbIds: {
type: Array,
default: function () {
return []
}
},
rdsId: {
type: Number
},
flag: {
type: Number
}
},
data() {
return {
list: [],
total: 0,
listQuery: {
name: ''
},
params: {
page: 1,
rows: 5
},
leftSlection: [],
rightSlection: [],
selectUserList: [],
buttonName: '读写(DDL+DML)'
}
},
computed: {
userIds() {
const ids = []
for (const a of this.selectUserList) {
ids.push(a.name)
}
return ids
},
privileges() {
const arr = []
for (const a of this.selectUserList) {
const obj = {
name: a.name,
accountPrivilege: a.accountPrivilege
}
arr.push(obj)
}
return arr
}
},
created() {
this.getSelectUser()
},
watch: {
flag: {
handler(newVal, oldVal) {
this.getSelectUser()
}
}
},
methods: {
setAuth() {
if (this.buttonName == '读写(DDL+DML)') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'ReadWrite')
})
this.buttonName = '只读'
} else if (this.buttonName == '只读') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'ReadOnly')
})
this.buttonName = '仅DDL'
} else if (this.buttonName == '仅DDL') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'DDLOnly')
})
this.buttonName = '仅DML'
} else if (this.buttonName == '仅DML') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'DMLOnly')
})
this.buttonName = '读写(DDL+DML)'
}
},
getSelectUser() {
getRdsDbs(this.rdsId, {
page: 1,
rows: 999999,
params: handleSearchParam({
rdsId: this.rdsId
})
}).then(data => {
if (data.success) {
const list = data.data.rows
list.forEach(item => {
if (this.dbIds.indexOf(item.name) > -1) {
this.selectUserList.push(item)
}
})
}
})
this.handleSearch()
},
getList() {
getRdsDbs(this.rdsId, this.params).then(data => {
if (data.success) {
this.list = data.data.rows
this.total = data.data.total
//
this.$nextTick(() => {
this.list.forEach(item => {
if (this.userIds.indexOf(item.name) > -1) this.$refs.userTable.toggleRowSelection(item, true)
})
})
}
})
},
//
handleSearch() {
this.params.page = 1
this.params.params = handleSearchParam({
rdsId: this.rdsId,
'name:LK': this.listQuery.name
})
this.getList()
},
selectionChange(selection) {
this.leftSlection = selection
},
selectionChangeCheck(selection) {
this.rightSlection = selection
},
selectAble(row) {
return !this.userIds.includes(row.name)
},
addUser() {
const users = this.leftSlection.filter(item => {
this.$set(item, 'accountPrivilege', 'ReadWrite')
return !this.userIds.includes(item.name)
})
this.selectUserList.unshift(...users)
},
removeUser() {
const ids = []
this.rightSlection.forEach(item => {
ids.push(item.name)
})
for (let i = 0; i < this.selectUserList.length; i++) {
const item = this.selectUserList[i]
if (ids.includes(item.name)) {
this.selectUserList.splice(i, 1)
i--
}
}
}
}
}
</script>
<style></style>

View File

@ -4,220 +4,47 @@
<template v-slot:action>
<el-button type="primary" @click="handleCreate()"></el-button>
</template>
<template #status="status">
<cb-status-icon :type="statusFilter[status]">
{{ filter[status] }}
<template #name="val, record">
<span class="detail-href" @click="getDetail(record)">{{ (record.instanceId || '--') + ' / ' + val }}</span>
</template>
<template #prodType="val, record">
{{ prodTypeFilter[val] }}
</template>
<template #status="val">
<cb-status-icon :type="statusFilter(val, 'color')">
{{ statusFilter(val, 'status') }}
</cb-status-icon>
</template>
<template #type="type">
{{ filter[type] }}
</template>
<template #payType="payType">
{{ filter[payType] }}
</template>
<template #name="val, record">
<span class="detail-href" @click="getDetail(record.id)">{{ (record.instanceId || '--') + ' / ' + val }}</span>
<template #diskType="val">
{{ val | diskTypeFilter }}
</template>
<template #operate="val, record">
<el-button type="text" @click="patch(record)" :disabled="record.status !== 'Running'"> 重启 </el-button>
<div class="action-divider"></div>
<!-- <el-button type="text" @click="handleReset(record)" :disabled="record.status !== 'Running'"> 重启 </el-button>
<div class="action-divider"></div> -->
<el-button type="text" @click="removeRds(record)" :disabled="record.status !== 'Running'"> 释放实例 </el-button>
</template>
</cb-advance-table>
<add :add-data="addData" v-if="addData.dialog" @back="getData"></add>
<cb-detail v-if="detailFlag" :title="detailData.instanceId + ' / ' + detailData.name" @goBack="goBack">
<template v-slot:item_container>
<cb-detail-item label="名称">{{ detailData.name }}</cb-detail-item>
<cb-detail-item label="状态">{{ filter[detailData.status] }}</cb-detail-item>
<cb-detail-item label="版本">{{ detailData.dataStoreVersion }}</cb-detail-item>
<cb-detail-item label="实例类型">{{ filter[detailData.type] }}</cb-detail-item>
<cb-detail-item label="数据库类型">{{ detailData.dataStoreType }}</cb-detail-item>
<cb-detail-item label="付费类型">{{ filter[detailData.payType] }}</cb-detail-item>
<cb-detail-item label="规格">{{ detailData.flavorId }}</cb-detail-item>
<cb-detail-item label="可用区">{{ detailData.region }}</cb-detail-item>
<cb-detail-item label="实例ID">{{ detailData.instanceId }}</cb-detail-item>
<cb-detail-item label="数据库引擎">{{ detailData.engine }}</cb-detail-item>
<cb-detail-item label="状态">
<cb-status-icon :type="statusFilter(detailData.status, 'color')">
{{ statusFilter(detailData.status, 'status') }}
</cb-status-icon>
</cb-detail-item>
<cb-detail-item label="虚拟IP地址">{{ detailData.vip }}</cb-detail-item>
<cb-detail-item label="虚拟IPv6地址">{{ detailData.vip6 }}</cb-detail-item>
<cb-detail-item label="写数据端口">{{ detailData.writePort }}</cb-detail-item>
<cb-detail-item label="读数据端口">{{ detailData.readPort }}</cb-detail-item>
<cb-detail-item label="存储空间GB">{{ detailData.diskSize }}</cb-detail-item>
<cb-detail-item label="存储类型">{{ detailData.diskType | diskTypeFilter }}</cb-detail-item>
<cb-detail-item label="创建时间">{{ detailData.createTime }}</cb-detail-item>
</template>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="账号列表" name="account">
<el-button class="m-b" type="primary" @click="createAccount()"></el-button>
<cb-table :data="usersList" :params="paramsUsers" :total="totalUsers" :get-list="getUsersList">
<el-table-column prop="username" label="账号" show-overflow-tooltip></el-table-column>
<el-table-column prop="permission" label="类型" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.permission | typeFilter }}
</template>
</el-table-column>
<el-table-column prop="status" label="状态" show-overflow-tooltip>
<template slot-scope="scope">
<cb-status-icon :type="scope.row.status | statusFilter('color')">{{ scope.row.status | statusFilter('status') }} </cb-status-icon>
</template>
</el-table-column>
<el-table-column prop="db" label="所属数据库" show-overflow-tooltip>
<template slot-scope="scope">
<div v-for="item in JSON.parse(scope.row.privileges)" :key="item.name">{{ item.name }} {{ item.accountPrivilege | authFilter }}</div>
</template>
</el-table-column>
<el-table-column prop="remark" label="账号描述" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" show-overflow-tooltip width="250px">
<template slot-scope="scope">
<el-button type="text" @click="resetPasd(scope.row)"></el-button>
<div class="action-divider"></div>
<!-- <el-button type="text" v-if="scope.row.permission == 'Super'" @click="resetAuth(scope.row)"></el-button> -->
<el-button type="text" v-if="scope.row.permission == 'Normal'" @click="modifyAuth(scope.row)"></el-button>
<div class="action-divider" v-if="scope.row.permission == 'Normal'"></div>
<!-- <div class="action-divider" v-if="scope.row.permission == 'Super'"></div> -->
<el-button type="text" @click="deleteAccount(scope.row)"></el-button>
</template>
</el-table-column>
<!-- <div slot="pagination"></div> -->
</cb-table>
<el-dialog title="重置账号" append-to-body v-if="resetFlag" :visible.sync="resetFlag" :close-on-click-modal="false">
<cb-form ref="resetData" :model="resetData" label-width="120px">
<cb-form-item label="数据库账号:" prop="username">
{{ resetData.username }}
</cb-form-item>
<cb-form-item label="密码:" prop="password" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="resetData.password"></el-input>
</cb-form-item>
</cb-form>
<span slot="footer" class="dialog-footer">
<el-button type="ghost" @click.native="resetFlag = false"> </el-button>
<el-button type="primary" @click.native="submitReset"> </el-button>
</span>
</el-dialog>
<el-dialog title="重置账号密码" append-to-body v-if="resetPasdFlag" :visible.sync="resetPasdFlag" :close-on-click-modal="false">
<cb-form ref="resetData" :model="resetData" label-width="120px">
<cb-form-item label="密码:" prop="password" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="resetData.password" show-password></el-input>
</cb-form-item>
<cb-form-item label="确认密码:" prop="password2" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="resetData.password2" show-password></el-input>
</cb-form-item>
</cb-form>
<span slot="footer" class="dialog-footer">
<el-button type="ghost" @click.native="resetPasdFlag = false"> </el-button>
<el-button type="primary" @click.native="submitResetPasd"> </el-button>
</span>
</el-dialog>
<el-drawer append-to-body title="创建用户账号" :visible.sync="drawer" direction="rtl" size="40%">
<el-card>
<cb-form ref="accountData" :model="accountData" label-width="120px">
<cb-form-item label="数据库账号:" prop="username" maxlength="16" :rules="[required, rdsAccountName, { validator: validateKeyword, trigger: 'blur' }]">
<el-tooltip class="item" effect="dark" content="由小写字母、数字、下划线_组成以字母开头以字母或数字结尾最多16个字符" placement="top">
<el-input v-model="accountData.username" auto-complete="off"></el-input>
</el-tooltip>
</cb-form-item>
<cb-form-item class="m-t-lg" label="账号类型:" prop="permission" :rules="[required]">
<el-radio-group v-model="accountData.permission">
<el-radio label="Super" :disabled="Super">高权限账号</el-radio>
<el-radio label="Normal">普通账号</el-radio>
</el-radio-group>
</cb-form-item>
<cb-form-item class="m-t-lg" label="密码:" prop="password" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="accountData.password" auto-complete="off"></el-input>
</cb-form-item>
<cb-form-item class="m-t-lg" label="确认密码:" prop="password2" :rules="[required]">
<el-input type="password" v-model="accountData.password2" auto-complete="off"></el-input>
</cb-form-item>
<cb-form-item class="m-t-lg" label="备注:" prop="remark" maxlength="256">
<el-input type="textarea" v-model="accountData.remark"></el-input>
<div class="text_mine">请输入备注说明,最多256个字符</div>
</cb-form-item>
<el-button type="primary" @click="submitAccount()"></el-button>
<el-button type="ghost" @click="drawer = false">取消</el-button>
</cb-form>
</el-card>
</el-drawer>
<!-- 修改权限 -->
<ModifyRole :dialog="editDialog" v-if="editDialog.visible" @getData="getUsersList"></ModifyRole>
<!-- <el-drawer append-to-body :with-header="false" :visible.sync="drawerAuth" direction="rtl" size="1200px">
<el-card>
<cb-form :model="accountData" label-width="120px">
<cb-form-item label="数据库账号:" prop="username" maxlength="16">
{{accountData.username}}
</cb-form-item>
<modify-db class="m-b" ref="modifyDb" :rdsId="detailData.id" :dbIds="accountData.dbIds" :flag="flag"></modify-db>
<el-button type="primary" @click="submitAuth()"></el-button>
<el-button type="ghost" @click="drawerAuth = false">取消</el-button>
</cb-form>
</el-card>
</el-drawer> -->
</el-tab-pane>
<el-tab-pane label="数据库列表" name="database">
<el-button class="m-b" type="primary" @click="createDB"></el-button>
<cb-table :data="databaseList" :params="paramsDb" :total="totalDb" :get-list="getDbList">
<el-table-column prop="name" label="名称" show-overflow-tooltip></el-table-column>
<el-table-column prop="status" label="状态" show-overflow-tooltip>
<!-- <template slot-scope="scope">
<cb-status-icon :type="scope.row.status | vmStatusColor">{{ scope.row.status | database }} </cb-status-icon>
</template> -->
</el-table-column>
<el-table-column prop="characterSet" label="字符集" show-overflow-tooltip></el-table-column>
<el-table-column prop="accounts" label="绑定账号" show-overflow-tooltip>
<template slot-scope="scope">
<div v-for="(item, index) in JSON.parse(scope.row.accounts)" :key="index">
{{ item.account }}
</div>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注说明" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" show-overflow-tooltip>
<template slot-scope="scope">
<el-button type="text" @click="deleteDB(scope.row)"></el-button>
</template>
</el-table-column>
</cb-table>
<el-drawer append-to-body title="创建数据库" :visible.sync="drawerDB" direction="rtl" size="40%">
<el-card>
<cb-form ref="databaseData" :model="databaseData" label-width="140px">
<cb-form-item
label="数据库(DB)名称:"
prop="name"
:rules="[
{
pattern: /^[a-z]([a-z0-9_-]{1,62})?([a-z0-9])$/,
message: '由小写字母、数字、下划线、中划线组成以字母开头字母或数字结尾最多64个字符',
trigger: null
},
{
validator: validateKeyword,
trigger: 'blur'
}
]"
validate="required"
>
<el-input v-model="databaseData.name" placeholder="请输入数据库名称" clearable></el-input>
</cb-form-item>
<cb-form-item class="m-t-lg" label="支持字符集:" prop="characterSet">
<el-select v-model="databaseData.characterSet" placeholder="请选择">
<el-option v-for="item in codeData" :key="item" :label="item" :value="item"> </el-option>
</el-select>
</cb-form-item>
<!-- <cb-form-item class="m-t-lg" label="授权账号:" prop="accountId">
<el-select v-model="databaseData.accountId" placeholder="请选择">
<el-option v-for="item in accounts" :key="item.id" :label="item.username" :value="item.id">
</el-option>
</el-select>
</cb-form-item> -->
<cb-form-item class="m-t-lg" label="账号类型:" prop="accountPrivilege" :rules="[required]" v-if="databaseData.accountId" key="accountPrivilege">
<el-radio-group v-model="databaseData.accountPrivilege">
<el-radio label="ReadWrite">读写 </el-radio>
<el-radio label="ReadOnly">只读 </el-radio>
<el-radio label="DDLOnly">仅DDL </el-radio>
<el-radio label="DMLOnly">仅DML </el-radio>
</el-radio-group>
</cb-form-item>
<cb-form-item class="m-t-lg" label="备注说明:" prop="remark" maxlength="256">
<el-input type="textarea" v-model="databaseData.remark"></el-input>
<div class="text_mine">请输入备注说明,最多256个字符</div>
</cb-form-item>
<el-button type="primary" @click="submitDB()"></el-button>
<el-button type="ghost" @click="drawerDB = false">取消</el-button>
</cb-form>
</el-card>
</el-drawer>
</el-tab-pane>
<el-tab-pane label="连接地址管理" name="connection">
<cb-table :data="connectionList" :params="paramsCo" :total="totalDo" :get-list="getCoList">
<cb-table :data="connectionList" :params="paramsConnection" :total="totalConnection" :get-list="getConnectionList">
<el-table-column label="网络类型" show-overflow-tooltip>
<template slot-scope="scope">
{{ instanceNetworkTypeMap[scope.row.instanceNetworkType] + '(' + ipTypeMap[scope.row.ipType] + ')' }}
@ -227,46 +54,17 @@
<el-table-column prop="port" label="端口" show-overflow-tooltip></el-table-column>
</cb-table>
</el-tab-pane>
<!-- <el-tab-pane label="参数设置" name="params">
<el-tabs value="modify">
<el-tab-pane label="可修改参数" name="modify">
<cb-table :data="detailData.nodes">
<el-table-column prop="name" label="参数名" show-overflow-tooltip></el-table-column>
<el-table-column prop="type" label="参数默认值" show-overflow-tooltip></el-table-column>
<el-table-column prop="db" label="运行参数值" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.params}} <el-button type="text" class="el-icon-edit"></el-button>
</template>
</el-table-column>
<el-table-column prop="remark" label="是否重启" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="参数值范围" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="参数描述" show-overflow-tooltip></el-table-column>
<div slot="pagination"></div>
</cb-table>
</el-tab-pane>
<el-tab-pane label="参数修改历史" name="history">
<cb-table :data="detailData.nodes">
<el-table-column prop="name" label="参数名" show-overflow-tooltip></el-table-column>
<el-table-column prop="type" label="变更前参数值" show-overflow-tooltip></el-table-column>
<el-table-column prop="db" label="变更后参数值" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="是否生效" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="变更时间" show-overflow-tooltip></el-table-column>
</cb-table>
</el-tab-pane>
</el-tabs>
</el-tab-pane> -->
</el-tabs>
</cb-detail>
<Add :add-data="addData" v-if="addData.dialog" @back="getData"></Add>
</div>
</template>
<script>
import validate from '@/validate'
import { getRegion } from 'services/platform/index'
import { getRds, detailRds, getRdsCos, patchRds, removeRds, getRdsUsers, createRdsUsers, removeRdsUsers, resetRdsUserPasd, resetRdsUser, authRdsUser, getRdsDbs, createRdsDbs, removeRdsDbs } from 'views/resource/ctstack/services/database/rds.js'
import add from '../components/add.vue'
import ModifyRole from './ModifyRole.vue'
import { keywords } from './validate'
import { getRds, getRdsCos, patchRds, removeRds } from 'views/resource/ctstack/services/database/rds.js'
import Add from '../components/Add.vue'
import { handleSearchParam } from '@cmp/cmp-element'
const columns = [
{
@ -275,28 +73,47 @@ const columns = [
scopedSlots: { customRender: 'name' }
},
{
label: '状态',
label: '实例类型',
prop: 'prodType',
scopedSlots: { customRender: 'prodType' }
},
{
label: '数据库引擎',
prop: 'engine'
},
{
label: '状态', // mysql
prop: 'status',
scopedSlots: { customRender: 'status' }
},
{
label: '版本',
prop: 'dataStoreVersion'
label: '虚拟IP地址',
prop: 'vip'
},
{
label: '规格',
prop: 'cpu',
customRender(cpu, { memory }) {
return cpu && memory ? `${cpu}C/${memory}GB` : '--'
}
label: '虚拟IPv6地址', // mysql
prop: 'vip6'
},
{
label: '存储空间GB',
prop: 'volSize'
label: '写数据端口',
prop: 'writePort'
},
{
label: '读数据端口',
prop: 'readPort'
},
{
label: '存储空间GB', // mysql
prop: 'diskSize'
},
{
label: '存储类型', // mysql
prop: 'diskType',
scopedSlots: { customRender: 'diskType' }
},
{
label: '创建时间',
prop: 'createDate'
prop: 'createTime'
},
{
label: '操作',
@ -306,33 +123,24 @@ const columns = [
}
]
const validateKeyword = (rule, value, callback) => {
const valid = keywords.find(item => item.toLocaleLowerCase() === value)
if (!valid) {
callback()
} else {
callback(new Error(`${valid.toLocaleLowerCase()}为关键字,不能输入`))
}
}
const instanceNetworkTypeMap = {
VPC: '专有网络',
Classic: '经典网络'
}
const ipTypeMap = {
Inner: '内网',
Public: '外网',
Private: '内网'
}
export default {
props: {
platformObject: {
type: Object
}
},
components: { add, ModifyRole },
components: { Add },
filters: {
diskTypeFilter(value) {
// 1SATA2SAS 3-SSD 4-LVM
const obj = {
1: 'SATA',
2: 'SAS',
3: 'SSD',
4: 'LVM'
}
return obj[value]
},
typeFilter(value) {
const obj = {
Normal: '普通账号',
@ -341,36 +149,68 @@ export default {
return obj[value]
},
statusFilter(value, type) {
// 0. 1. 2. 3. 4. 5. 6&7. 8. 9. 10.
const obj = {
Unavailable: {
status: '未激活',
color: 'info'
},
Available: {
status: ' 已激活',
0: {
status: '运行中',
color: 'success'
},
1: {
status: '重启中',
color: 'warning'
},
2: {
status: '备份中',
color: 'warning'
},
3: {
status: '恢复中',
color: 'warning'
},
4: {
status: '修改参数中',
color: 'warning'
},
5: {
status: '应用参数组中',
color: 'warning'
},
6: {
status: '扩容中',
color: 'warning'
},
7: {
status: '扩容中',
color: 'warning'
},
8: {
status: '修改端口中',
color: 'warning'
},
9: {
status: '迁移中',
color: 'warning'
},
10: {
status: '重置密码中',
color: 'warning'
}
}
return obj[value] && obj[value][type]
},
authFilter(value) {
const obj = {
ReadWrite: '读写(DDL+DML)',
ReadOnly: '只读',
DDLOnly: '仅DDL',
DMLOnly: 'DMLOnly'
}
return obj[value]
}
},
data() {
return {
validateKeyword,
ipTypeMap,
instanceNetworkTypeMap,
ipTypeMap: {
Inner: '内网',
Public: '外网',
Private: '内网'
},
instanceNetworkTypeMap: {
VPC: '专有网络',
Classic: '经典网络'
},
required: validate.required,
rdsAccountName: { pattern: /^[a-z]([a-z0-9_-]{0,14}[a-z0-9])?$/, message: '由小写字母、数字、下划线_组成以字母开头以字母或数字结尾最多16个字符', trigger: null },
rdsDBPassword: { pattern: '^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,32}$', message: '必须包含三种及以上类型大小写字母、数字、特殊符号。长度为8-32位特殊字符包括! @ # $ % ^ & * () _ + - =', trigger: null },
searchConfigs: [
{ type: 'Input', label: '名称', value: 'name' },
{ type: 'Select', label: '所属地域', data: [], value: 'regionId', props: { value: 'regionId' } },
@ -403,98 +243,23 @@ export default {
RebootFailed: '重启失败',
DBInstanceClassChanging: '升降级中'
},
statusFilter: {
Creating: 'warning',
Running: 'success',
Deleting: 'warning',
Rebooting: 'warning',
RebootFailed: 'danger',
DBInstanceClassChanging: 'warning'
prodTypeFilter: {
0: '单机版',
1: '一主一备',
2: '一主两备',
3: '一主三备'
},
addData: {
dialog: false,
data: {}
},
activeName: 'account',
//
paramsUsers: {
page: 1,
rows: 10
},
totalUsers: 0,
usersList: [],
drawer: false,
accountData: {},
drawerAuth: false,
//
resetFlag: false,
resetPasdFlag: false,
resetData: {},
//
drawerDB: false,
databaseData: {},
codeData: [
'utf8mb4',
'utf8',
'gbk',
'gb18030',
'latin1',
'euckr',
'armscii8',
'ascii',
'big5',
'binary',
'cp1250',
'cp1251',
'cp1256',
'cp1257',
'cp850',
'cp852',
'cp866',
'cp932',
'dec8',
'eucjpms',
'gb2312',
'geostd8',
'greek',
'hebrew',
'hp8',
'keybcs2',
'koi8r',
'koi8u',
'latin2',
'latin5',
'latin7',
'macce',
'macroman',
'sjis',
'swe7',
'tis620',
'ucs2',
'ujis',
'utf16',
'utf16le',
'utf32'
],
accounts: [],
databaseList: [],
paramsDb: {
page: 1,
rows: 10
},
totalDb: 0,
flag: 0,
Super: false,
activeName: 'connection',
connectionList: [],
paramsCo: {
paramsConnection: {
page: 1,
rows: 10
},
totalDo: 0,
editDialog: {
visible: false,
record: {}
}
totalConnection: 0
}
},
watch: {
@ -517,18 +282,18 @@ export default {
this.getRegion()
},
methods: {
async getCoList(id) {
this.paramsCo.params = handleSearchParam({
async getConnectionList(id) {
this.paramsConnection.params = handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
const res = await getRdsCos(id, this.paramsCo)
const res = await getRdsCos(id, this.paramsConnection)
if (res.success) {
this.totalDo = res.data.total
this.totalConnection = res.data.total
this.connectionList = res.data.rows
}
},
patch(data) {
handleReset(data) {
this.$confirm('确定重启该实例吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@ -579,279 +344,21 @@ export default {
type: 'MYSQL'
}
},
getDetail(id) {
this.Super = false
detailRds(id).then(data => {
if (data.success) {
this.detailData = data.data
this.detailFlag = true
this.getUsersList()
}
})
getDetail(record) {
this.detailData = { ...record }
this.detailFlag = true
},
handleClick() {
switch (this.activeName) {
case 'account':
this.getUsersList()
break
case 'database':
this.getDbList()
break
case 'connection':
this.getCoList(this.detailData.id)
this.getConnectionList(this.detailData.id)
break
}
},
getUsersList() {
this.paramsUsers.params = handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
getRdsUsers(this.detailData.id, this.paramsUsers).then(data => {
if (data.success) {
this.usersList = data.data.rows
this.totalUsers = data.data.total
}
})
getRdsUsers(this.detailData.id, {
simple: true,
params: handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
}).then(data => {
if (data.success) {
const list = data.data.rows
list.forEach(item => {
if (item.permission == 'Super') {
this.Super = true
}
})
}
})
},
getDbList() {
this.paramsDb.params = handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
getRdsDbs(this.detailData.id, this.paramsDb).then(data => {
if (data.success) {
this.databaseList = data.data.rows
this.totalDb = data.data.total
}
})
},
goBack() {
this.detailFlag = false
},
//
createAccount() {
this.drawer = true
this.accountData = {
rdsId: this.detailData.id,
vendorId: this.detailData.vendorId
}
},
submitAccount() {
this.$refs.accountData.validate(valid => {
if (valid) {
if (this.accountData.password !== this.accountData.password2) {
return this.$message.error('两次密码输入不一致')
}
const { vendorId, username, password, rdsId, permission, remark } = this.accountData
createRdsUsers(this.accountData.rdsId, {
rdsId: rdsId,
vendorId: vendorId,
username: username,
permission: permission,
password: crypto.encrypt(password),
remark: remark
}).then(data => {
if (data.success) {
this.$message.success(data.message)
this.drawer = false
this.getUsersList()
}
})
}
})
},
//
deleteAccount(data) {
this.$confirm(`您确定要删除【${data.username}】吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeRdsUsers({
rdsId: this.detailData.id,
userId: data.id
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.getUsersList()
}
})
})
},
//
modifyAuth(data) {
// this.getDbList()
this.flag++
const privilege = data.privilege ? JSON.parse(data.privilege) : []
const arr = []
privilege.forEach(element => {
arr.push(element.name)
})
// this.accountData = {
// rdsId: this.detailData.id,
// userId: data.id,
// username: data.username,
// dbIds: arr
// }
this.editDialog = {
record: { ...data },
visible: true
}
},
submitAuth() {
const { rdsId, username, userId } = this.accountData
authRdsUser({
rdsId: rdsId,
userId: userId,
id: userId,
username: username,
privileges: this.$refs.modifyDb.privileges
}).then(data => {
if (data.success) {
this.$message.success(data.message)
this.getUsersList()
this.drawerAuth = false
}
})
},
//
resetAuth(data) {
this.resetData = {
rdsId: this.detailData.id,
userId: data.id,
password: '',
username: data.username
}
this.resetFlag = true
},
submitReset() {
this.$refs.resetData.validate(valid => {
if (valid) {
const { rdsId, userId, password } = this.resetData
resetRdsUser({
rdsId: rdsId,
userId: userId,
password: crypto.encrypt(password)
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.resetFlag = false
this.getUsersList()
}
})
}
})
},
resetPasd(data) {
//
this.resetData = {
rdsId: this.detailData.id,
userId: data.id,
username: data.username
}
this.resetPasdFlag = true
},
submitResetPasd() {
this.$refs.resetData.validate(valid => {
if (valid) {
if (this.resetData.password !== this.resetData.password2) {
return this.$message.error('两次密码输入不一致')
}
const { rdsId, userId, password } = this.resetData
resetRdsUserPasd({
rdsId: rdsId,
userId: userId,
password: crypto.encrypt(password)
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.resetPasdFlag = false
this.getUsersList()
}
})
}
})
},
createDB() {
this.drawerDB = true
getRdsUsers(this.detailData.id, {
page: 1,
rows: 99999,
params: handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id,
permission: 'Normal'
})
}).then(data => {
if (data.success) {
this.accounts = data.data.rows
}
})
this.databaseData = {
name: '',
accountPrivilege: 'ReadWrite',
characterSet: 'utf8'
}
},
submitDB() {
this.$refs.databaseData.validate(valid => {
if (valid) {
createRdsDbs(this.detailData.id, this.databaseData).then(data => {
if (data.success) {
this.$message.success(data.message)
this.drawerDB = false
this.getDbList()
}
})
}
})
},
deleteDB(data) {
this.$confirm(`您确定要删除【${data.name}】吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeRdsDbs({
rdsId: this.detailData.id,
dbId: data.id
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.getDbList()
}
})
})
}, //
//
getRegion() {
getRegion({ vendorId: this.platformObject.vendorId }).then(data => {
if (data.success) {

View File

@ -1,439 +0,0 @@
export const keywords = [
// RDS MySQL
'ACTION',
'ADD',
'ADMIN',
'ALL',
'ALTER',
'ANALYZE',
'AND',
'AS',
'ASC',
'ASENSITIVE',
'BEFORE',
'BETWEEN',
'BIGINT',
'BINARY',
'BLOB',
'BOTH',
'BY',
'CALL',
'CASCADE',
'CASE',
'CHANGE',
'CHAR',
'CHARACTER',
'CHECK',
'COLLATE',
'COLUMN',
'CONDITION',
'CONNECTION',
'CONSTRAINT',
'CONTINUE',
'CONVERT',
'CREATE',
'CROSS',
'CURRENT_DATE',
'CURRENT_TIME',
'CURRENT_TIMESTAMP',
'CURRENT_USER',
'CURSOR',
'DATABASE',
'DATABASES',
'DAY_HOUR',
'DAY_MICROSECOND',
'DAY_MINUTE',
'DAY_SECOND',
'DEC',
'DECIMAL',
'DECLARE',
'DEFAULT',
'DELAYED',
'DELETE',
'DESC',
'DESCRIBE',
'DETERMINISTIC',
'DISTINCT',
'DISTINCTROW',
'DIV',
'DOUBLE',
'DROP',
'DUAL',
'EACH',
'EAGLEYE',
'ELSE',
'ELSEIF',
'ENCLOSED',
'ESCAPED',
'EXISTS',
'EXIT',
'EXPLAIN',
'FALSE',
'FETCH',
'FLOAT',
'FLOAT4',
'FLOAT8',
'FOR',
'FORCE',
'FOREIGN',
'FROM',
'FULLTEXT',
'GOTO',
'GRANT',
'GROUP',
'GUEST',
'HAVING',
'HIGH_PRIORITY',
'HOUR_MICROSECOND',
'HOUR_MINUTE',
'HOUR_SECOND',
'IF',
'IGNORE',
'IN',
'INDEX',
'INFILE',
'INFORMATION_SCHEMA',
'INNER',
'INOUT',
'INSENSITIVE',
'INSERT',
'INT',
'INT1',
'INT2',
'INT3',
'INT4',
'INT8',
'INTEGER',
'INTERVAL',
'INTO',
'IS',
'ITERATE',
'JOIN',
'KEY',
'KEYS',
'KILL',
'LABEL',
'LEADING',
'LEAVE',
'LEFT',
'LIKE',
'LIMIT',
'LINEAR',
'LINES',
'LOAD',
'LOCALTIME',
'LOCALTIMESTAMP',
'LOCK',
'LONG',
'LONGBLOB',
'LONGTEXT',
'LOOP',
'LOW_PRIORITY',
'MATCH',
'MEDIUMBLOB',
'MEDIUMINT',
'MEDIUMTEXT',
'MIDDLEINT',
'MINUTE_MICROSECOND',
'MINUTE_SECOND',
'MOD',
'MODIFIES',
'MYSQL',
'NATURAL',
'NO_WRITE_TO_BINLOG',
'NOT',
'NULL',
'NUMERIC',
'ON',
'OPTIMIZE',
'OPTION',
'OPTIONALLY',
'OR',
'ORDER',
'OUT',
'OUTER',
'OUTFILE',
'PERFORMANCE_SCHEMA',
'PRECISION',
'PRIMARY',
'PROCEDURE',
'PURGE',
'RAID0',
'RANGE',
'READ',
'READS',
'REAL',
'REFERENCES',
'REGEXP',
'RELEASE',
'RENAME',
'REPEAT',
'REPLACE',
'REPLICATOR',
'REQUIRE',
'RESTRICT',
'RETURN',
'REVOKE',
'RIGHT',
'RLIKE',
'ROOT',
'SCHEMA',
'SCHEMAS',
'SECOND_MICROSECOND',
'SELECT',
'SENSITIVE',
'SEPARATOR',
'SET',
'SHOW',
'SMALLINT',
'SPATIAL',
'SPECIFIC',
'SQL',
'SQL_BIG_RESULT',
'SQL_CALC_FOUND_ROWS',
'SQL_SMALL_RESULT',
'SQLEXCEPTION',
'SQLSTATE',
'SQLWARNING',
'SSL',
'STARTING',
'STRAIGHT_JOIN',
'TABLE',
'TERMINATED',
'TEST',
'THEN',
'TINYBLOB',
'TINYINT',
'TINYTEXT',
'TO',
'TRAILING',
'TRIGGER',
'TRUE',
'UNDO',
'UNION',
'UNIQUE',
'UNLOCK',
'UNSIGNED',
'UPDATE',
'USAGE',
'USE',
'USING',
'UTC_DATE',
'UTC_TIME',
'UTC_TIMESTAMP',
'VALUES',
'VARBINARY',
'VARCHAR',
'VARCHARACTER',
'VARYING',
'WHEN',
'WHERE',
'WHILE',
'WITH',
'WRITE',
'X509',
'XOR',
'XTRABAK',
'YEAR_MONTH',
'ZEROFILL',
// RDS SQL Server
'ADD',
'ADMIN',
'ADMINISTRATOR',
'ALL',
'ALTER',
'AND',
'ANY',
'AS',
'ASC',
'AURORA',
'AUTHORIZATION',
'BACKUP',
'BEGIN',
'BETWEEN',
'BREAK',
'BROWSE',
'BULK',
'BULKADMIN',
'BY',
'CASCADE',
'CASE',
'CHECK',
'CHECKPOINT',
'CLOSE',
'CLUSTERED',
'COALESCE',
'COLLATE',
'COLUMN',
'COMMIT',
'COMPUTE',
'CONSTRAINT',
'CONTAINS',
'CONTAINSTABLE',
'CONTINUE',
'CONVERT',
'CREATE',
'CROSS',
'CURRENT',
'CURRENT_DATE',
'CURRENT_TIME',
'CURRENT_TIMESTAMP',
'CURRENT_USER',
'CURSOR',
'DATABASE',
'DBCC',
'DBCREATOR',
'DEALLOCATE',
'DECLARE',
'DEFAULT',
'DELETE',
'DENY',
'DESC',
'DISK',
'DISKADMIN',
'DISTINCT',
'DISTRIBUTED',
'DISTRIBUTION',
'DOUBLE',
'DROP',
'DUMMY',
'DUMP',
'EAGLEYE',
'ELSE',
'END',
'ERRLVL',
'ESCAPE',
'EXCEPT',
'EXEC',
'EXECUTE',
'EXISTS',
'EXIT',
'FETCH',
'FILE',
'FILLFACTOR',
'FOR',
'FOREIGN',
'FREETEXT',
'FREETEXTTABLE',
'FROM',
'FULL',
'FUNCTION',
'GALAXY',
'GOTO',
'GRANT',
'GROUP',
'GUEST',
'HAVING',
'HOLDLOCK',
'IDENTITY',
'IDENTITY_INSERT',
'IDENTITYCOL',
'IF',
'IN',
'INDEX',
'INNER',
'INSERT',
'INTERSECT',
'INTO',
'IS',
'JOIN',
'KEY',
'KILL',
'LEFT',
'LIKE',
'LINENO',
'LOAD',
'MASTER',
'MODEL',
'MSDB',
'MSSQLD',
'MSSQLSYSTEMRESOURCE',
'NATIONAL',
'NOCHECK',
'NONCLUSTERED',
'NOT',
'NULL',
'NULLIF',
'OF',
'OFF',
'OFFSETS',
'ON',
'OPEN',
'OPENDATASOURCE',
'OPENQUERY',
'OPENROWSET',
'OPENXML',
'OPTION',
'OR',
'ORDER',
'OUTER',
'OVER',
'PERCENT',
'PLAN',
'PRECISION',
'PRIMARY',
'PRINT',
'PROC',
'PROCEDURE',
'PROCESSADMIN',
'PUBLIC',
'PUBLIC',
'RAISERROR',
'READ',
'READTEXT',
'RECONFIGURE',
'REFERENCES',
'REPLICATION',
'RESTORE',
'RESTRICT',
'RETURN',
'REVOKE',
'RIGHT',
'ROLLBACK',
'ROOT',
'ROWCOUNT',
'ROWGUIDCOL',
'RULE',
'SA',
'SAVE',
'SCHEMA',
'SECURITYADMIN',
'SELECT',
'SERVERADMIN',
'SESSION_USER',
'SET',
'SETUPADMIN',
'SETUSER',
'SHUTDOWN',
'SOME',
'STATISTICS',
'SYSADMIN',
'SYSTEM_USER',
'TABLE',
'TEMPDB',
'TEXTSIZE',
'THEN',
'TO',
'TOP',
'TRAN',
'TRANSACTION',
'TRIGGER',
'TRUNCATE',
'TSEQUAL',
'UNION',
'UNIQUE',
'UPDATE',
'UPDATETEXT',
'USE',
'USER',
'VALUES',
'VARYING',
'VIEW',
'WAITFOR',
'WHEN',
'WHERE',
'WHILE',
'WITH',
'WRITETEXT'
]

View File

@ -1,135 +0,0 @@
<template>
<el-dialog title="修改权限" :close-on-click-modal="false" :visible.sync="dialog.visible" width="1100px" append-to-body>
<cb-form ref="addFormRef" :model="addData" label-width="140px">
<cb-form-item label-width="0">
<el-transfer
style="text-align: left; display: inline-block"
v-model="addData.checkedUseRoleIds"
filterable
:titles="['未选择', '已选择']"
:format="{
noChecked: '${total}',
hasChecked: '${checked}/${total}'
}"
:props="{ key: 'name', label: 'name' }"
:data="list"
>
<span slot-scope="{ option }">
<span style="margin-right: 10px">{{ option.name }}</span>
<el-radio-group v-model="option.role" class="role-group">
<el-radio label="ReadWrite">读写</el-radio>
<el-radio label="ReadOnly">只读</el-radio>
<el-radio label="DDLOnly">DDL</el-radio>
<el-radio label="DMLOnly">DML</el-radio>
</el-radio-group>
</span>
</el-transfer>
</cb-form-item>
</cb-form>
<div slot="footer" class="dialog-footer">
<el-button type="ghost" @click.native="dialog.visible = false">取消</el-button>
<el-button type="primary" @click.native="addSubmit" :loading="loading">确定</el-button>
</div>
</el-dialog>
</template>
<script lang="ts">
import { defineComponent, ref } from 'vue'
import { Message } from 'element-ui'
import { handleSearchParam } from '@cmp/cmp-element'
import { getRdsDbs, authRdsUser } from '@/views/resource/ctstack/services/database/rds'
export default defineComponent({
props: {
dialog: {
type: Object
}
},
setup(props: any, context: any) {
const { record } = props.dialog
const addData = ref({
...record,
checkedUseRoleIds: record.privileges && JSON.parse(record.privileges).map((item: any) => item.name),
privileges: record.privileges ? JSON.parse(record.privileges) : []
})
const list = ref([])
const { vendorId, rdsId } = addData.value
;(async () => {
const res = await getRdsDbs(rdsId, { params: handleSearchParam({ vendorId, rdsId }) })
if (res.success) {
const { checkedUseRoleIds, privileges } = addData.value
console.log(privileges)
list.value = res.data.rows.map((item: any) => {
if (checkedUseRoleIds.includes(item.name)) {
const { accountPrivilege = '' } = privileges.find((role: any) => role.name === item.name) || {}
return {
...item,
role: accountPrivilege
}
} else {
return {
role: 'ReadWrite',
...item
}
}
})
}
})()
const loading = ref(false)
const addFormRef = ref(null)
function addSubmit() {
//
const { validate } = (addFormRef.value || context.refs.addFormRef) as HTMLFormElement
validate(async (valid: boolean) => {
if (valid) {
loading.value = true
const { rdsId, id, checkedUseRoleIds: checkedUserIds, username } = addData.value
const userRoles = list.value
.filter((item: any) => checkedUserIds.includes(item.name))
.map(({ name, role }: any) => {
return {
name,
accountPrivilege: role
}
})
const data = await authRdsUser({ rdsId, userId: id, id, username, privileges: userRoles })
loading.value = false
if (data.success) {
Message({
message: data.message,
type: 'success'
})
context.emit('getData')
;(props.dialog as Base.IDialog).visible = false
}
}
})
}
return {
loading,
addFormRef,
addData,
addSubmit,
list
}
}
})
</script>
<style lang="scss" scoped>
.slider-wrapper {
display: flex;
::v-deep .el-slider__marks-text {
white-space: nowrap;
}
}
::v-deep .el-transfer-panel:nth-child(1) .role-group {
display: none;
}
::v-deep .el-transfer-panel:nth-child(3) {
width: 600px;
}
</style>

View File

@ -1,76 +0,0 @@
/** * Created by HaijunZhang on 2019/4/28. */
<template>
<el-row :gutter="20">
<el-col :span="24">
<cb-form-item label="所属地域:" prop="regionId" validate="required">
<el-radio-group v-model="addData.regionId" @change="getZoneList">
<el-radio-button :label="item.regionId" v-for="item in regionList" :key="item.regionId">{{ item.name }}</el-radio-button>
</el-radio-group>
</cb-form-item>
</el-col>
<el-col :span="24">
<cb-form-item label="可用区:" prop="zone" validate="required">
<el-radio-group v-model="addData.zone" class="simple-radio">
<el-radio-button :label="item.zoneId" v-for="item in zoneList" :key="item.zoneId">{{ item.name }}</el-radio-button>
</el-radio-group>
</cb-form-item>
</el-col>
</el-row>
</template>
<script>
import { computed, defineComponent, reactive, ref, Ref, toRefs } from 'vue'
import { getRegion, getZone } from 'services/platform/index'
export default {
props: {
addData: {
type: Object,
required: true
}
},
setup(props, { root: { $set } }) {
const regionList = ref([])
const zoneList = ref([])
async function getRegionList() {
const res = await getRegion({ vendorId: props.addData.vendorId })
if (res.success) {
regionList.value = res.data
if (!props.addData.regionId) {
$set(props.addData, 'regionId', res.data[0].regionId)
}
getZoneList()
}
}
getRegionList()
async function getZoneList(rgId) {
// rgId
if (props.addData.zone && rgId) props.addData.zone = ''
const { vendorId, regionId } = props.addData
const res = await getZone({ vendorId, regionId })
if (res.success) {
zoneList.value = res.data
if (!props.addData.zone) {
$set(props.addData, 'zone', res.data[0].zoneId)
}
}
}
return {
regionList,
zoneList,
getZoneList
}
}
}
</script>
<style scoped>
.el-radio-button {
margin-bottom: 8px;
}
::v-deep .el-radio-button__inner {
border-left: solid 1px #dcdfe6;
}
.el-icon-question {
color: #bbbbbd;
margin-left: 10px;
}
</style>

View File

@ -1,225 +0,0 @@
<template>
<cb-card-layout title="授权数据库">
<el-row :gutter="10" class="m-b">
<el-col :span="8">
<el-card style="height: 408px">
<div slot="header">
<span>未授权数据库</span>
</div>
<el-form :inline="true">
<el-form-item>
<el-input placeholder="名称" v-model="listQuery.name"> </el-input>
</el-form-item>
<el-form-item>
<el-button type="ghost" icon="el-icon-search" @click="handleSearch"></el-button>
</el-form-item>
</el-form>
<cb-table ref="userTable" :small="true" :data="list" :params="params" :get-list="getList" :total="total" @selection-change="selectionChange">
<el-table-column type="selection" :selectable="selectAble" width="60"> </el-table-column>
<el-table-column show-overflow-tooltip label="名称" prop="name"> </el-table-column>
<el-pagination class="pull-right m-t-sm" slot="pagination" background :page-size="params.rows" :pager-count="5" layout="prev, pager, next" @current-change="getList" :current-page.sync="params.page" :total="total"> </el-pagination>
</cb-table>
</el-card>
</el-col>
<el-col :span="2">
<div>
<div style="height: 204px; line-height: 330px">
<el-button type="primary" size="mini" :disabled="leftSlection.length === 0" @click="addUser"><i class="el-icon-right"></i></el-button>
</div>
<div style="height: 204px">
<el-button type="primary" size="mini" @click="removeUser" :disabled="rightSlection.length === 0"><i class="el-icon-back"></i></el-button>
</div>
</div>
</el-col>
<el-col :span="14">
<el-card style="height: 408px">
<div slot="header">
<span class="">已授权数据库</span>
<span class="pull-right">
全部设 <el-button class="m-r" type="text" @click="setAuth">{{ buttonName }}</el-button>
</span>
</div>
<cb-smart-table :data="selectUserList" :rows="5" @selection-change="selectionChangeCheck">
<el-table-column type="selection" width="60"> </el-table-column>
<el-table-column show-overflow-tooltip label="名称" prop="name"> </el-table-column>
<el-table-column show-overflow-tooltip label="权限" prop="name" width="400px">
<template slot-scope="scope">
<el-radio-group v-model="scope.row.accountPrivilege">
<el-radio label="ReadWrite">读写(DDL+DML)</el-radio>
<el-radio label="ReadOnly">只读</el-radio>
<el-radio label="DDLOnly">仅DDL</el-radio>
<el-radio label="DMLOnly">仅DML</el-radio>
</el-radio-group>
</template>
</el-table-column>
</cb-smart-table>
</el-card>
</el-col>
</el-row>
</cb-card-layout>
</template>
<script>
import { handleSearchParam } from '@cmp/cmp-element'
import { getRdsDbs } from 'views/resource/ctstack/services/database/rds.js'
export default {
props: {
dbIds: {
type: Array,
default: function () {
return []
}
},
rdsId: {
type: Number
},
flag: {
type: Number
}
},
data() {
return {
list: [],
total: 0,
listQuery: {
name: ''
},
params: {
page: 1,
rows: 5
},
leftSlection: [],
rightSlection: [],
selectUserList: [],
buttonName: '读写(DDL+DML)'
}
},
computed: {
userIds() {
const ids = []
for (const a of this.selectUserList) {
ids.push(a.name)
}
return ids
},
privileges() {
const arr = []
for (const a of this.selectUserList) {
const obj = {
name: a.name,
accountPrivilege: a.accountPrivilege
}
arr.push(obj)
}
return arr
}
},
created() {
this.getSelectUser()
},
watch: {
flag: {
handler(newVal, oldVal) {
this.getSelectUser()
}
}
},
methods: {
setAuth() {
if (this.buttonName == '读写(DDL+DML)') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'ReadWrite')
})
this.buttonName = '只读'
} else if (this.buttonName == '只读') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'ReadOnly')
})
this.buttonName = '仅DDL'
} else if (this.buttonName == '仅DDL') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'DDLOnly')
})
this.buttonName = '仅DML'
} else if (this.buttonName == '仅DML') {
this.selectUserList.forEach(item => {
this.$set(item, 'accountPrivilege', 'DMLOnly')
})
this.buttonName = '读写(DDL+DML)'
}
},
getSelectUser() {
getRdsDbs(this.rdsId, {
page: 1,
rows: 999999,
params: handleSearchParam({
rdsId: this.rdsId
})
}).then(data => {
if (data.success) {
const list = data.data.rows
list.forEach(item => {
if (this.dbIds.indexOf(item.name) > -1) {
this.selectUserList.push(item)
}
})
}
})
this.handleSearch()
},
getList() {
getRdsDbs(this.rdsId, this.params).then(data => {
if (data.success) {
this.list = data.data.rows
this.total = data.data.total
//
this.$nextTick(() => {
this.list.forEach(item => {
if (this.userIds.indexOf(item.name) > -1) this.$refs.userTable.toggleRowSelection(item, true)
})
})
}
})
},
//
handleSearch() {
this.params.page = 1
this.params.params = handleSearchParam({
rdsId: this.rdsId,
'name:LK': this.listQuery.name
})
this.getList()
},
selectionChange(selection) {
this.leftSlection = selection
},
selectionChangeCheck(selection) {
this.rightSlection = selection
},
selectAble(row) {
return !this.userIds.includes(row.name)
},
addUser() {
const users = this.leftSlection.filter(item => {
this.$set(item, 'accountPrivilege', 'ReadWrite')
return !this.userIds.includes(item.name)
})
this.selectUserList.unshift(...users)
},
removeUser() {
const ids = []
this.rightSlection.forEach(item => {
ids.push(item.name)
})
for (let i = 0; i < this.selectUserList.length; i++) {
const item = this.selectUserList[i]
if (ids.includes(item.name)) {
this.selectUserList.splice(i, 1)
i--
}
}
}
}
}
</script>
<style></style>

View File

@ -4,220 +4,47 @@
<template v-slot:action>
<el-button type="primary" @click="handleCreate()"></el-button>
</template>
<template #status="status">
<cb-status-icon :type="statusFilter[status]">
{{ filter[status] }}
<template #name="val, record">
<span class="detail-href" @click="getDetail(record)">{{ (record.instanceId || '--') + ' / ' + val }}</span>
</template>
<template #prodType="val, record">
{{ prodTypeFilter[val] }}
</template>
<template #status="val">
<cb-status-icon :type="statusFilter(val, 'color')">
{{ statusFilter(val, 'status') }}
</cb-status-icon>
</template>
<template #type="type">
{{ filter[type] }}
</template>
<template #payType="payType">
{{ filter[payType] }}
</template>
<template #name="val, record">
<span class="detail-href" @click="getDetail(record.id)">{{ (record.instanceId || '--') + ' / ' + val }}</span>
<template #diskType="val">
{{ val | diskTypeFilter }}
</template>
<template #operate="val, record">
<el-button type="text" @click="patch(record)" :disabled="record.status !== 'Running'"> 重启 </el-button>
<div class="action-divider"></div>
<!-- <el-button type="text" @click="handleReset(record)" :disabled="record.status !== 'Running'"> 重启 </el-button>
<div class="action-divider"></div> -->
<el-button type="text" @click="removeRds(record)" :disabled="record.status !== 'Running'"> 释放实例 </el-button>
</template>
</cb-advance-table>
<add :add-data="addData" v-if="addData.dialog" @back="getData"></add>
<cb-detail v-if="detailFlag" :title="detailData.instanceId + ' / ' + detailData.name" @goBack="goBack">
<template v-slot:item_container>
<cb-detail-item label="名称">{{ detailData.name }}</cb-detail-item>
<cb-detail-item label="状态">{{ filter[detailData.status] }}</cb-detail-item>
<cb-detail-item label="版本">{{ detailData.dataStoreVersion }}</cb-detail-item>
<cb-detail-item label="实例类型">{{ filter[detailData.type] }}</cb-detail-item>
<cb-detail-item label="数据库类型">{{ detailData.dataStoreType }}</cb-detail-item>
<cb-detail-item label="付费类型">{{ filter[detailData.payType] }}</cb-detail-item>
<cb-detail-item label="规格">{{ detailData.flavorId }}</cb-detail-item>
<cb-detail-item label="可用区">{{ detailData.region }}</cb-detail-item>
<cb-detail-item label="实例ID">{{ detailData.instanceId }}</cb-detail-item>
<cb-detail-item label="数据库引擎">{{ detailData.engine }}</cb-detail-item>
<cb-detail-item label="状态">
<cb-status-icon :type="statusFilter(detailData.status, 'color')">
{{ statusFilter(detailData.status, 'status') }}
</cb-status-icon>
</cb-detail-item>
<cb-detail-item label="虚拟IP地址">{{ detailData.vip }}</cb-detail-item>
<cb-detail-item label="虚拟IPv6地址">{{ detailData.vip6 }}</cb-detail-item>
<cb-detail-item label="写数据端口">{{ detailData.writePort }}</cb-detail-item>
<cb-detail-item label="读数据端口">{{ detailData.readPort }}</cb-detail-item>
<cb-detail-item label="存储空间GB">{{ detailData.diskSize }}</cb-detail-item>
<cb-detail-item label="存储类型">{{ detailData.diskType | diskTypeFilter }}</cb-detail-item>
<cb-detail-item label="创建时间">{{ detailData.createTime }}</cb-detail-item>
</template>
<el-tabs v-model="activeName" @tab-click="handleClick">
<el-tab-pane label="账号列表" name="account">
<el-button class="m-b" type="primary" @click="createAccount()"></el-button>
<cb-table :data="usersList" :params="paramsUsers" :total="totalUsers" :get-list="getUsersList">
<el-table-column prop="username" label="账号" show-overflow-tooltip></el-table-column>
<el-table-column prop="permission" label="类型" show-overflow-tooltip>
<template slot-scope="scope">
{{ scope.row.permission | typeFilter }}
</template>
</el-table-column>
<el-table-column prop="status" label="状态" show-overflow-tooltip>
<template slot-scope="scope">
<cb-status-icon :type="scope.row.status | statusFilter('color')">{{ scope.row.status | statusFilter('status') }} </cb-status-icon>
</template>
</el-table-column>
<el-table-column prop="db" label="所属数据库" show-overflow-tooltip>
<template slot-scope="scope">
<div v-for="item in JSON.parse(scope.row.privileges)" :key="item.name">{{ item.name }} {{ item.accountPrivilege | authFilter }}</div>
</template>
</el-table-column>
<el-table-column prop="remark" label="账号描述" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" show-overflow-tooltip width="250px">
<template slot-scope="scope">
<el-button type="text" @click="resetPasd(scope.row)"></el-button>
<div class="action-divider"></div>
<!-- <el-button type="text" v-if="scope.row.permission == 'Super'" @click="resetAuth(scope.row)"></el-button> -->
<el-button type="text" v-if="scope.row.permission == 'Normal'" @click="modifyAuth(scope.row)"></el-button>
<div class="action-divider" v-if="scope.row.permission == 'Normal'"></div>
<!-- <div class="action-divider" v-if="scope.row.permission == 'Super'"></div> -->
<el-button type="text" @click="deleteAccount(scope.row)"></el-button>
</template>
</el-table-column>
<!-- <div slot="pagination"></div> -->
</cb-table>
<el-dialog title="重置账号" append-to-body v-if="resetFlag" :visible.sync="resetFlag" :close-on-click-modal="false">
<cb-form ref="resetData" :model="resetData" label-width="120px">
<cb-form-item label="数据库账号:" prop="username">
{{ resetData.username }}
</cb-form-item>
<cb-form-item label="密码:" prop="password" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="resetData.password"></el-input>
</cb-form-item>
</cb-form>
<span slot="footer" class="dialog-footer">
<el-button type="ghost" @click.native="resetFlag = false"> </el-button>
<el-button type="primary" @click.native="submitReset"> </el-button>
</span>
</el-dialog>
<el-dialog title="重置账号密码" append-to-body v-if="resetPasdFlag" :visible.sync="resetPasdFlag" :close-on-click-modal="false">
<cb-form ref="resetData" :model="resetData" label-width="120px">
<cb-form-item label="密码:" prop="password" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="resetData.password" show-password></el-input>
</cb-form-item>
<cb-form-item label="确认密码:" prop="password2" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="resetData.password2" show-password></el-input>
</cb-form-item>
</cb-form>
<span slot="footer" class="dialog-footer">
<el-button type="ghost" @click.native="resetPasdFlag = false"> </el-button>
<el-button type="primary" @click.native="submitResetPasd"> </el-button>
</span>
</el-dialog>
<el-drawer append-to-body title="创建用户账号" :visible.sync="drawer" direction="rtl" size="40%">
<el-card>
<cb-form ref="accountData" :model="accountData" label-width="120px">
<cb-form-item label="数据库账号:" prop="username" maxlength="16" :rules="[required, rdsAccountName, { validator: validateKeyword, trigger: 'blur' }]">
<el-tooltip class="item" effect="dark" content="由小写字母、数字、下划线_组成以字母开头以字母或数字结尾最多16个字符" placement="top">
<el-input v-model="accountData.username" auto-complete="off"></el-input>
</el-tooltip>
</cb-form-item>
<cb-form-item class="m-t-lg" label="账号类型:" prop="permission" :rules="[required]">
<el-radio-group v-model="accountData.permission">
<el-radio label="Super" :disabled="Super">高权限账号</el-radio>
<el-radio label="Normal">普通账号</el-radio>
</el-radio-group>
</cb-form-item>
<cb-form-item class="m-t-lg" label="密码:" prop="password" :rules="[required, rdsDBPassword]">
<el-input type="password" v-model="accountData.password" auto-complete="off"></el-input>
</cb-form-item>
<cb-form-item class="m-t-lg" label="确认密码:" prop="password2" :rules="[required]">
<el-input type="password" v-model="accountData.password2" auto-complete="off"></el-input>
</cb-form-item>
<cb-form-item class="m-t-lg" label="备注:" prop="remark" maxlength="256">
<el-input type="textarea" v-model="accountData.remark"></el-input>
<div class="text_mine">请输入备注说明,最多256个字符</div>
</cb-form-item>
<el-button type="primary" @click="submitAccount()"></el-button>
<el-button type="ghost" @click="drawer = false">取消</el-button>
</cb-form>
</el-card>
</el-drawer>
<!-- 修改权限 -->
<ModifyRole :dialog="editDialog" v-if="editDialog.visible" @getData="getUsersList"></ModifyRole>
<!-- <el-drawer append-to-body :with-header="false" :visible.sync="drawerAuth" direction="rtl" size="1200px">
<el-card>
<cb-form :model="accountData" label-width="120px">
<cb-form-item label="数据库账号:" prop="username" maxlength="16">
{{accountData.username}}
</cb-form-item>
<modify-db class="m-b" ref="modifyDb" :rdsId="detailData.id" :dbIds="accountData.dbIds" :flag="flag"></modify-db>
<el-button type="primary" @click="submitAuth()"></el-button>
<el-button type="ghost" @click="drawerAuth = false">取消</el-button>
</cb-form>
</el-card>
</el-drawer> -->
</el-tab-pane>
<el-tab-pane label="数据库列表" name="database">
<el-button class="m-b" type="primary" @click="createDB"></el-button>
<cb-table :data="databaseList" :params="paramsDb" :total="totalDb" :get-list="getDbList">
<el-table-column prop="name" label="名称" show-overflow-tooltip></el-table-column>
<el-table-column prop="status" label="状态" show-overflow-tooltip>
<!-- <template slot-scope="scope">
<cb-status-icon :type="scope.row.status | vmStatusColor">{{ scope.row.status | database }} </cb-status-icon>
</template> -->
</el-table-column>
<el-table-column prop="characterSet" label="字符集" show-overflow-tooltip></el-table-column>
<el-table-column prop="accounts" label="绑定账号" show-overflow-tooltip>
<template slot-scope="scope">
<div v-for="(item, index) in JSON.parse(scope.row.accounts)" :key="index">
{{ item.account }}
</div>
</template>
</el-table-column>
<el-table-column prop="remark" label="备注说明" show-overflow-tooltip></el-table-column>
<el-table-column label="操作" show-overflow-tooltip>
<template slot-scope="scope">
<el-button type="text" @click="deleteDB(scope.row)"></el-button>
</template>
</el-table-column>
</cb-table>
<el-drawer append-to-body title="创建数据库" :visible.sync="drawerDB" direction="rtl" size="40%">
<el-card>
<cb-form ref="databaseData" :model="databaseData" label-width="140px">
<cb-form-item
label="数据库(DB)名称:"
prop="name"
:rules="[
{
pattern: /^[a-z]([a-z0-9_-]{1,62})?([a-z0-9])$/,
message: '由小写字母、数字、下划线、中划线组成以字母开头字母或数字结尾最多64个字符',
trigger: null
},
{
validator: validateKeyword,
trigger: 'blur'
}
]"
validate="required"
>
<el-input v-model="databaseData.name" placeholder="请输入数据库名称" clearable></el-input>
</cb-form-item>
<cb-form-item class="m-t-lg" label="支持字符集:" prop="characterSet">
<el-select v-model="databaseData.characterSet" placeholder="请选择">
<el-option v-for="item in codeData" :key="item" :label="item" :value="item"> </el-option>
</el-select>
</cb-form-item>
<!-- <cb-form-item class="m-t-lg" label="授权账号:" prop="accountId">
<el-select v-model="databaseData.accountId" placeholder="请选择">
<el-option v-for="item in accounts" :key="item.id" :label="item.username" :value="item.id">
</el-option>
</el-select>
</cb-form-item> -->
<cb-form-item class="m-t-lg" label="账号类型:" prop="accountPrivilege" :rules="[required]" v-if="databaseData.accountId" key="accountPrivilege">
<el-radio-group v-model="databaseData.accountPrivilege">
<el-radio label="ReadWrite">读写 </el-radio>
<el-radio label="ReadOnly">只读 </el-radio>
<el-radio label="DDLOnly">仅DDL </el-radio>
<el-radio label="DMLOnly">仅DML </el-radio>
</el-radio-group>
</cb-form-item>
<cb-form-item class="m-t-lg" label="备注说明:" prop="remark" maxlength="256">
<el-input type="textarea" v-model="databaseData.remark"></el-input>
<div class="text_mine">请输入备注说明,最多256个字符</div>
</cb-form-item>
<el-button type="primary" @click="submitDB()"></el-button>
<el-button type="ghost" @click="drawerDB = false">取消</el-button>
</cb-form>
</el-card>
</el-drawer>
</el-tab-pane>
<el-tab-pane label="连接地址管理" name="connection">
<cb-table :data="connectionList" :params="paramsCo" :total="totalDo" :get-list="getCoList">
<cb-table :data="connectionList" :params="paramsConnection" :total="totalConnection" :get-list="getConnectionList">
<el-table-column label="网络类型" show-overflow-tooltip>
<template slot-scope="scope">
{{ instanceNetworkTypeMap[scope.row.instanceNetworkType] + '(' + ipTypeMap[scope.row.ipType] + ')' }}
@ -227,46 +54,17 @@
<el-table-column prop="port" label="端口" show-overflow-tooltip></el-table-column>
</cb-table>
</el-tab-pane>
<!-- <el-tab-pane label="参数设置" name="params">
<el-tabs value="modify">
<el-tab-pane label="可修改参数" name="modify">
<cb-table :data="detailData.nodes">
<el-table-column prop="name" label="参数名" show-overflow-tooltip></el-table-column>
<el-table-column prop="type" label="参数默认值" show-overflow-tooltip></el-table-column>
<el-table-column prop="db" label="运行参数值" show-overflow-tooltip>
<template slot-scope="scope">
{{scope.row.params}} <el-button type="text" class="el-icon-edit"></el-button>
</template>
</el-table-column>
<el-table-column prop="remark" label="是否重启" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="参数值范围" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="参数描述" show-overflow-tooltip></el-table-column>
<div slot="pagination"></div>
</cb-table>
</el-tab-pane>
<el-tab-pane label="参数修改历史" name="history">
<cb-table :data="detailData.nodes">
<el-table-column prop="name" label="参数名" show-overflow-tooltip></el-table-column>
<el-table-column prop="type" label="变更前参数值" show-overflow-tooltip></el-table-column>
<el-table-column prop="db" label="变更后参数值" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="是否生效" show-overflow-tooltip></el-table-column>
<el-table-column prop="remark" label="变更时间" show-overflow-tooltip></el-table-column>
</cb-table>
</el-tab-pane>
</el-tabs>
</el-tab-pane> -->
</el-tabs>
</cb-detail>
<Add :add-data="addData" v-if="addData.dialog" @back="getData"></Add>
</div>
</template>
<script>
import validate from '@/validate'
import { getRegion } from 'services/platform/index'
import { getRds, detailRds, getRdsCos, patchRds, removeRds, getRdsUsers, createRdsUsers, removeRdsUsers, resetRdsUserPasd, resetRdsUser, authRdsUser, getRdsDbs, createRdsDbs, removeRdsDbs } from 'views/resource/ctstack/services/database/rds.js'
import add from '../components/add.vue'
import ModifyRole from './ModifyRole.vue'
import { keywords } from './validate'
import { getRds, getRdsCos, patchRds, removeRds } from 'views/resource/ctstack/services/database/rds.js'
import Add from '../components/Add.vue'
import { handleSearchParam } from '@cmp/cmp-element'
const columns = [
{
@ -275,28 +73,47 @@ const columns = [
scopedSlots: { customRender: 'name' }
},
{
label: '状态',
prop: 'status',
scopedSlots: { customRender: 'status' }
label: '实例类型',
prop: 'prodType',
scopedSlots: { customRender: 'prodType' }
},
{
label: '版本',
prop: 'dataStoreVersion'
label: '数据库引擎',
prop: 'engine'
},
// {
// label: '', // mysql
// prop: 'status',
// scopedSlots: { customRender: 'status' }
// },
{
label: '虚拟IP地址',
prop: 'vip'
},
// {
// label: 'IPv6', // mysql
// prop: 'vip6'
// },
{
label: '写数据端口',
prop: 'writePort'
},
{
label: '规格',
prop: 'cpu',
customRender(cpu, { memory }) {
return cpu && memory ? `${cpu}C/${memory}GB` : '--'
}
},
{
label: '存储空间GB',
prop: 'volSize'
label: '读数据端口',
prop: 'readPort'
},
// {
// label: 'GB', // mysql
// prop: 'diskSize'
// },
// {
// label: '', // mysql
// prop: 'diskType',
// scopedSlots: { customRender: 'diskType' }
// },
{
label: '创建时间',
prop: 'createDate'
prop: 'createTime'
},
{
label: '操作',
@ -306,33 +123,24 @@ const columns = [
}
]
const validateKeyword = (rule, value, callback) => {
const valid = keywords.find(item => item.toLocaleLowerCase() === value)
if (!valid) {
callback()
} else {
callback(new Error(`${valid.toLocaleLowerCase()}为关键字,不能输入`))
}
}
const instanceNetworkTypeMap = {
VPC: '专有网络',
Classic: '经典网络'
}
const ipTypeMap = {
Inner: '内网',
Public: '外网',
Private: '内网'
}
export default {
props: {
platformObject: {
type: Object
}
},
components: { add, ModifyRole },
components: { Add },
filters: {
diskTypeFilter(value) {
// 1SATA2SAS 3-SSD 4-LVM
const obj = {
1: 'SATA',
2: 'SAS',
3: 'SSD',
4: 'LVM'
}
return obj[value]
},
typeFilter(value) {
const obj = {
Normal: '普通账号',
@ -341,36 +149,68 @@ export default {
return obj[value]
},
statusFilter(value, type) {
// 0. 1. 2. 3. 4. 5. 6&7. 8. 9. 10.
const obj = {
Unavailable: {
status: '未激活',
color: 'info'
},
Available: {
status: ' 已激活',
0: {
status: '运行中',
color: 'success'
},
1: {
status: '重启中',
color: 'warning'
},
2: {
status: '备份中',
color: 'warning'
},
3: {
status: '恢复中',
color: 'warning'
},
4: {
status: '修改参数中',
color: 'warning'
},
5: {
status: '应用参数组中',
color: 'warning'
},
6: {
status: '扩容中',
color: 'warning'
},
7: {
status: '扩容中',
color: 'warning'
},
8: {
status: '修改端口中',
color: 'warning'
},
9: {
status: '迁移中',
color: 'warning'
},
10: {
status: '重置密码中',
color: 'warning'
}
}
return obj[value] && obj[value][type]
},
authFilter(value) {
const obj = {
ReadWrite: '读写(DDL+DML)',
ReadOnly: '只读',
DDLOnly: '仅DDL',
DMLOnly: 'DMLOnly'
}
return obj[value]
}
},
data() {
return {
validateKeyword,
ipTypeMap,
instanceNetworkTypeMap,
ipTypeMap: {
Inner: '内网',
Public: '外网',
Private: '内网'
},
instanceNetworkTypeMap: {
VPC: '专有网络',
Classic: '经典网络'
},
required: validate.required,
rdsAccountName: { pattern: /^[a-z]([a-z0-9_-]{0,14}[a-z0-9])?$/, message: '由小写字母、数字、下划线_组成以字母开头以字母或数字结尾最多16个字符', trigger: null },
rdsDBPassword: { pattern: '^(?![a-zA-Z]+$)(?![A-Z0-9]+$)(?![A-Z\\W_]+$)(?![a-z0-9]+$)(?![a-z\\W_]+$)(?![0-9\\W_]+$)[a-zA-Z0-9\\W_]{8,32}$', message: '必须包含三种及以上类型大小写字母、数字、特殊符号。长度为8-32位特殊字符包括! @ # $ % ^ & * () _ + - =', trigger: null },
searchConfigs: [
{ type: 'Input', label: '名称', value: 'name' },
{ type: 'Select', label: '所属地域', data: [], value: 'regionId', props: { value: 'regionId' } },
@ -403,98 +243,23 @@ export default {
RebootFailed: '重启失败',
DBInstanceClassChanging: '升降级中'
},
statusFilter: {
Creating: 'warning',
Running: 'success',
Deleting: 'warning',
Rebooting: 'warning',
RebootFailed: 'danger',
DBInstanceClassChanging: 'warning'
prodTypeFilter: {
0: '单机版',
1: '一主一备',
2: '一主两备',
3: '一主三备'
},
addData: {
dialog: false,
data: {}
},
activeName: 'account',
//
paramsUsers: {
page: 1,
rows: 10
},
totalUsers: 0,
usersList: [],
drawer: false,
accountData: {},
drawerAuth: false,
//
resetFlag: false,
resetPasdFlag: false,
resetData: {},
//
drawerDB: false,
databaseData: {},
codeData: [
'utf8mb4',
'utf8',
'gbk',
'gb18030',
'latin1',
'euckr',
'armscii8',
'ascii',
'big5',
'binary',
'cp1250',
'cp1251',
'cp1256',
'cp1257',
'cp850',
'cp852',
'cp866',
'cp932',
'dec8',
'eucjpms',
'gb2312',
'geostd8',
'greek',
'hebrew',
'hp8',
'keybcs2',
'koi8r',
'koi8u',
'latin2',
'latin5',
'latin7',
'macce',
'macroman',
'sjis',
'swe7',
'tis620',
'ucs2',
'ujis',
'utf16',
'utf16le',
'utf32'
],
accounts: [],
databaseList: [],
paramsDb: {
page: 1,
rows: 10
},
totalDb: 0,
flag: 0,
Super: false,
activeName: 'connection',
connectionList: [],
paramsCo: {
paramsConnection: {
page: 1,
rows: 10
},
totalDo: 0,
editDialog: {
visible: false,
record: {}
}
totalConnection: 0
}
},
watch: {
@ -517,18 +282,18 @@ export default {
this.getRegion()
},
methods: {
async getCoList(id) {
this.paramsCo.params = handleSearchParam({
async getConnectionList(id) {
this.paramsConnection.params = handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
const res = await getRdsCos(id, this.paramsCo)
const res = await getRdsCos(id, this.paramsConnection)
if (res.success) {
this.totalDo = res.data.total
this.totalConnection = res.data.total
this.connectionList = res.data.rows
}
},
patch(data) {
handleReset(data) {
this.$confirm('确定重启该实例吗?', '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
@ -579,279 +344,21 @@ export default {
type: 'POSTGRESQL'
}
},
getDetail(id) {
this.Super = false
detailRds(id).then(data => {
if (data.success) {
this.detailData = data.data
this.detailFlag = true
this.getUsersList()
}
})
getDetail(record) {
this.detailData = { ...record }
this.detailFlag = true
},
handleClick() {
switch (this.activeName) {
case 'account':
this.getUsersList()
break
case 'database':
this.getDbList()
break
case 'connection':
this.getCoList(this.detailData.id)
this.getConnectionList(this.detailData.id)
break
}
},
getUsersList() {
this.paramsUsers.params = handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
getRdsUsers(this.detailData.id, this.paramsUsers).then(data => {
if (data.success) {
this.usersList = data.data.rows
this.totalUsers = data.data.total
}
})
getRdsUsers(this.detailData.id, {
simple: true,
params: handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
}).then(data => {
if (data.success) {
const list = data.data.rows
list.forEach(item => {
if (item.permission == 'Super') {
this.Super = true
}
})
}
})
},
getDbList() {
this.paramsDb.params = handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id
})
getRdsDbs(this.detailData.id, this.paramsDb).then(data => {
if (data.success) {
this.databaseList = data.data.rows
this.totalDb = data.data.total
}
})
},
goBack() {
this.detailFlag = false
},
//
createAccount() {
this.drawer = true
this.accountData = {
rdsId: this.detailData.id,
vendorId: this.detailData.vendorId
}
},
submitAccount() {
this.$refs.accountData.validate(valid => {
if (valid) {
if (this.accountData.password !== this.accountData.password2) {
return this.$message.error('两次密码输入不一致')
}
const { vendorId, username, password, rdsId, permission, remark } = this.accountData
createRdsUsers(this.accountData.rdsId, {
rdsId: rdsId,
vendorId: vendorId,
username: username,
permission: permission,
password: crypto.encrypt(password),
remark: remark
}).then(data => {
if (data.success) {
this.$message.success(data.message)
this.drawer = false
this.getUsersList()
}
})
}
})
},
//
deleteAccount(data) {
this.$confirm(`您确定要删除【${data.username}】吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeRdsUsers({
rdsId: this.detailData.id,
userId: data.id
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.getUsersList()
}
})
})
},
//
modifyAuth(data) {
// this.getDbList()
this.flag++
const privilege = data.privilege ? JSON.parse(data.privilege) : []
const arr = []
privilege.forEach(element => {
arr.push(element.name)
})
// this.accountData = {
// rdsId: this.detailData.id,
// userId: data.id,
// username: data.username,
// dbIds: arr
// }
this.editDialog = {
record: { ...data },
visible: true
}
},
submitAuth() {
const { rdsId, username, userId } = this.accountData
authRdsUser({
rdsId: rdsId,
userId: userId,
id: userId,
username: username,
privileges: this.$refs.modifyDb.privileges
}).then(data => {
if (data.success) {
this.$message.success(data.message)
this.getUsersList()
this.drawerAuth = false
}
})
},
//
resetAuth(data) {
this.resetData = {
rdsId: this.detailData.id,
userId: data.id,
password: '',
username: data.username
}
this.resetFlag = true
},
submitReset() {
this.$refs.resetData.validate(valid => {
if (valid) {
const { rdsId, userId, password } = this.resetData
resetRdsUser({
rdsId: rdsId,
userId: userId,
password: crypto.encrypt(password)
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.resetFlag = false
this.getUsersList()
}
})
}
})
},
resetPasd(data) {
//
this.resetData = {
rdsId: this.detailData.id,
userId: data.id,
username: data.username
}
this.resetPasdFlag = true
},
submitResetPasd() {
this.$refs.resetData.validate(valid => {
if (valid) {
if (this.resetData.password !== this.resetData.password2) {
return this.$message.error('两次密码输入不一致')
}
const { rdsId, userId, password } = this.resetData
resetRdsUserPasd({
rdsId: rdsId,
userId: userId,
password: crypto.encrypt(password)
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.resetPasdFlag = false
this.getUsersList()
}
})
}
})
},
createDB() {
this.drawerDB = true
getRdsUsers(this.detailData.id, {
page: 1,
rows: 99999,
params: handleSearchParam({
vendorId: this.detailData.vendorId,
rdsId: this.detailData.id,
permission: 'Normal'
})
}).then(data => {
if (data.success) {
this.accounts = data.data.rows
}
})
this.databaseData = {
name: '',
accountPrivilege: 'ReadWrite',
characterSet: 'utf8'
}
},
submitDB() {
this.$refs.databaseData.validate(valid => {
if (valid) {
createRdsDbs(this.detailData.id, this.databaseData).then(data => {
if (data.success) {
this.$message.success(data.message)
this.drawerDB = false
this.getDbList()
}
})
}
})
},
deleteDB(data) {
this.$confirm(`您确定要删除【${data.name}】吗?`, '提示', {
confirmButtonText: '确定',
cancelButtonText: '取消',
type: 'warning'
}).then(() => {
removeRdsDbs({
rdsId: this.detailData.id,
dbId: data.id
}).then(data => {
if (data.success) {
this.$message({
type: 'success',
message: data.message
})
this.getDbList()
}
})
})
}, //
//
getRegion() {
getRegion({ vendorId: this.platformObject.vendorId }).then(data => {
if (data.success) {

View File

@ -1,439 +0,0 @@
export const keywords = [
// RDS MySQL
'ACTION',
'ADD',
'ADMIN',
'ALL',
'ALTER',
'ANALYZE',
'AND',
'AS',
'ASC',
'ASENSITIVE',
'BEFORE',
'BETWEEN',
'BIGINT',
'BINARY',
'BLOB',
'BOTH',
'BY',
'CALL',
'CASCADE',
'CASE',
'CHANGE',
'CHAR',
'CHARACTER',
'CHECK',
'COLLATE',
'COLUMN',
'CONDITION',
'CONNECTION',
'CONSTRAINT',
'CONTINUE',
'CONVERT',
'CREATE',
'CROSS',
'CURRENT_DATE',
'CURRENT_TIME',
'CURRENT_TIMESTAMP',
'CURRENT_USER',
'CURSOR',
'DATABASE',
'DATABASES',
'DAY_HOUR',
'DAY_MICROSECOND',
'DAY_MINUTE',
'DAY_SECOND',
'DEC',
'DECIMAL',
'DECLARE',
'DEFAULT',
'DELAYED',
'DELETE',
'DESC',
'DESCRIBE',
'DETERMINISTIC',
'DISTINCT',
'DISTINCTROW',
'DIV',
'DOUBLE',
'DROP',
'DUAL',
'EACH',
'EAGLEYE',
'ELSE',
'ELSEIF',
'ENCLOSED',
'ESCAPED',
'EXISTS',
'EXIT',
'EXPLAIN',
'FALSE',
'FETCH',
'FLOAT',
'FLOAT4',
'FLOAT8',
'FOR',
'FORCE',
'FOREIGN',
'FROM',
'FULLTEXT',
'GOTO',
'GRANT',
'GROUP',
'GUEST',
'HAVING',
'HIGH_PRIORITY',
'HOUR_MICROSECOND',
'HOUR_MINUTE',
'HOUR_SECOND',
'IF',
'IGNORE',
'IN',
'INDEX',
'INFILE',
'INFORMATION_SCHEMA',
'INNER',
'INOUT',
'INSENSITIVE',
'INSERT',
'INT',
'INT1',
'INT2',
'INT3',
'INT4',
'INT8',
'INTEGER',
'INTERVAL',
'INTO',
'IS',
'ITERATE',
'JOIN',
'KEY',
'KEYS',
'KILL',
'LABEL',
'LEADING',
'LEAVE',
'LEFT',
'LIKE',
'LIMIT',
'LINEAR',
'LINES',
'LOAD',
'LOCALTIME',
'LOCALTIMESTAMP',
'LOCK',
'LONG',
'LONGBLOB',
'LONGTEXT',
'LOOP',
'LOW_PRIORITY',
'MATCH',
'MEDIUMBLOB',
'MEDIUMINT',
'MEDIUMTEXT',
'MIDDLEINT',
'MINUTE_MICROSECOND',
'MINUTE_SECOND',
'MOD',
'MODIFIES',
'MYSQL',
'NATURAL',
'NO_WRITE_TO_BINLOG',
'NOT',
'NULL',
'NUMERIC',
'ON',
'OPTIMIZE',
'OPTION',
'OPTIONALLY',
'OR',
'ORDER',
'OUT',
'OUTER',
'OUTFILE',
'PERFORMANCE_SCHEMA',
'PRECISION',
'PRIMARY',
'PROCEDURE',
'PURGE',
'RAID0',
'RANGE',
'READ',
'READS',
'REAL',
'REFERENCES',
'REGEXP',
'RELEASE',
'RENAME',
'REPEAT',
'REPLACE',
'REPLICATOR',
'REQUIRE',
'RESTRICT',
'RETURN',
'REVOKE',
'RIGHT',
'RLIKE',
'ROOT',
'SCHEMA',
'SCHEMAS',
'SECOND_MICROSECOND',
'SELECT',
'SENSITIVE',
'SEPARATOR',
'SET',
'SHOW',
'SMALLINT',
'SPATIAL',
'SPECIFIC',
'SQL',
'SQL_BIG_RESULT',
'SQL_CALC_FOUND_ROWS',
'SQL_SMALL_RESULT',
'SQLEXCEPTION',
'SQLSTATE',
'SQLWARNING',
'SSL',
'STARTING',
'STRAIGHT_JOIN',
'TABLE',
'TERMINATED',
'TEST',
'THEN',
'TINYBLOB',
'TINYINT',
'TINYTEXT',
'TO',
'TRAILING',
'TRIGGER',
'TRUE',
'UNDO',
'UNION',
'UNIQUE',
'UNLOCK',
'UNSIGNED',
'UPDATE',
'USAGE',
'USE',
'USING',
'UTC_DATE',
'UTC_TIME',
'UTC_TIMESTAMP',
'VALUES',
'VARBINARY',
'VARCHAR',
'VARCHARACTER',
'VARYING',
'WHEN',
'WHERE',
'WHILE',
'WITH',
'WRITE',
'X509',
'XOR',
'XTRABAK',
'YEAR_MONTH',
'ZEROFILL',
// RDS SQL Server
'ADD',
'ADMIN',
'ADMINISTRATOR',
'ALL',
'ALTER',
'AND',
'ANY',
'AS',
'ASC',
'AURORA',
'AUTHORIZATION',
'BACKUP',
'BEGIN',
'BETWEEN',
'BREAK',
'BROWSE',
'BULK',
'BULKADMIN',
'BY',
'CASCADE',
'CASE',
'CHECK',
'CHECKPOINT',
'CLOSE',
'CLUSTERED',
'COALESCE',
'COLLATE',
'COLUMN',
'COMMIT',
'COMPUTE',
'CONSTRAINT',
'CONTAINS',
'CONTAINSTABLE',
'CONTINUE',
'CONVERT',
'CREATE',
'CROSS',
'CURRENT',
'CURRENT_DATE',
'CURRENT_TIME',
'CURRENT_TIMESTAMP',
'CURRENT_USER',
'CURSOR',
'DATABASE',
'DBCC',
'DBCREATOR',
'DEALLOCATE',
'DECLARE',
'DEFAULT',
'DELETE',
'DENY',
'DESC',
'DISK',
'DISKADMIN',
'DISTINCT',
'DISTRIBUTED',
'DISTRIBUTION',
'DOUBLE',
'DROP',
'DUMMY',
'DUMP',
'EAGLEYE',
'ELSE',
'END',
'ERRLVL',
'ESCAPE',
'EXCEPT',
'EXEC',
'EXECUTE',
'EXISTS',
'EXIT',
'FETCH',
'FILE',
'FILLFACTOR',
'FOR',
'FOREIGN',
'FREETEXT',
'FREETEXTTABLE',
'FROM',
'FULL',
'FUNCTION',
'GALAXY',
'GOTO',
'GRANT',
'GROUP',
'GUEST',
'HAVING',
'HOLDLOCK',
'IDENTITY',
'IDENTITY_INSERT',
'IDENTITYCOL',
'IF',
'IN',
'INDEX',
'INNER',
'INSERT',
'INTERSECT',
'INTO',
'IS',
'JOIN',
'KEY',
'KILL',
'LEFT',
'LIKE',
'LINENO',
'LOAD',
'MASTER',
'MODEL',
'MSDB',
'MSSQLD',
'MSSQLSYSTEMRESOURCE',
'NATIONAL',
'NOCHECK',
'NONCLUSTERED',
'NOT',
'NULL',
'NULLIF',
'OF',
'OFF',
'OFFSETS',
'ON',
'OPEN',
'OPENDATASOURCE',
'OPENQUERY',
'OPENROWSET',
'OPENXML',
'OPTION',
'OR',
'ORDER',
'OUTER',
'OVER',
'PERCENT',
'PLAN',
'PRECISION',
'PRIMARY',
'PRINT',
'PROC',
'PROCEDURE',
'PROCESSADMIN',
'PUBLIC',
'PUBLIC',
'RAISERROR',
'READ',
'READTEXT',
'RECONFIGURE',
'REFERENCES',
'REPLICATION',
'RESTORE',
'RESTRICT',
'RETURN',
'REVOKE',
'RIGHT',
'ROLLBACK',
'ROOT',
'ROWCOUNT',
'ROWGUIDCOL',
'RULE',
'SA',
'SAVE',
'SCHEMA',
'SECURITYADMIN',
'SELECT',
'SERVERADMIN',
'SESSION_USER',
'SET',
'SETUPADMIN',
'SETUSER',
'SHUTDOWN',
'SOME',
'STATISTICS',
'SYSADMIN',
'SYSTEM_USER',
'TABLE',
'TEMPDB',
'TEXTSIZE',
'THEN',
'TO',
'TOP',
'TRAN',
'TRANSACTION',
'TRIGGER',
'TRUNCATE',
'TSEQUAL',
'UNION',
'UNIQUE',
'UPDATE',
'UPDATETEXT',
'USE',
'USER',
'VALUES',
'VARYING',
'VIEW',
'WAITFOR',
'WHEN',
'WHERE',
'WHILE',
'WITH',
'WRITETEXT'
]

View File

@ -1,24 +0,0 @@
import { request } from '@cmp/cmp-element'
import { wrapperParams } from 'utils'
// 查询实例IP白名单列表
export function getSecurityIps(url) {
return function (params) {
return request.get(`/cmp/plugins/ctstack/v1/${url}/security/ips`, {
params
})
}
}
// 修改MongoDB实例IP白名单
export function modifySecurityIps(url, params) {
// 设置modifyMode传Cover 删除modifyMode传Delete
return request.put(`/cmp/plugins/ctstack/v1/${url}/${params.id}/security/ips`, wrapperParams(params))
}
export function getUserApps(id) {
return request.get(`/sms/v1/users/${id}/apps`)
}
export function getIps(params) {
return request.get('/cmp/plugins/ctstack/v1/vms/ips', { params })
}

View File

@ -11,9 +11,6 @@ const mockRequest = data =>
data
})
)
export function getRegion(params) {
return request.get(`${url}/regions`, { params })
}
export function getRdsProject(params) {
if (isDev) return mockRequest(projectList)
@ -36,10 +33,6 @@ export function createRds(params) {
return request.post(`${url}`, params)
}
export function getRdsDbs(id, params) {
return request.get(`${url}/${id}/dbs`, { params })
}
export function getRdsCos(id, params) {
return request.get(`${url}/${id}/nets`, { params })
}
@ -59,35 +52,3 @@ export function patchRds(id) {
export function removeRds(id) {
return request.delete(`${url}/${id}`)
}
export function getRdsUsers(id, params) {
return request.get(`${url}/${id}/users`, { params })
}
export function createRdsUsers(id, params) {
return request.post(`${url}/${id}/users`, params)
}
export function removeRdsUsers(params) {
return request.delete(`${url}/${params.rdsId}/users/${params.userId}`)
}
export function resetRdsUserPasd(params) {
return request.put(`${url}/${params.rdsId}/users/${params.userId}/resetpassword`, wrapperParams(params))
}
export function resetRdsUser(params) {
return request.put(`${url}/${params.rdsId}/users/${params.userId}/resetaccount`, wrapperParams(params))
}
export function authRdsUser(params) {
return request.put(`${url}/${params.rdsId}/users/${params.userId}/dbs`, wrapperParams(params))
}
export function createRdsDbs(id, params) {
return request.post(`${url}/${id}/dbs`, params)
}
export function removeRdsDbs(params) {
return request.delete(`${url}/${params.rdsId}/dbs/${params.dbId}`)
}