Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix: 周期任务接口添加验证 --story=121224121 #7673

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions gcloud/apigw/views/modify_cron_for_periodic_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

from blueapps.account.decorators import login_exempt
from gcloud import err_code
from gcloud.utils.strings import inspect_time
from gcloud.conf import settings
from gcloud.apigw.decorators import mark_request_whether_is_trust, return_json_response
from gcloud.apigw.decorators import project_inject
from gcloud.periodictask.models import PeriodicTask
Expand All @@ -44,6 +46,12 @@ def modify_cron_for_periodic_task(request, task_id, project_id):
cron = params.get("cron", {})
tz = project.time_zone

if not inspect_time(cron, settings.PERIODIC_TASK_SHORTEST_TIME, settings.PERIODIC_TASK_ITERATION):
return {
"result": False,
"message": "The interval must be at least {} minutes".format(settings.PERIODIC_TASK_SHORTEST_TIME),
"code": err_code.REQUEST_PARAM_INVALID.code,
}
try:
task = PeriodicTask.objects.get(id=task_id, project_id=project.id)
except PeriodicTask.DoesNotExist:
Expand Down
1 change: 1 addition & 0 deletions gcloud/contrib/template_market/serializers.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class FileUploadAddrSerializer(serializers.Serializer):

class TemplateSharedRecordSerializer(serializers.Serializer):
project_code = serializers.CharField(required=True, max_length=32, help_text="项目id")
project_name = serializers.CharField(required=True, help_text="项目名称")
templates = serializers.ListField(required=True, help_text="关联的模板列表")
name = serializers.CharField(required=True, help_text="共享名称")
category = serializers.CharField(required=True, help_text="共享分类")
Expand Down
12 changes: 3 additions & 9 deletions gcloud/core/apis/drf/serilaziers/periodic_task.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,22 +158,15 @@ class CronFieldSerializer(serializers.Serializer):
cron = serializers.DictField(write_only=True)

def inspect_cron(self, cron):
minute = cron.get("minute", "*")
hour = cron.get("hour", "*")
day_of_month = cron.get("day_of_month", "*")
month = cron.get("month", "*")
day_of_week = cron.get("day_of_week", "*")

cron_expression = f"{minute} {hour} {day_of_month} {month} {day_of_week}"

result = inspect_time(cron_expression, settings.PERIODIC_TASK_SHORTEST_TIME, settings.PERIODIC_TASK_ITERATION)
result = inspect_time(cron, settings.PERIODIC_TASK_SHORTEST_TIME, settings.PERIODIC_TASK_ITERATION)
if not result:
raise serializers.ValidationError(
"The interval between tasks should be at least {} minutes".format(settings.PERIODIC_TASK_SHORTEST_TIME)
)


class CreatePeriodicTaskSerializer(CronFieldSerializer, serializers.ModelSerializer):
id = serializers.IntegerField(required=False)
project = serializers.IntegerField(write_only=True)
template_source = serializers.CharField(required=False, default=PROJECT)
pipeline_tree = ReadWriteSerializerMethodField()
Expand Down Expand Up @@ -220,6 +213,7 @@ def validate(self, attrs):
class Meta:
model = PeriodicTask
fields = [
"id",
"project",
"cron",
"name",
Expand Down
8 changes: 4 additions & 4 deletions gcloud/tests/utils/strings/test_inspect_time.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,25 +17,25 @@

class InspectTimeTestCase(TestCase):
def test_inspect_time(self):
cron = "* * * * *"
cron = {"minute": "*", "hour": "*", "day_of_month": "*", "month": "*", "day_of_week": "*"}
shortest_time = 30
iter_count = 10
self.assertFalse(inspect_time(cron=cron, shortest_time=shortest_time, iter_count=iter_count))

def test_fail_inspect_time(self):
cron = "*/15 * * * *"
cron = {"minute": "*/15", "hour": "*", "day_of_month": "*", "month": "*", "day_of_week": "*"}
shortest_time = 30
iter_count = 10
self.assertFalse(inspect_time(cron=cron, shortest_time=shortest_time, iter_count=iter_count))

def test_success_inspect_time(self):
cron = "15 2 * * *"
cron = {"minute": "15", "hour": "2", "day_of_month": "*", "month": "*", "day_of_week": "*"}
shortest_time = 30
iter_count = 10
self.assertTrue(inspect_time(cron=cron, shortest_time=shortest_time, iter_count=iter_count))

def test_iter_count_inspect_time(self):
cron = "*/15 * * * *"
cron = {"minute": "*/15", "hour": "*", "day_of_month": "*", "month": "*", "day_of_week": "*"}
shortest_time = 30
iter_count = 100
self.assertFalse(inspect_time(cron=cron, shortest_time=shortest_time, iter_count=iter_count))
11 changes: 9 additions & 2 deletions gcloud/utils/strings.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,14 +122,21 @@ def django_celery_beat_cron_time_format_fit(cron_str):
def inspect_time(cron, shortest_time, iter_count):
"""检查定时任务时间间隔是否符合要求
:param cron: 定时任务配置
:type cron str
:type cron dict
:param shortest_time: 最短时间间隔,以分钟为单位,例如 30
:type shortest_time int
:param iter_count: 迭代次数
:type iter_count int
"""
minute = cron.get("minute", "*")
hour = cron.get("hour", "*")
day_of_month = cron.get("day_of_month", "*")
month = cron.get("month", "*")
day_of_week = cron.get("day_of_week", "*")

schedule_iter = croniter(cron)
cron_expression = f"{minute} {hour} {day_of_month} {month} {day_of_week}"

schedule_iter = croniter(cron_expression)
# 计算指定次数内的最短时间间隔
next_times = [schedule_iter.get_next(datetime) for _ in range(iter_count)]
min_interval = min((next_times[i] - next_times[i - 1] for i in range(1, len(next_times))))
Expand Down
Loading