A 新增私有仓库地址辅助配置功能

pull/480/head
vapao 2022-04-17 17:45:11 +08:00
parent 5ccd814707
commit bd548e425e
5 changed files with 131 additions and 5 deletions

View File

@ -196,7 +196,12 @@ def get_versions(request, d_id):
return json_response({'branches': branches, 'tags': tags})
@auth('deploy.app.config')
@auth('deploy.app.config|deploy.app.edit')
def kit_key(request):
api_key = AppSetting.get_default('api_key')
return json_response(api_key)
form, error = JsonParser(
Argument('key', filter=lambda x: x in ('api_key', 'public_key'), help='参数错误')
).parse(request.body)
if error is None:
api_key = AppSetting.get_default(form.key)
return json_response(api_key)
return json_response(error=error)

View File

@ -30,4 +30,9 @@ code {
/* Common CSS style */
.none {
display: none;
}
.btn {
color: #2563fc;
cursor: pointer;
}

View File

@ -19,7 +19,7 @@ export default observer(function AutoDeploy() {
if (store.deploy.extend === '1') {
fetchVersions()
}
http.get('/api/app/kit/key/')
http.post('/api/app/kit/key/', {key: 'api_key'})
.then(res => setKey(res))
}, [])

View File

@ -7,12 +7,14 @@ import React, { useEffect, useState } from 'react';
import { observer } from 'mobx-react';
import { Link } from 'react-router-dom';
import { Switch, Form, Input, Select, Button, Radio } from 'antd';
import Repo from './Repo';
import envStore from 'pages/config/environment/store';
import Selector from 'pages/host/Selector';
import store from './store';
export default observer(function Ext1Setup1() {
const [envs, setEnvs] = useState([]);
const [visible, setVisible] = useState(false);
function updateEnvs() {
const ids = store.currentRecord['deploys'].map(x => x.env_id);
@ -63,7 +65,7 @@ export default observer(function Ext1Setup1() {
{info.host_ids.length > 0 && <span style={{marginRight: 16}}>已选择 {info.host_ids.length} </span>}
<Button type="link" style={{padding: 0}} onClick={() => store.selectorVisible = true}>选择主机</Button>
</Form.Item>
<Form.Item required label="Git仓库地址">
<Form.Item required label="Git仓库地址" extra={<span className="btn" onClick={() => setVisible(true)}>私有仓库</span>}>
<Input disabled={store.isReadOnly} value={info['git_repo']} onChange={e => info['git_repo'] = e.target.value}
placeholder="请输入Git仓库地址"/>
</Form.Item>
@ -119,6 +121,7 @@ export default observer(function Ext1Setup1() {
selectedRowKeys={[...info.host_ids]}
onCancel={() => store.selectorVisible = false}
onOk={(_, ids) => info.host_ids = ids}/>
{visible && <Repo url={info['git_repo']} onOk={v => info['git_repo'] = v} onCancel={() => setVisible(false)}/>}
</Form>
)
})

View File

@ -0,0 +1,113 @@
/**
* Copyright (c) OpenSpug Organization. https://github.com/openspug/spug
* Copyright (c) <spug.dev@gmail.com>
* Released under the AGPL-3.0 License.
*/
import React, { useEffect, useState } from 'react';
import { Modal, Form, Radio, Input, message } from 'antd';
import { http } from 'libs';
function Repo(props) {
const [form] = Form.useForm()
const [key, setKey] = useState()
useEffect(() => {
http.post('/api/app/kit/key/', {key: 'public_key'})
.then(res => setKey(res))
if (props.url) {
const fields = props.url.match(/^(https?:\/\/)(.+):(.+)@(.*)$/)
if (fields && fields.length === 5) {
form.setFieldsValue({
type: 'password',
url: fields[1] + fields[4],
username: decodeURIComponent(fields[2]),
password: decodeURIComponent(fields[3])
})
} else if (props.url.startsWith('git@')) {
form.setFieldsValue({type: 'key', url: props.url})
} else {
form.setFieldsValue({url: props.url})
}
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
function handleSubmit() {
const formData = form.getFieldsValue()
if (!formData.url) return message.error('请输入仓库地址')
let url = formData.url;
if (formData.type === 'password') {
if (!formData.username) return message.error('请输入账户')
if (!formData.password) return message.error('请输入密码')
if (formData.url.startsWith('http')) {
const username = encodeURIComponent(formData.username)
const password = encodeURIComponent(formData.password)
url = formData.url.replace(/^(https?:\/\/)/, `$1${username}:${password}@`)
} else {
return message.error('认证类型为账户密码仓库地址需以http或https开头。')
}
} else if (formData.url.startsWith('http')) {
return message.error('输入的仓库地址以http或https开头则认证类型需为账户密码认证。')
}
props.onOk(url)
props.onCancel()
}
function copyToClipBoard() {
const t = document.createElement('input');
t.value = key;
document.body.appendChild(t);
t.select();
document.execCommand('copy');
t.remove();
message.success('已复制')
}
return (
<Modal
visible
maskClosable={false}
title="设置Git仓库"
onCancel={props.onCancel}
onOk={handleSubmit}>
<Form form={form} labelCol={{span: 6}} wrapperCol={{span: 16}}>
<Form.Item label="认证类型" name="type" initialValue="password">
<Radio.Group>
<Radio.Button value="password">账户密码</Radio.Button>
<Radio.Button value="key">密钥</Radio.Button>
</Radio.Group>
</Form.Item>
<Form.Item required label="仓库地址" name="url">
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item noStyle shouldUpdate>
{({getFieldValue}) =>
getFieldValue('type') === 'password' ? (
<React.Fragment>
<Form.Item required label="账户" name="username">
<Input placeholder="请输入"/>
</Form.Item>
<Form.Item required label="密码" name="password">
<Input placeholder="请输入"/>
</Form.Item>
</React.Fragment>
) : (
<Form.Item label="密钥" extra={(
<span>
请复制该密钥以Gitee为例可参考
<a target="_blank" rel="noopener noreferrer" href="https://gitee.com/help/articles/4191">Gitee文档</a>
进行后续配置
</span>
)}>
<span className="btn" onClick={copyToClipBoard}>点击复制密钥</span>
</Form.Item>
)
}
</Form.Item>
</Form>
</Modal>
)
}
export default Repo