def post(self, request): form, error = JsonParser( Argument('id', type=int, required=False), Argument('username', help='请输入登录名'), Argument('password', help='请输入密码'), Argument('nickname', help='请输入姓名'), Argument('role_ids', type=list, default=[]), Argument('wx_token', required=False), ).parse(request.body) if error is None: user = User.objects.filter(username=form.username, deleted_by_id__isnull=True).first() if user and (not form.id or form.id != user.id): return json_response(error=f'已存在登录名为【{form.username}】的用户') role_ids, password = form.pop('role_ids'), form.pop('password') if form.id: user = User.objects.get(pk=form.id) user.update_by_dict(form) else: user = User.objects.create( password_hash=User.make_password(password), created_by=request.user, **form) user.roles.set(role_ids) user.set_perms_cache() return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('id', type=int, required=False), Argument('zone', help='请输入主机类型'), Argument('name', help='请输主机名称'), Argument('username', handler=str.strip, help='请输入登录用户名'), Argument('hostname', handler=str.strip, help='请输入主机名或IP'), Argument('port', type=int, help='请输入SSH端口'), Argument('pkey', required=False), Argument('desc', required=False), Argument('password', required=False), ).parse(request.body) if error is None: if valid_ssh(form.hostname, form.port, form.username, password=form.pop('password'), pkey=form.pkey) is False: return json_response('auth fail') if form.id: Host.objects.filter(pk=form.pop('id')).update(**form) elif Host.objects.filter(name=form.name, deleted_by_id__isnull=True).exists(): return json_response(error=f'已存在的主机名称【{form.name}】') else: host = Host.objects.create(created_by=request.user, **form) if request.user.role: request.user.role.add_host_perm(host.id) return json_response(error=error)
def login(request): form, error = JsonParser(Argument('username', help='请输入用户名'), Argument('password', help='请输入密码'), Argument('type')).parse(request.body) if error is None: user = User.objects.filter(username=form.username) if form.type == 'ldap': u = LDAP() valid = u.valid_user(form.username, form.password) if valid['status']: user = user.filter(type='LDAP').first() if user: if not user.is_active: return json_response(error="账户已被系统禁用") if not user.role_id: return json_response(error="LDAP用户角色未分配") x_real_ip = request.headers.get('x-real-ip', '') ret = handle_user_info(user, form.username, x_real_ip) return json_response(ret) x_real_ip = request.headers.get('x-real-ip', '') form.access_token = uuid.uuid4().hex form.nickname = form.username form.token_expired = time.time() + 8 * 60 * 60 form.last_login = human_datetime() form.last_ip = x_real_ip form.type = 'LDAP' form.pop('password') User.objects.create(**form) return json_response({ 'access_token': form.access_token, 'nickname': form.username, 'is_supper': False, 'has_real_ip': True if x_real_ip else False, 'permissions': [] }) return json_response(error=valid['info']) else: user = user.filter(type='系统用户').first() if user and user.deleted_by is None: if not user.is_active: return json_response(error="账户已被系统禁用") if user.verify_password(form.password): cache.delete(form.username) x_real_ip = request.headers.get('x-real-ip', '') ret = handle_user_info(user, form.username, x_real_ip) return json_response(ret) value = cache.get_or_set(form.username, 0, 86400) if value >= 3: if user and user.is_active: user.is_active = False user.save() return json_response(error='账户已被系统禁用') cache.set(form.username, value + 1, 86400) return json_response(error="用户名或密码错误,连续多次错误账户将会被禁用") return json_response(error=error)
def patch(self, request): form, error = JsonParser( Argument('id', type=int, help='请指定操作对象'), Argument('username', required=False), Argument('password', required=False), Argument('nickname', required=False), Argument('role_id', required=False), Argument('is_active', type=bool, required=False), ).parse(request.body, True) if error is None: if form.get('password'): form.token_expired = 0 form.password_hash = User.make_password(form.pop('password')) User.objects.filter(pk=form.pop('id')).update(**form) return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('o_id', type=int, help='缺少必要参数'), Argument('type', filter=lambda x: x in dict(Config.TYPES), help='缺少必要参数'), Argument('envs', type=list, filter=lambda x: len(x), help='请选择环境'), Argument('key', help='请输入Key'), Argument('is_public', type=bool, help='缺少必要参数'), Argument('value', type=str, default=''), Argument('desc', required=False)).parse(request.body) if error is None: form.value = form.value.strip() form.updated_at = human_datetime() form.updated_by = request.user envs = form.pop('envs') for env_id in envs: cf = Config.objects.filter(o_id=form.o_id, type=form.type, env_id=env_id, key=form.key).first() if cf: raise Exception(f'{cf.env.name} 中已存在该Key') Config.objects.create(env_id=env_id, **form) ConfigHistory.objects.create(action='1', env_id=env_id, **form) return json_response(error=error)
def post_request_ext1_rollback(request): form, error = JsonParser( Argument('request_id', type=int, help='请选择要回滚的版本'), Argument('name', help='请输入申请标题'), Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'), Argument('desc', required=False), ).parse(request.body) if error is None: req = DeployRequest.objects.get(pk=form.pop('request_id')) requests = DeployRequest.objects.filter(deploy=req.deploy, status__in=('3', '-3')) versions = list({x.spug_version: 1 for x in requests}.keys()) if req.spug_version not in versions[:req.deploy.extend_obj.versions + 1]: return json_response( error='选择的版本超出了发布配置中设置的版本数量,无法快速回滚,可通过新建发布申请选择构建仓库里的该版本再次发布。') form.status = '0' if req.deploy.is_audit else '1' form.host_ids = json.dumps(sorted(form.host_ids)) new_req = DeployRequest.objects.create(deploy_id=req.deploy_id, repository_id=req.repository_id, type='2', extra=req.extra, version=req.version, spug_version=req.spug_version, created_by=request.user, **form) if req.deploy.is_audit: Thread(target=Helper.send_deploy_notify, args=(new_req, 'approve_req')).start() return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('id', type=int, required=False), Argument('group_ids', type=list, filter=lambda x: len(x), help='请选择主机分组'), Argument('name', help='请输主机名称'), Argument('username', handler=str.strip, help='请输入登录用户名'), Argument('hostname', handler=str.strip, help='请输入主机名或IP'), Argument('port', type=int, help='请输入SSH端口'), Argument('pkey', required=False), Argument('desc', required=False), Argument('password', required=False), ).parse(request.body) if error is None: password = form.pop('password') private_key, public_key = AppSetting.get_ssh_key() try: if form.pkey: private_key = form.pkey elif password: with SSH(form.hostname, form.port, form.username, password=password) as ssh: ssh.add_public_key(public_key) with SSH(form.hostname, form.port, form.username, private_key) as ssh: ssh.ping() except BadAuthenticationType: return json_response(error='该主机不支持密钥认证,请参考官方文档,错误代码:E01') except AuthenticationException: if password: return json_response(error='密钥认证失败,请参考官方文档,错误代码:E02') return json_response('auth fail') group_ids = form.pop('group_ids') other = Host.objects.filter(name=form.name).first() if other and (not form.id or other.id != form.id): return json_response(error=f'已存在的主机名称【{form.name}】') if form.id: Host.objects.filter(pk=form.id).update(is_verified=True, **form) host = Host.objects.get(pk=form.id) else: host = Host.objects.create(created_by=request.user, is_verified=True, **form) _sync_host_extend(host, ssh=ssh) host.groups.set(group_ids) response = host.to_view() response['group_ids'] = group_ids return json_response(response) return json_response(error=error)
def patch(self, request): form, error = JsonParser( Argument('id', type=int, help='请指定操作对象'), Argument('username', required=False), Argument('password', required=False), Argument('nickname', required=False), Argument('role_id', required=False), Argument('is_active', type=bool, required=False), ).parse(request.body, True) if error is None: if form.get('password'): form.token_expired = 0 form.password_hash = User.make_password(form.pop('password')) if User.objects.filter( username=form.username, deleted_by_id__isnull=True).exclude(id=form.id).exists(): return json_response(error=f'已存在登录名为【{form.username}】的用户') User.objects.filter(pk=form.pop('id')).update(**form) return json_response(error=error)
def parse_json(request): form, error = JsonParser( Argument('o_id', type=int, help='缺少必要参数'), Argument('type', filter=lambda x: x in dict(Config.TYPES), help='缺少必要参数'), Argument('env_id', type=int, help='缺少必要参数'), Argument('data', type=dict, help='缺少必要参数')).parse(request.body) if error is None: data = form.pop('data') _parse(request, form, data) return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('username', help='请输入登录名'), Argument('password', help='请输入密码'), Argument('nickname', help='请输入姓名'), Argument('role_id', type=int, help='请选择角色'), ).parse(request.body) if error is None: form.password_hash = User.make_password(form.pop('password')) form.created_by = request.user User.objects.create(**form) return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('id', type=int, required=False), Argument('zone', help='请输入主机类型'), Argument('name', help='请输主机名称'), Argument('username', help='请输入登录用户名'), Argument('hostname', help='请输入主机名或IP'), Argument('port', type=int, help='请输入SSH端口'), Argument('desc', required=False), Argument('password', required=False), ).parse(request.body) if error is None: if valid_ssh(form.hostname, form.port, form.username, form.pop('password')) is False: return json_response('auth fail') if form.id: Host.objects.filter(pk=form.pop('id')).update(**form) else: form.created_by = request.user Host.objects.create(**form) return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('username', help='请输入登录名'), Argument('password', help='请输入密码'), Argument('nickname', help='请输入姓名'), Argument('role_id', type=int, help='请选择角色'), ).parse(request.body) if error is None: if User.objects.filter(username=form.username, deleted_by_id__isnull=True).exists(): return json_response(error=f'已存在登录名为【{form.username}】的用户') form.password_hash = User.make_password(form.pop('password')) form.created_by = request.user User.objects.create(**form) return json_response(error=error)
def get(self, request): form, error = JsonParser( Argument('id', type=int, help='未指定操作对象'), Argument('type', filter=lambda x: x in dict(Config.TYPES), help='缺少必要参数'), Argument('env_id', type=int, help='缺少必要参数'), ).parse(request.GET) if error is None: form.o_id, data = form.pop('id'), [] for item in Config.objects.filter(**form).annotate(update_user=F('updated_by__nickname')): tmp = item.to_dict() tmp['update_user'] = item.update_user data.append(tmp) return json_response(data) return json_response(error=error)
def post_diff(request): form, error = JsonParser( Argument('o_id', type=int, help='缺少必要参数'), Argument('type', filter=lambda x: x in dict(Config.TYPES), help='缺少必要参数'), Argument('envs', type=list, filter=lambda x: len(x), help='缺少必要参数'), ).parse(request.body) if error is None: data, form.env_id__in = {}, form.pop('envs') for item in Config.objects.filter(**form).order_by('key'): if item.key in data: data[item.key][item.env_id] = item.value else: data[item.key] = {'key': item.key, item.env_id: item.value} return json_response(list(data.values())) return json_response(error=error)
def patch(self, request): form, error = JsonParser( Argument('id', type=int, help='参数错误'), Argument('password', required=False), Argument('is_active', type=bool, required=False), ).parse(request.body) if error is None: user = User.objects.get(pk=form.id) if form.password: user.token_expired = 0 user.password_hash = User.make_password(form.pop('password')) if form.is_active is not None: user.is_active = form.is_active cache.delete(user.username) user.save() return json_response(error=error)
def post(self, request): form, error = JsonParser(Argument('id', type=int, required=False), Argument('name', help='请输入模版名称'), Argument('type', help='请选择模版类型'), Argument('body', help='请输入模版内容'), Argument('desc', required=False)).parse(request.body) if error is None: if form.id: form.updated_at = human_datetime() form.updated_by = request.user ExecTemplate.objects.filter(pk=form.pop('id')).update(**form) else: form.created_by = request.user ExecTemplate.objects.create(**form) return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('id', type=int, required=False), Argument('name', help='机房名称'), Argument('desc', required=False), ).parse(request.body) if error is None: if form.id: Idc.objects.filter(pk=form.pop('id')).update(**form) elif Idc.objects.filter(name=form.name, deleted_by_id__isnull=True).exists(): return json_response(error=f'已存在的机房名称【{form.name}】') else: idc = Idc.objects.create(created_by=request.user, **form) return json_response(error=error)
def patch(self, request): form, error = JsonParser( Argument('id', type=int, help='参数错误'), Argument('page_perms', type=dict, required=False), Argument('deploy_perms', type=dict, required=False)).parse(request.body) if error is None: role = Role.objects.filter(pk=form.pop('id')).first() if not role: return json_response(error='未找到指定角色') if form.page_perms is not None: role.page_perms = json.dumps(form.page_perms) if form.deploy_perms is not None: role.deploy_perms = json.dumps(form.deploy_perms) role.user_set.update(token_expired=0) role.save() return json_response(error=error)
def post_request_ext2(request): form, error = JsonParser( Argument('id', type=int, required=False), Argument('deploy_id', type=int, help='缺少必要参数'), Argument('name', help='请输申请标题'), Argument('host_ids', type=list, filter=lambda x: len(x), help='请选择要部署的主机'), Argument('extra', type=dict, required=False), Argument('version', default=''), Argument('type', default='1'), Argument('plan', required=False), Argument('desc', required=False), ).parse(request.body) if error is None: deploy = Deploy.objects.filter(pk=form.deploy_id).first() if not deploy: return json_response(error='未找到该发布配置') extra = form.pop('extra') if DeployExtend2.objects.filter( deploy=deploy, host_actions__contains='"src_mode": "1"').exists(): if not extra: return json_response( error='该应用的发布配置中使用了数据传输动作且设置为发布时上传,请上传要传输的数据') form.spug_version = extra['path'] form.extra = json.dumps(extra) else: form.spug_version = Repository.make_spug_version(deploy.id) form.name = form.name.replace("'", '') form.status = '0' if deploy.is_audit else '1' form.host_ids = json.dumps(form.host_ids) if form.id: req = DeployRequest.objects.get(pk=form.id) is_required_notify = deploy.is_audit and req.status == '-1' DeployRequest.objects.filter(pk=form.id).update( created_by=request.user, reason=None, **form) else: req = DeployRequest.objects.create(created_by=request.user, **form) is_required_notify = deploy.is_audit if is_required_notify: Thread(target=Helper.send_deploy_notify, args=(req, 'approve_req')).start() return json_response(error=error)
def post(self, request): form, error = JsonParser( Argument('id', type=int, required=False), Argument('name', help='请输入引擎名称'), Argument('engine_type', filter=lambda x: x in dict(ExecEngine.ENGINE_TYPES), help='请选择引擎类型'), Argument('start_user', help='请输入启动用户', required=False), Argument('start_command', help='请输入启动命令', required=False), Argument('start_script', help='请输入启动脚本', required=False), Argument('engine_desc', required=False)).parse(request.body) if error is None: if form.id: # 更新 ExecEngine.objects.filter(pk=form.pop('id')).update(**form) else: ExecEngine.objects.create(**form) return json_response(error=error)
def parse_text(request): form, error = JsonParser( Argument('o_id', type=int, help='缺少必要参数'), Argument('type', filter=lambda x: x in dict(Config.TYPES), help='缺少必要参数'), Argument('env_id', type=int, help='缺少必要参数'), Argument('data', handler=str.strip, help='缺少必要参数') ).parse(request.body) if error is None: data = {} for line in form.pop('data').split('\n'): line = line.strip() if line: fields = line.split('=', 1) if len(fields) != 2 or fields[0].strip() == '': return json_response(error=f'解析配置{line!r}失败,确认其遵循 key = value 格式') data[fields[0].strip()] = fields[1].strip() _parse(request, form, data) return json_response(error=error)