A copy ssh public key

This commit is contained in:
张臻 2021-02-14 14:22:22 +08:00
parent 2a408ba0fe
commit b20ac01b12
11 changed files with 102 additions and 18 deletions

View File

@ -24,11 +24,9 @@ type Deploy Controller
// GetList - // GetList -
func (Deploy) GetList(gp *core.Goploy) *core.Response { func (Deploy) GetList(gp *core.Goploy) *core.Response {
projectName := gp.URLQuery.Get("projectName")
projects, err := model.Project{ projects, err := model.Project{
NamespaceID: gp.Namespace.ID, NamespaceID: gp.Namespace.ID,
UserID: gp.UserInfo.ID, UserID: gp.UserInfo.ID,
Name: projectName,
}.GetUserProjectList() }.GetUserProjectList()
if err != nil { if err != nil {

View File

@ -4,6 +4,7 @@ import (
"github.com/zhenorzz/goploy/core" "github.com/zhenorzz/goploy/core"
"github.com/zhenorzz/goploy/model" "github.com/zhenorzz/goploy/model"
"github.com/zhenorzz/goploy/utils" "github.com/zhenorzz/goploy/utils"
"io/ioutil"
) )
// Server struct // Server struct
@ -52,6 +53,19 @@ func (Server) GetOption(gp *core.Goploy) *core.Response {
} }
} }
// GetPublicKey -
func (Server) GetPublicKey(gp *core.Goploy) *core.Response {
path := gp.URLQuery.Get("path")
contentByte, err := ioutil.ReadFile(path + ".pub")
if err != nil {
return &core.Response{Code: core.Error, Message: err.Error()}
}
return &core.Response{
Data: string(contentByte),
}
}
// Check server // Check server
func (Server) Check(gp *core.Goploy) *core.Response { func (Server) Check(gp *core.Goploy) *core.Response {
type ReqData struct { type ReqData struct {

View File

@ -329,7 +329,7 @@ func (p Project) GetTotal() (int64, error) {
// GetUserProjectList - // GetUserProjectList -
func (p Project) GetUserProjectList() (Projects, error) { func (p Project) GetUserProjectList() (Projects, error) {
builder := sq. rows, err := sq.
Select(` Select(`
project.id, project.id,
project.name, project.name,
@ -351,13 +351,9 @@ func (p Project) GetUserProjectList() (Projects, error) {
"project_user.user_id": p.UserID, "project_user.user_id": p.UserID,
"project.state": Enable, "project.state": Enable,
}). }).
OrderBy("project.id DESC") OrderBy("project.id DESC").
RunWith(DB).
if len(p.Name) > 0 { Query()
builder = builder.Where(sq.Like{"project.name": "%" + p.Name + "%"})
}
rows, err := builder.RunWith(DB).Query()
if err != nil { if err != nil {
return nil, err return nil, err
} }

View File

@ -97,6 +97,7 @@ func Init() *router.Router {
rt.Add("/server/getList", http.MethodGet, controller.Server{}.GetList) rt.Add("/server/getList", http.MethodGet, controller.Server{}.GetList)
rt.Add("/server/getTotal", http.MethodGet, controller.Server{}.GetTotal) rt.Add("/server/getTotal", http.MethodGet, controller.Server{}.GetTotal)
rt.Add("/server/getOption", http.MethodGet, controller.Server{}.GetOption) rt.Add("/server/getOption", http.MethodGet, controller.Server{}.GetOption)
rt.Add("/server/getPublicKey", http.MethodGet, controller.Server{}.GetPublicKey)
rt.Add("/server/check", http.MethodPost, controller.Server{}.Check).Roles([]string{core.RoleAdmin, core.RoleManager}) rt.Add("/server/check", http.MethodPost, controller.Server{}.Check).Roles([]string{core.RoleAdmin, core.RoleManager})
rt.Add("/server/add", http.MethodPost, controller.Server{}.Add).Roles([]string{core.RoleAdmin, core.RoleManager}) rt.Add("/server/add", http.MethodPost, controller.Server{}.Add).Roles([]string{core.RoleAdmin, core.RoleManager})
rt.Add("/server/edit", http.MethodPost, controller.Server{}.Edit).Roles([]string{core.RoleAdmin, core.RoleManager}) rt.Add("/server/edit", http.MethodPost, controller.Server{}.Edit).Roles([]string{core.RoleAdmin, core.RoleManager})

View File

@ -22,6 +22,17 @@ export function getTotal() {
}) })
} }
/**
* @return {Promise}
*/
export function getPublicKey(path) {
return request({
url: '/server/getPublicKey',
method: 'get',
params: { path }
})
}
/** /**
* @return {Promise} * @return {Promise}
*/ */

View File

@ -137,6 +137,8 @@ export default {
sshKeyOwner: 'SSH-Key Owner', sshKeyOwner: 'SSH-Key Owner',
sshKeyPath: 'SSH-Key Path', sshKeyPath: 'SSH-Key Path',
sshKeyPassword: 'SSH-Key Pswd', sshKeyPassword: 'SSH-Key Pswd',
copyPub: 'Copy pub',
copyPubTips: 'Copy success. Paste it to ~/.ssh/authorized_keys',
testConnection: 'Test', testConnection: 'Test',
removeServerTips: 'This action will delete the server({serverName}), continue?' removeServerTips: 'This action will delete the server({serverName}), continue?'
}, },

View File

@ -137,6 +137,8 @@ export default {
sshKeyOwner: 'SSH-Key 所有者', sshKeyOwner: 'SSH-Key 所有者',
sshKeyPath: 'SSH-Key 路径', sshKeyPath: 'SSH-Key 路径',
sshKeyPassword: 'SSH-Key 密码', sshKeyPassword: 'SSH-Key 密码',
copyPub: '复制共钥',
copyPubTips: '复制成功,请粘贴到目标服务器~/.ssh/authorized_keys里面',
testConnection: '测试连接', testConnection: '测试连接',
removeServerTips: '此操作将删除服务器({serverName}), 是否继续?' removeServerTips: '此操作将删除服务器({serverName}), 是否继续?'
}, },

View File

@ -14,6 +14,26 @@ const mixin = {
}, },
isMember() { isMember() {
return this.$global.member === getNamespace()['role'] return this.$global.member === getNamespace()['role']
},
copy(content, message = '复制成功') {
const el = document.createElement('textarea')
el.value = content
el.setAttribute('readonly', '')
el.style.position = 'absolute'
el.style.left = '-9999px'
document.body.appendChild(el)
const selected =
document.getSelection().rangeCount > 0
? document.getSelection().getRangeAt(0)
: false
el.select()
document.execCommand('copy')
document.body.removeChild(el)
if (selected) {
document.getSelection().removeAllRanges()
document.getSelection().addRange(selected)
}
this.$message.success(message)
} }
} }
} }

View File

@ -1,7 +1,17 @@
<template> <template>
<el-row class="app-container"> <el-row class="app-container">
<el-row class="app-bar" type="flex"> <el-row class="app-bar" type="flex">
<el-input v-model="projectName" style="width:300px" placeholder="Filter the project name" @change="getList" /> <el-select v-model="searchProject.environment" placeholder="environment" clearable>
<el-option :label="$t('envOption[1]')" :value="1" />
<el-option :label="$t('envOption[2]')" :value="2" />
<el-option :label="$t('envOption[3]')" :value="3" />
<el-option :label="$t('envOption[4]')" :value="4" />
</el-select>
<el-select v-model="searchProject.autoDeploy" placeholder="auto deploy" clearable>
<el-option :label="$t('close')" :value="0" />
<el-option label="webhook" :value="1" />
</el-select>
<el-input v-model="searchProject.name" style="width:300px" placeholder="Filter the project name" />
</el-row> </el-row>
<el-table <el-table
:key="tableHeight" :key="tableHeight"
@ -611,7 +621,6 @@ export default {
return { return {
userId: '', userId: '',
userOption: [], userOption: [],
projectName: '',
publishToken: '', publishToken: '',
commitDialogVisible: false, commitDialogVisible: false,
tagDialogVisible: false, tagDialogVisible: false,
@ -624,10 +633,15 @@ export default {
traceLoading: false, traceLoading: false,
tableloading: false, tableloading: false,
tableData: [], tableData: [],
searchProject: {
name: '',
environment: '',
autoDeploy: ''
},
pagination: { pagination: {
total: 0, total: 0,
page: 1, page: 1,
rows: 20 rows: 16
}, },
taskTableLoading: false, taskTableLoading: false,
taskTableData: [], taskTableData: [],
@ -741,7 +755,17 @@ export default {
}, },
computed: { computed: {
tablePageData: function() { tablePageData: function() {
return this.tableData.slice((this.pagination.page - 1) * this.pagination.rows, this.pagination.page * this.pagination.rows) let tableData = this.tableData
if (this.searchProject.name !== '') {
tableData = this.tableData.filter(item => item.name.indexOf(this.searchProject.name) !== -1)
}
if (this.searchProject.environment !== '') {
tableData = this.tableData.filter(item => item.environment === this.searchProject.environment)
}
if (this.searchProject.autoDeploy !== '') {
tableData = this.tableData.filter(item => item.autoDeploy === this.searchProject.autoDeploy)
}
return tableData.slice((this.pagination.page - 1) * this.pagination.rows, this.pagination.page * this.pagination.rows)
}, },
previewFilterlength: function() { previewFilterlength: function() {
let number = 0 let number = 0
@ -813,7 +837,7 @@ export default {
getList() { getList() {
this.tableloading = true this.tableloading = true
getList(this.projectName).then((response) => { getList().then((response) => {
this.tableData = response.data.list.map(element => { this.tableData = response.data.list.map(element => {
element.progressPercentage = 0 element.progressPercentage = 0
element.tagType = 'info' element.tagType = 'info'

View File

@ -70,7 +70,9 @@
<el-table-column prop="operation" :label="$t('op')" width="180" align="center" fixed="right"> <el-table-column prop="operation" :label="$t('op')" width="180" align="center" fixed="right">
<template slot-scope="scope"> <template slot-scope="scope">
<el-button type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)" /> <el-button type="primary" icon="el-icon-edit" @click="handleEdit(scope.row)" />
<el-button type="info" icon="el-icon-document-copy" @click="handleCopy(scope.row)" /> <el-tooltip class="item" effect="dark" content="Copy" placement="bottom">
<el-button type="info" icon="el-icon-document-copy" @click="handleCopy(scope.row)" />
</el-tooltip>
<el-button type="danger" icon="el-icon-delete" @click="handleRemove(scope.row)" /> <el-button type="danger" icon="el-icon-delete" @click="handleRemove(scope.row)" />
</template> </template>
</el-table-column> </el-table-column>

View File

@ -54,7 +54,15 @@
<el-input v-model="formData.owner" autocomplete="off" placeholder="root" /> <el-input v-model="formData.owner" autocomplete="off" placeholder="root" />
</el-form-item> </el-form-item>
<el-form-item :label="$t('serverPage.sshKeyPath')" prop="path"> <el-form-item :label="$t('serverPage.sshKeyPath')" prop="path">
<el-input v-model="formData.path" autocomplete="off" placeholder="/root/.ssh/id_rsa" /> <el-row type="flex">
<el-input v-model="formData.path" autocomplete="off" placeholder="/root/.ssh/id_rsa" />
<el-button
:icon="'el-icon-copy-document'"
type="success"
:disabled="formData.path===''"
@click="getPublicKey"
>{{ $t('serverPage.copyPub') }}</el-button>
</el-row>
</el-form-item> </el-form-item>
<el-form-item :label="$t('serverPage.sshKeyPassword')" prop="password"> <el-form-item :label="$t('serverPage.sshKeyPassword')" prop="password">
<el-input v-model="formData.password" autocomplete="off" placeholder="" /> <el-input v-model="formData.password" autocomplete="off" placeholder="" />
@ -80,7 +88,7 @@
</el-row> </el-row>
</template> </template>
<script> <script>
import { getList, getTotal, add, edit, check, remove } from '@/api/server' import { getList, getTotal, getPublicKey, add, edit, check, remove } from '@/api/server'
export default { export default {
name: 'Server', name: 'Server',
@ -154,6 +162,12 @@ export default {
}) })
}, },
getPublicKey() {
getPublicKey(this.formData.path).then((response) => {
this.copy(response.data, this.$t('serverPage.copyPubTips'))
})
},
// //
handlePageChange(val) { handlePageChange(val) {
this.pagination.page = val this.pagination.page = val