diff --git a/spug_api/apps/app/models.py b/spug_api/apps/app/models.py index 3da9dac..010314f 100644 --- a/spug_api/apps/app/models.py +++ b/spug_api/apps/app/models.py @@ -41,6 +41,7 @@ class Deploy(models.Model, ModelMixin): host_ids = models.TextField() extend = models.CharField(max_length=2, choices=EXTENDS) is_audit = models.BooleanField() + rst_notify = models.CharField(max_length=255) created_at = models.CharField(max_length=20, default=human_datetime) 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['app_name'] = self.app_name if hasattr(self, 'app_name') else None deploy['host_ids'] = json.loads(self.host_ids) + deploy['rst_notify'] = json.loads(self.rst_notify) deploy.update(self.extend_obj.to_dict()) return deploy diff --git a/spug_api/apps/app/views.py b/spug_api/apps/app/views.py index 6647520..4807f5e 100644 --- a/spug_api/apps/app/views.py +++ b/spug_api/apps/app/views.py @@ -81,6 +81,7 @@ class DeployView(View): Argument('app_id', type=int, help='请选择应用'), Argument('env_id', type=int, 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('is_audit', type=bool, default=False) ).parse(request.body) @@ -89,6 +90,7 @@ class DeployView(View): if deploy and deploy.id != form.id: return json_response(error='应用在该环境下已经存在发布配置') form.host_ids = json.dumps(form.host_ids) + form.rst_notify = json.dumps(form.rst_notify) if form.extend == '1': extend_form, error = JsonParser( Argument('git_repo', handler=str.strip, help='请输入git仓库地址'), diff --git a/spug_api/apps/deploy/utils.py b/spug_api/apps/deploy/utils.py index 818cb69..8999dbf 100644 --- a/spug_api/apps/deploy/utils.py +++ b/spug_api/apps/deploy/utils.py @@ -3,9 +3,10 @@ # Released under the MIT License. from django_redis import get_redis_connection 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 concurrent import futures +import requests import socket import subprocess import json @@ -46,6 +47,7 @@ def deploy_dispatch(request, req, token): rds.expire(token, 5 * 60) rds.close() req.save() + Helper.send_deploy_notify(req) def _ext1_deploy(req, helper, env): @@ -179,6 +181,51 @@ class Helper: self.rds = rds 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'**发布结果:** {text}', + 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): data, files = data.strip(), [] if data: diff --git a/spug_web/src/pages/deploy/app/AddSelect.js b/spug_web/src/pages/deploy/app/AddSelect.js index 4638cc0..f87ae65 100644 --- a/spug_web/src/pages/deploy/app/AddSelect.js +++ b/spug_web/src/pages/deploy/app/AddSelect.js @@ -17,6 +17,7 @@ class AddSelect extends React.Component { store.deploy = { git_type: 'branch', is_audit: false, + rst_notify: {mode: '0'}, versions: 10, host_ids: [undefined], filter_rule: {type: 'contain', data: ''} @@ -28,6 +29,7 @@ class AddSelect extends React.Component { store.ext2Visible = true; store.deploy = { is_audit: false, + rst_notify: {mode: '0'}, host_ids: [undefined], host_actions: [], server_actions: [] diff --git a/spug_web/src/pages/deploy/app/Ext1Setup1.js b/spug_web/src/pages/deploy/app/Ext1Setup1.js index 43e1a66..5bc30e9 100644 --- a/spug_web/src/pages/deploy/app/Ext1Setup1.js +++ b/spug_web/src/pages/deploy/app/Ext1Setup1.js @@ -36,6 +36,20 @@ export default observer(function Ext2Setup1() { checked={info['is_audit']} onChange={v => info['is_audit'] = v}/> + + info['rst_notify']['mode'] = v}> + 关闭 + 钉钉 + Webhook + + )} + disabled={info['rst_notify']['mode'] === '0'} + value={info['rst_notify']['value']} + onChange={e => info['rst_notify']['value'] = e.target.value} + placeholder="请输入"/> +