Esempio n. 1
0
 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)
Esempio n. 2
0
def login(request):
    form, error = JsonParser(Argument('username', help='请输入用户名'),
                             Argument('password', help='请输入密码'),
                             Argument('type',
                                      required=False)).parse(request.body)
    if error is None:
        x_real_ip = get_request_real_ip(request.headers)
        user = User.objects.filter(username=form.username,
                                   type=form.type).first()
        if user and not user.is_active:
            return json_response(error="账户已被系统禁用")

        if user and user.deleted_by is None:
            if user.verify_password(form.password):
                return handle_user_info(user, x_real_ip)

        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)
Esempio n. 3
0
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)
Esempio n. 4
0
 def patch(self, request):
     form, error = JsonParser(
         Argument('old_password', required=False),
         Argument('new_password', required=False),
         Argument('nickname', required=False, help='请输入昵称'),
         Argument('wx_token', required=False),
     ).parse(request.body)
     if error is None:
         print(form)
         if form.old_password and form.new_password:
             if request.user.type == 'ldap':
                 return json_response(error='LDAP账户无法修改密码')
             if len(form.new_password) < 6:
                 return json_response(error='请设置至少6位的新密码')
             if request.user.verify_password(form.old_password):
                 request.user.password_hash = User.make_password(
                     form.new_password)
                 request.user.token_expired = 0
                 request.user.save()
                 return json_response()
             else:
                 return json_response(error='原密码错误,请重新输入')
         if form.nickname is not None:
             request.user.nickname = form.nickname
         if form.wx_token is not None:
             request.user.wx_token = form.wx_token
         request.user.save()
     return json_response(error=error)
Esempio n. 5
0
 def delete(self, request):
     form, error = JsonParser(
         Argument('id', type=int, required=False),
         Argument('expire', required=False),
         Argument('count', type=int, required=False,
                  help='请输入数字')).parse(request.GET)
     if error is None:
         if form.id:
             DeployRequest.objects.filter(pk=form.id,
                                          status__in=('0', '1',
                                                      '-1')).delete()
             return json_response()
         elif form.count:
             if form.count < 1:
                 return json_response(error='请输入正确的保留数量')
             counter, ids = defaultdict(int), []
             for item in DeployRequest.objects.all():
                 if counter[item.deploy_id] == form.count:
                     ids.append(item.id)
                 else:
                     counter[item.deploy_id] += 1
             count, _ = DeployRequest.objects.filter(id__in=ids).delete()
             return json_response(count)
         elif form.expire:
             count, _ = DeployRequest.objects.filter(
                 created_at__lt=form.expire).delete()
             return json_response(count)
         else:
             return json_response(error='请至少使用一个删除条件')
     return json_response(error=error)
Esempio n. 6
0
def login(request):
    form, error = JsonParser(Argument('username', help='请输入用户名'),
                             Argument('password', help='请输入密码'),
                             Argument('type')).parse(request.body)
    if error is None:
        x_real_ip = request.headers.get('x-real-ip', '')
        user = User.objects.filter(username=form.username,
                                   type=form.type).first()
        if user and not user.is_active:
            return json_response(error="账户已被系统禁用")
        if form.type == 'ldap':
            ldap = LDAP()
            is_success, message = ldap.valid_user(form.username, form.password)
            if is_success:
                if not user:
                    user = User.objects.create(username=form.username,
                                               nickname=form.username,
                                               type=form.type)
                return handle_user_info(user, x_real_ip)
            elif message:
                return json_response(error=message)
        else:
            if user and user.deleted_by is None:
                if user.verify_password(form.password):
                    return handle_user_info(user, x_real_ip)

        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="用户名或密码错误,连续多次错误账户将会被禁用")
Esempio n. 7
0
def do_task(request):
    form, error = JsonParser(
        Argument('host_ids',
                 type=list,
                 filter=lambda x: len(x),
                 help='请选择执行主机'), Argument('command', help='请输入执行命令内容'),
        Argument('engine_type', type=int, required=False),
        Argument('engine_id', type=int, required=False)).parse(request.body)
    if error is None:
        token = Channel.get_token()
        engine = None
        if form.engine_id:
            engine_obj = ExecEngine.objects.filter(pk=form.engine_id).first()
            if engine_obj:
                engine = ExecEngine.get_engine_dict(engine_obj)
        else:
            engine = ExecEngine.build_engine(form.engine_type)
        logger.info(f'{engine}')
        for host in Host.objects.filter(id__in=form.host_ids):
            Channel.send_ssh_executor(token=token,
                                      hostname=host.hostname,
                                      port=host.port,
                                      username=host.username,
                                      command=form.command,
                                      engine=engine)
        return json_response(token)
    return json_response(error=error)
Esempio n. 8
0
def next_run_time(request):
    form, error = JsonParser(Argument('rule', help='参数错误'),
                             Argument('start', required=False),
                             Argument('stop',
                                      required=False)).parse(request.body)
    if error is None:
        try:
            minute, hour, day, month, week = form.rule.split()
            week = Scheduler.week_map[week]
            trigger = CronTrigger(minute=minute,
                                  hour=hour,
                                  day=day,
                                  month=month,
                                  day_of_week=week,
                                  start_date=form.start,
                                  end_date=form.stop)
        except (ValueError, KeyError):
            return json_response({'success': False, 'msg': '无效的执行规则'})
        scheduler = BackgroundScheduler(timezone=settings.TIME_ZONE)
        scheduler.start()
        job = scheduler.add_job(lambda: None, trigger)
        run_time = job.next_run_time
        scheduler.shutdown()
        if run_time:
            return json_response({
                'success': True,
                'msg': run_time.strftime('%Y-%m-%d %H:%M:%S')
            })
        else:
            return json_response({'success': False, 'msg': '无法被触发'})
    return json_response(error=error)
Esempio n. 9
0
 def patch(self, request):
     form, error = JsonParser(
         Argument('s_id', type=int, help='参数错误'),
         Argument('d_id', type=int, help='参数错误'),
         Argument('action', type=int, help='参数错误')
     ).parse(request.body)
     if error is None:
         src = Group.objects.get(pk=form.s_id)
         dst = Group.objects.get(pk=form.d_id)
         if form.action == 0:
             src.parent_id = dst.id
             dst = Group.objects.filter(parent_id=dst.id).first()
             if not dst:
                 src.save()
                 return json_response()
             form.action = -1
         src.parent_id = dst.parent_id
         if src.sort_id > dst.sort_id:
             if form.action == -1:
                 dst = Group.objects.filter(sort_id__gt=dst.sort_id).last()
             Group.objects.filter(sort_id__lt=src.sort_id, sort_id__gte=dst.sort_id).update(sort_id=F('sort_id') + 1)
         else:
             if form.action == 1:
                 dst = Group.objects.filter(sort_id__lt=dst.sort_id).first()
             Group.objects.filter(sort_id__lte=dst.sort_id, sort_id__gt=src.sort_id).update(sort_id=F('sort_id') - 1)
         src.sort_id = dst.sort_id
         src.save()
     return json_response(error=error)
Esempio n. 10
0
 def patch(self, request):
     form, error = JsonParser(
         Argument('id', type=int, help='参数错误'),
         Argument('sort',
                  filter=lambda x: x in ('up', 'down'),
                  required=False),
         Argument('read', required=False)).parse(request.body)
     if error is None:
         notice = Notice.objects.filter(pk=form.id).first()
         if not notice:
             return json_response(error='未找到指定记录')
         if form.sort:
             if form.sort == 'up':
                 tmp = Notice.objects.filter(
                     sort_id__gt=notice.sort_id).last()
             else:
                 tmp = Notice.objects.filter(
                     sort_id__lt=notice.sort_id).first()
             if tmp:
                 tmp.sort_id, notice.sort_id = notice.sort_id, tmp.sort_id
                 tmp.save()
         if form.read:
             read_ids = json.loads(notice.read_ids)
             read_ids.append(str(request.user.id))
             notice.read_ids = json.dumps(read_ids)
         notice.save()
     return json_response(error=error)
Esempio n. 11
0
 def patch(self, request):
     form, error = JsonParser(
         Argument('id', type=int, help='缺少必要参数'),
         Argument('value', type=str, default=''),
         Argument('is_public', type=bool, help='缺少必要参数'),
         Argument('desc', required=False)
     ).parse(request.body)
     if error is None:
         form.value = form.value.strip()
         config = Config.objects.filter(pk=form.id).first()
         if not config:
             return json_response(error='未找到指定对象')
         config.desc = form.desc
         config.is_public = form.is_public
         if config.value != form.value:
             old_value = config.value
             config.value = form.value
             config.updated_at = human_datetime()
             config.updated_by = request.user
             ConfigHistory.objects.create(
                 action='2',
                 old_value=old_value,
                 **config.to_dict(excludes=('id',)))
         config.save()
     return json_response(error=error)
Esempio n. 12
0
 def put(self, request):
     form, error = JsonParser(
         Argument('id', type=int, help='缺少必要参数'),
         Argument('action',
                  filter=lambda x: x in ('check', 'do'),
                  help='参数错误')).parse(request.body)
     if error is None:
         req = DeployRequest.objects.filter(pk=form.id).first()
         if not req:
             return json_response(error='未找到指定发布申请')
         pre_req = DeployRequest.objects.filter(
             deploy_id=req.deploy_id,
             type='1',
             id__lt=req.id,
             version__isnull=False).first()
         if not pre_req:
             return json_response(error='未找到该应用可以用于回滚的版本')
         if form.action == 'check':
             return json_response({
                 'date': pre_req.created_at,
                 'name': pre_req.name
             })
         DeployRequest.objects.create(
             deploy_id=req.deploy_id,
             name=f'{req.name} - 回滚',
             type='2',
             extra=pre_req.extra,
             host_ids=req.host_ids,
             status='0' if pre_req.deploy.is_audit else '1',
             desc='自动回滚至该应用的上个版本',
             version=pre_req.version,
             created_by=request.user)
     return json_response(error=error)
Esempio n. 13
0
 def delete(self, request):
     form, error = JsonParser(
         Argument('id', type=int, required=False),
         Argument('group_id', type=int, required=False),
     ).parse(request.GET)
     if error is None:
         if form.id:
             host_ids = [form.id]
         elif form.group_id:
             group = Group.objects.get(pk=form.group_id)
             host_ids = [x.id for x in group.hosts.all()]
         else:
             return json_response(error='参数错误')
         for host_id in host_ids:
             regex = fr'[^0-9]{host_id}[^0-9]'
             deploy = Deploy.objects.filter(host_ids__regex=regex) \
                 .annotate(app_name=F('app__name'), env_name=F('env__name')).first()
             if deploy:
                 return json_response(error=f'应用【{deploy.app_name}】在【{deploy.env_name}】的发布配置关联了该主机,请解除关联后再尝试删除该主机')
             task = Task.objects.filter(targets__regex=fr'[^0-9]{form.id}[^0-9]').first()
             if task:
                 return json_response(error=f'任务计划中的任务【{task.name}】关联了该主机,请解除关联后再尝试删除该主机')
             detection = Detection.objects.filter(type__in=('3', '4'), targets__regex=regex).first()
             if detection:
                 return json_response(error=f'监控中心的任务【{detection.name}】关联了该主机,请解除关联后再尝试删除该主机')
         Host.objects.filter(id__in=host_ids).delete()
     return json_response(error=error)
Esempio n. 14
0
def post():
    form, error = JsonParser(
        Argument('title', help='Please enter the title'),
        Argument('count', type=int, filter=lambda x: x >= 0, help='Please enter the count')
    ).parse()
    if error is None:
        Blog(**form).save()
    return json_response(message=error)
Esempio n. 15
0
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)
Esempio n. 16
0
def run_test(request):
    form, error = JsonParser(Argument('type', help='请选择监控类型'),
                             Argument('addr', help='请输入监控地址'),
                             Argument('extra',
                                      required=False)).parse(request.body)
    if error is None:
        is_success, message = dispatch(form.type, form.addr, form.extra, True)
        return json_response({'is_success': is_success, 'message': message})
    return json_response(error=error)
Esempio n. 17
0
def run_test(request):
    form, error = JsonParser(
        Argument('type', help='请选择监控类型'),
        Argument('targets', type=list,
                 filter=lambda x: len(x), help='请输入监控地址'),
        Argument('extra', required=False)).parse(request.body)
    if error is None:
        is_success, message = dispatch(form.type, form.targets[0], form.extra)
        return json_response({'is_success': is_success, 'message': message})
    return json_response(error=error)
Esempio n. 18
0
File: views.py Progetto: 9233/spug
    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)
Esempio n. 19
0
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)
Esempio n. 20
0
 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:
             Role.objects.filter(pk=form.id).update(**form)
         else:
             Role.objects.create(created_by=request.user, **form)
     return json_response(error=error)
Esempio n. 21
0
 def delete(self, request):
     form, error = JsonParser(Argument('id', type=int, help='参数错误'),
                              Argument('file',
                                       help='请输入文件路径')).parse(request.GET)
     if error is None:
         host = Host.objects.get(pk=form.id)
         if not host:
             return json_response(error='未找到指定主机')
         cli = host.get_ssh()
         cli.remove_file(form.file)
     return json_response(error=error)
Esempio n. 22
0
 def get(self, request):
     form, error = JsonParser(Argument('id', type=int, help='参数错误'),
                              Argument('path',
                                       help='参数错误')).parse(request.GET)
     if error is None:
         host = Host.objects.get(pk=form.id)
         if not host:
             return json_response(error='未找到指定主机')
         cli = host.get_ssh()
         objects = cli.list_dir_attr(form.path)
         return json_response([parse_sftp_attr(x) for x in objects])
     return json_response(error=error)
Esempio n. 23
0
File: views.py Progetto: zzti/spug
 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)
Esempio n. 24
0
 def patch(self, request):
     form, error = JsonParser(
         Argument('id', type=int, required=False),
         Argument('zone', help='请输入主机类别')
     ).parse(request.body)
     if error is None:
         host = Host.objects.filter(pk=form.id).first()
         if not host:
             return json_response(error='未找到指定主机')
         count = Host.objects.filter(zone=host.zone, deleted_by_id__isnull=True).update(zone=form.zone)
         return json_response(count)
     return json_response(error=error)
Esempio n. 25
0
 def get(self, request):
     form, error = JsonParser(Argument('id', type=int, help='参数错误'),
                              Argument('path',
                                       help='参数错误')).parse(request.GET)
     if error is None:
         if not has_host_perm(request.user, form.id):
             return json_response(error='无权访问主机,请联系管理员')
         host = Host.objects.get(pk=form.id)
         if not host:
             return json_response(error='未找到指定主机')
         objects = fetch_dir_list(host, form.path)
         return json_response(objects)
     return json_response(error=error)
Esempio n. 26
0
 def patch(self, request):
     form, error = JsonParser(
         Argument('id', type=int, help='参数错误'),
         Argument('action', help='参数错误')
     ).parse(request.body)
     if error is None:
         rep = Repository.objects.filter(pk=form.id).first()
         if not rep:
             return json_response(error='未找到指定构建记录')
         if form.action == 'rebuild':
             Thread(target=dispatch, args=(rep,)).start()
             return json_response(rep.to_view())
     return json_response(error=error)
Esempio n. 27
0
 def delete(self, request):
     form, error = JsonParser(Argument('id', type=int, help='参数错误'),
                              Argument('file',
                                       help='请输入文件路径')).parse(request.GET)
     if error is None:
         if not has_host_perm(request.user, form.id):
             return json_response(error='无权访问主机,请联系管理员')
         host = Host.objects.get(pk=form.id)
         if not host:
             return json_response(error='未找到指定主机')
         with host.get_ssh() as ssh:
             ssh.remove_file(form.file)
     return json_response(error=error)
Esempio n. 28
0
 def post(self, request):
     form, error = JsonParser(
         Argument('id', type=int, required=False),
         Argument('name', help='请输入组名'),
         Argument('contacts', type=list, help='请选择联系人'),
         Argument('desc', required=False)).parse(request.body)
     if error is None:
         form.contacts = json.dumps(form.contacts)
         if form.id:
             Group.objects.filter(pk=form.id).update(**form)
         else:
             form.created_by = request.user
             Group.objects.create(**form)
     return json_response(error=error)
Esempio n. 29
0
 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)).parse(request.body)
     if error is None:
         app = App.objects.filter(pk=form.id).first()
         if not app:
             return json_response(error='未找到指定应用')
         app.rel_apps = json.dumps(form.rel_apps)
         app.rel_services = json.dumps(form.rel_services)
         app.save()
     return json_response(error=error)
Esempio n. 30
0
File: views.py Progetto: zzti/spug
 def post(self, request):
     form, error = JsonParser(
         Argument('id', type=int, required=False),
         Argument('type', help='请输入任务类型'),
         Argument('name', help='请输入任务名称'),
         Argument('command', help='请输入任务内容'),
         Argument('targets',
                  type=list,
                  filter=lambda x: len(x),
                  help='请选择执行对象'),
         Argument('trigger',
                  filter=lambda x: x in dict(Task.TRIGGERS),
                  help='请选择触发器类型'),
         Argument('trigger_args', help='请输入触发器参数'),
         Argument('desc', required=False),
     ).parse(request.body)
     if error is None:
         form.targets = json.dumps(form.targets)
         if form.id:
             Task.objects.filter(pk=form.id).update(
                 updated_at=human_datetime(),
                 updated_by=request.user,
                 **form)
             task = Task.objects.filter(pk=form.id).first()
             if task and task.is_active:
                 form.action = 'modify'
                 form.targets = json.loads(form.targets)
                 rds_cli = get_redis_connection()
                 rds_cli.lpush(settings.SCHEDULE_KEY, json.dumps(form))
         else:
             Task.objects.create(created_by=request.user, **form)
     return json_response(error=error)