A 添加应用发布结果通知功能

pull/22/head
vapao 2020-02-15 17:21:22 +08:00
parent a2609b876a
commit 2301311d76
5 changed files with 68 additions and 1 deletions

View File

@ -41,6 +41,7 @@ class Deploy(models.Model, ModelMixin):
host_ids = models.TextField() host_ids = models.TextField()
extend = models.CharField(max_length=2, choices=EXTENDS) extend = models.CharField(max_length=2, choices=EXTENDS)
is_audit = models.BooleanField() is_audit = models.BooleanField()
rst_notify = models.CharField(max_length=255)
created_at = models.CharField(max_length=20, default=human_datetime) created_at = models.CharField(max_length=20, default=human_datetime)
created_by = models.ForeignKey(User, models.PROTECT, related_name='+') created_by = models.ForeignKey(User, models.PROTECT, related_name='+')
@ -56,6 +57,7 @@ class Deploy(models.Model, ModelMixin):
deploy = super().to_dict(*args, **kwargs) deploy = super().to_dict(*args, **kwargs)
deploy['app_name'] = self.app_name if hasattr(self, 'app_name') else None deploy['app_name'] = self.app_name if hasattr(self, 'app_name') else None
deploy['host_ids'] = json.loads(self.host_ids) deploy['host_ids'] = json.loads(self.host_ids)
deploy['rst_notify'] = json.loads(self.rst_notify)
deploy.update(self.extend_obj.to_dict()) deploy.update(self.extend_obj.to_dict())
return deploy return deploy

View File

@ -81,6 +81,7 @@ class DeployView(View):
Argument('app_id', type=int, help='请选择应用'), Argument('app_id', type=int, help='请选择应用'),
Argument('env_id', type=int, help='请选择环境'), Argument('env_id', type=int, help='请选择环境'),
Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'), Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'),
Argument('rst_notify', type=dict, help='请选择发布结果通知方式'),
Argument('extend', filter=lambda x: x in dict(Deploy.EXTENDS), help='请选择发布类型'), Argument('extend', filter=lambda x: x in dict(Deploy.EXTENDS), help='请选择发布类型'),
Argument('is_audit', type=bool, default=False) Argument('is_audit', type=bool, default=False)
).parse(request.body) ).parse(request.body)
@ -89,6 +90,7 @@ class DeployView(View):
if deploy and deploy.id != form.id: if deploy and deploy.id != form.id:
return json_response(error='应用在该环境下已经存在发布配置') return json_response(error='应用在该环境下已经存在发布配置')
form.host_ids = json.dumps(form.host_ids) form.host_ids = json.dumps(form.host_ids)
form.rst_notify = json.dumps(form.rst_notify)
if form.extend == '1': if form.extend == '1':
extend_form, error = JsonParser( extend_form, error = JsonParser(
Argument('git_repo', handler=str.strip, help='请输入git仓库地址'), Argument('git_repo', handler=str.strip, help='请输入git仓库地址'),

View File

@ -3,9 +3,10 @@
# Released under the MIT License. # Released under the MIT License.
from django_redis import get_redis_connection from django_redis import get_redis_connection
from django.conf import settings from django.conf import settings
from libs.utils import AttrDict, human_time from libs.utils import AttrDict, human_time, human_datetime
from apps.host.models import Host from apps.host.models import Host
from concurrent import futures from concurrent import futures
import requests
import socket import socket
import subprocess import subprocess
import json import json
@ -46,6 +47,7 @@ def deploy_dispatch(request, req, token):
rds.expire(token, 5 * 60) rds.expire(token, 5 * 60)
rds.close() rds.close()
req.save() req.save()
Helper.send_deploy_notify(req)
def _ext1_deploy(req, helper, env): def _ext1_deploy(req, helper, env):
@ -179,6 +181,51 @@ class Helper:
self.rds = rds self.rds = rds
self.token = token self.token = token
@staticmethod
def send_deploy_notify(req):
rst_notify = json.loads(req.deploy.rst_notify)
if rst_notify['mode'] != '0' and rst_notify.get('value'):
extra = json.loads(req.extra)
if req.deploy.extend == '1':
mode, extra1, extra2 = extra
if mode == 'branch':
version = f'{extra1}#{extra2[:6]}'
else:
version = extra1
else:
version = extra[0]
if rst_notify['mode'] == '1':
color, text = ('#8ece60', '成功') if req.status == '3' else ('#f90202', '失败')
texts = [
'## %s ## ' % '发布结果通知',
f'**应用名称:** {req.deploy.app.name} ',
f'**发布环境:** {req.deploy.env.name} ',
f'**应用版本:** {version} ',
f'**发布结果:** <font color="{color}">{text}</font>',
f'**发布时间:** {human_datetime()} ',
'> 来自 Spug运维平台'
]
data = {
'msgtype': 'markdown',
'markdown': {
'title': '发布结果通知',
'text': '\n\n'.join(texts)
}
}
res = requests.post(rst_notify['value'], json=data)
elif rst_notify['mode'] == '2':
data = {
'req_id': req.id,
'app_id': req.deploy.app_id,
'app_name': req.deploy.app.name,
'env_id': req.deploy.env_id,
'env_name': req.deploy.env.name,
'version': version,
'is_success': req.status == '3',
'deploy_at': human_datetime()
}
requests.post(rst_notify['value'], json=data)
def parse_filter_rule(self, data: str): def parse_filter_rule(self, data: str):
data, files = data.strip(), [] data, files = data.strip(), []
if data: if data:

View File

@ -17,6 +17,7 @@ class AddSelect extends React.Component {
store.deploy = { store.deploy = {
git_type: 'branch', git_type: 'branch',
is_audit: false, is_audit: false,
rst_notify: {mode: '0'},
versions: 10, versions: 10,
host_ids: [undefined], host_ids: [undefined],
filter_rule: {type: 'contain', data: ''} filter_rule: {type: 'contain', data: ''}
@ -28,6 +29,7 @@ class AddSelect extends React.Component {
store.ext2Visible = true; store.ext2Visible = true;
store.deploy = { store.deploy = {
is_audit: false, is_audit: false,
rst_notify: {mode: '0'},
host_ids: [undefined], host_ids: [undefined],
host_actions: [], host_actions: [],
server_actions: [] server_actions: []

View File

@ -36,6 +36,20 @@ export default observer(function Ext2Setup1() {
checked={info['is_audit']} checked={info['is_audit']}
onChange={v => info['is_audit'] = v}/> onChange={v => info['is_audit'] = v}/>
</Form.Item> </Form.Item>
<Form.Item label="结果通知" help="应用发布成功或失败结果通知">
<Input addonBefore={(
<Select
value={info['rst_notify']['mode']} style={{width: 100}} onChange={v => info['rst_notify']['mode'] = v}>
<Select.Option value="0">关闭</Select.Option>
<Select.Option value="1">钉钉</Select.Option>
<Select.Option value="2">Webhook</Select.Option>
</Select>
)}
disabled={info['rst_notify']['mode'] === '0'}
value={info['rst_notify']['value']}
onChange={e => info['rst_notify']['value'] = e.target.value}
placeholder="请输入"/>
</Form.Item>
<Form.Item wrapperCol={{span: 14, offset: 6}}> <Form.Item wrapperCol={{span: 14, offset: 6}}>
<Button <Button
type="primary" type="primary"