mirror of https://github.com/openspug/spug
				
				
				
			
		
			
				
	
	
		
			184 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
			
		
		
	
	
			184 lines
		
	
	
		
			9.0 KiB
		
	
	
	
		
			Python
		
	
	
| # Copyright: (c) OpenSpug Organization. https://github.com/openspug/spug
 | |
| # Copyright: (c) <spug.dev@gmail.com>
 | |
| # Released under the AGPL-3.0 License.
 | |
| from django.views.generic import View
 | |
| from django.db.models import F
 | |
| from django.conf import settings
 | |
| from libs import JsonParser, Argument, json_response
 | |
| from apps.app.models import App, Deploy, DeployExtend1, DeployExtend2
 | |
| from apps.config.models import Config
 | |
| from apps.app.utils import parse_envs, fetch_versions, remove_repo
 | |
| import subprocess
 | |
| import json
 | |
| import os
 | |
| 
 | |
| 
 | |
| class AppView(View):
 | |
|     def get(self, request):
 | |
|         # v2.3.14 临时数据初始化
 | |
|         app = App.objects.first()
 | |
|         if app and hasattr(app, 'sort_id') and app.sort_id == 0:
 | |
|             for app in App.objects.all():
 | |
|                 app.sort_id = app.id
 | |
|                 app.save()
 | |
|         query = {}
 | |
|         if not request.user.is_supper:
 | |
|             query['id__in'] = request.user.deploy_perms['apps']
 | |
|         apps = App.objects.filter(**query)
 | |
|         return json_response(apps)
 | |
| 
 | |
|     def post(self, request):
 | |
|         form, error = JsonParser(
 | |
|             Argument('id', type=int, required=False),
 | |
|             Argument('name', help='请输入服务名称'),
 | |
|             Argument('key', help='请输入唯一标识符'),
 | |
|             Argument('desc', required=False)
 | |
|         ).parse(request.body)
 | |
|         if error is None:
 | |
|             form.name = form.name.replace("'", '')
 | |
|             app = App.objects.filter(key=form.key).first()
 | |
|             if app and app.id != form.id:
 | |
|                 return json_response(error=f'唯一标识符 {form.key} 已存在,请更改后重试')
 | |
|             if form.id:
 | |
|                 App.objects.filter(pk=form.id).update(**form)
 | |
|             else:
 | |
|                 app = App.objects.create(created_by=request.user, **form)
 | |
|                 app.sort_id = app.id
 | |
|                 app.save()
 | |
|                 if request.user.role:
 | |
|                     request.user.role.add_deploy_perm('apps', app.id)
 | |
|         return json_response(error=error)
 | |
| 
 | |
|     def patch(self, request):
 | |
|         form, error = JsonParser(
 | |
|             Argument('id', type=int, help='参数错误'),
 | |
|             Argument('rel_apps', type=list, required=False),
 | |
|             Argument('rel_services', type=list, required=False),
 | |
|             Argument('sort', filter=lambda x: x in ('up', 'down'), required=False)
 | |
|         ).parse(request.body)
 | |
|         if error is None:
 | |
|             app = App.objects.filter(pk=form.id).first()
 | |
|             if not app:
 | |
|                 return json_response(error='未找到指定应用')
 | |
|             if form.rel_apps is not None:
 | |
|                 app.rel_apps = json.dumps(form.rel_apps)
 | |
|             if form.rel_services is not None:
 | |
|                 app.rel_services = json.dumps(form.rel_services)
 | |
|             if form.sort:
 | |
|                 if form.sort == 'up':
 | |
|                     tmp = App.objects.filter(sort_id__gt=app.sort_id).last()
 | |
|                 else:
 | |
|                     tmp = App.objects.filter(sort_id__lt=app.sort_id).first()
 | |
|                 if tmp:
 | |
|                     tmp.sort_id, app.sort_id = app.sort_id, tmp.sort_id
 | |
|                     tmp.save()
 | |
|             app.save()
 | |
|         return json_response(error=error)
 | |
| 
 | |
|     def delete(self, request):
 | |
|         form, error = JsonParser(
 | |
|             Argument('id', type=int, help='请指定操作对象')
 | |
|         ).parse(request.GET)
 | |
|         if error is None:
 | |
|             if Deploy.objects.filter(app_id=form.id).exists():
 | |
|                 return json_response(error='该应用在应用发布中已存在关联的发布配置,请删除相关发布配置后再尝试删除')
 | |
|             if Config.objects.filter(type='app', o_id=form.id).exists():
 | |
|                 return json_response(error='该应用在配置中心已存在关联的配置信息,请删除相关配置后再尝试删除')
 | |
|             App.objects.filter(pk=form.id).delete()
 | |
|         return json_response(error=error)
 | |
| 
 | |
| 
 | |
| class DeployView(View):
 | |
|     def get(self, request):
 | |
|         form, error = JsonParser(
 | |
|             Argument('app_id', type=int, required=False)
 | |
|         ).parse(request.GET, True)
 | |
|         if not request.user.is_supper:
 | |
|             perms = request.user.deploy_perms
 | |
|             form.app_id__in = perms['apps']
 | |
|             form.env_id__in = perms['envs']
 | |
|         deploys = Deploy.objects.filter(**form).annotate(app_name=F('app__name')).order_by('-app__sort_id')
 | |
|         return json_response(deploys)
 | |
| 
 | |
|     def post(self, request):
 | |
|         form, error = JsonParser(
 | |
|             Argument('id', type=int, required=False),
 | |
|             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)
 | |
|         if error is None:
 | |
|             deploy = Deploy.objects.filter(app_id=form.app_id, env_id=form.env_id).first()
 | |
|             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仓库地址'),
 | |
|                     Argument('dst_dir', handler=str.strip, help='请输入发布目标路径'),
 | |
|                     Argument('dst_repo', handler=str.strip, help='请输入目标仓库路径'),
 | |
|                     Argument('versions', type=int, help='请输入保留历史版本数量'),
 | |
|                     Argument('filter_rule', type=dict, help='参数错误'),
 | |
|                     Argument('custom_envs', handler=str.strip, required=False),
 | |
|                     Argument('hook_pre_server', handler=str.strip, default=''),
 | |
|                     Argument('hook_post_server', handler=str.strip, default=''),
 | |
|                     Argument('hook_pre_host', handler=str.strip, default=''),
 | |
|                     Argument('hook_post_host', handler=str.strip, default='')
 | |
|                 ).parse(request.body)
 | |
|                 if error:
 | |
|                     return json_response(error=error)
 | |
|                 extend_form.dst_dir = extend_form.dst_dir.rstrip('/')
 | |
|                 extend_form.filter_rule = json.dumps(extend_form.filter_rule)
 | |
|                 extend_form.custom_envs = json.dumps(parse_envs(extend_form.custom_envs))
 | |
|                 if form.id:
 | |
|                     extend = DeployExtend1.objects.filter(deploy_id=form.id).first()
 | |
|                     if extend.git_repo != extend_form.git_repo:
 | |
|                         remove_repo(form.id)
 | |
|                     Deploy.objects.filter(pk=form.id).update(**form)
 | |
|                     DeployExtend1.objects.filter(deploy_id=form.id).update(**extend_form)
 | |
|                 else:
 | |
|                     deploy = Deploy.objects.create(created_by=request.user, **form)
 | |
|                     DeployExtend1.objects.create(deploy=deploy, **extend_form)
 | |
|             elif form.extend == '2':
 | |
|                 extend_form, error = JsonParser(
 | |
|                     Argument('server_actions', type=list, help='请输入执行动作'),
 | |
|                     Argument('host_actions', type=list, help='请输入执行动作')
 | |
|                 ).parse(request.body)
 | |
|                 if error:
 | |
|                     return json_response(error=error)
 | |
|                 if len(extend_form.server_actions) + len(extend_form.host_actions) == 0:
 | |
|                     return json_response(error='请至少设置一个执行的动作')
 | |
|                 extend_form.server_actions = json.dumps(extend_form.server_actions)
 | |
|                 extend_form.host_actions = json.dumps(extend_form.host_actions)
 | |
|                 if form.id:
 | |
|                     Deploy.objects.filter(pk=form.id).update(**form)
 | |
|                     DeployExtend2.objects.filter(deploy_id=form.id).update(**extend_form)
 | |
|                 else:
 | |
|                     deploy = Deploy.objects.create(created_by=request.user, **form)
 | |
|                     DeployExtend2.objects.create(deploy=deploy, **extend_form)
 | |
|         return json_response(error=error)
 | |
| 
 | |
|     def delete(self, request):
 | |
|         form, error = JsonParser(
 | |
|             Argument('id', type=int, help='请指定操作对象')
 | |
|         ).parse(request.GET)
 | |
|         if error is None:
 | |
|             Deploy.objects.filter(pk=form.id).delete()
 | |
|             repo_dir = os.path.join(settings.REPOS_DIR, str(form.id))
 | |
|             subprocess.Popen(f'rm -rf {repo_dir} {repo_dir + "_*"}', shell=True)
 | |
|         return json_response(error=error)
 | |
| 
 | |
| 
 | |
| def get_versions(request, d_id):
 | |
|     deploy = Deploy.objects.filter(pk=d_id).first()
 | |
|     if not deploy:
 | |
|         return json_response(error='未找到指定应用')
 | |
|     if deploy.extend == '2':
 | |
|         return json_response(error='该应用不支持此操作')
 | |
|     branches, tags = fetch_versions(deploy)
 | |
|     return json_response({'branches': branches, 'tags': tags})
 |