mirror of
https://github.com/ansible/awx.git
synced 2026-05-21 15:57:52 -02:30
Feature: saved launchtime configurations
Consolidate prompts accept/reject logic in unified models Break out accept/reject logic for variables Surface new promptable fields on WFJT nodes, schedules Make schedules and workflows accurately reject variables that are not allowed by the prompting rules or the survey rules on the template Validate against unallowed extra_data in system job schedules Prevent schedule or WFJT node POST/PATCH with unprompted data Move system job days validation to new mechanism Add new psuedo-field for WFJT node credential Add validation for node related credentials Add related config model to unified job Use JobLaunchConfig model for launch RBAC check Support credential overwrite behavior with multi-creds change modern manual launch to use merge behavior Refactor JobLaunchSerializer, self.instance=None Modularize job launch view to create "modern" data Auto-create config object with every job Add create schedule endpoint for jobs
This commit is contained in:
@@ -5,21 +5,19 @@ import re
|
||||
import logging
|
||||
import datetime
|
||||
import dateutil.rrule
|
||||
import json
|
||||
|
||||
# Django
|
||||
from django.db import models
|
||||
from django.db.models.query import QuerySet
|
||||
from django.utils.timezone import now, make_aware, get_default_timezone
|
||||
from django.utils.translation import ugettext_lazy as _
|
||||
from django.core.exceptions import ValidationError
|
||||
|
||||
# AWX
|
||||
from awx.api.versioning import reverse
|
||||
from awx.main.models.base import * # noqa
|
||||
from awx.main.models.jobs import LaunchTimeConfig
|
||||
from awx.main.utils import ignore_inventory_computed_fields
|
||||
from awx.main.consumers import emit_channel_notification
|
||||
from awx.main.fields import JSONField
|
||||
|
||||
logger = logging.getLogger('awx.main.models.schedule')
|
||||
|
||||
@@ -53,7 +51,7 @@ class ScheduleManager(ScheduleFilterMethods, models.Manager):
|
||||
return ScheduleQuerySet(self.model, using=self._db)
|
||||
|
||||
|
||||
class Schedule(CommonModel):
|
||||
class Schedule(CommonModel, LaunchTimeConfig):
|
||||
|
||||
class Meta:
|
||||
app_label = 'main'
|
||||
@@ -92,44 +90,6 @@ class Schedule(CommonModel):
|
||||
editable=False,
|
||||
help_text=_("The next time that the scheduled action will run.")
|
||||
)
|
||||
extra_data = JSONField(
|
||||
blank=True,
|
||||
default={}
|
||||
)
|
||||
|
||||
# extra_data is actually a string with a JSON payload in it. This
|
||||
# is technically OK because a string is a valid JSON. One day we will
|
||||
# enforce non-string JSON.
|
||||
def _clean_extra_data_system_jobs(self):
|
||||
extra_data = self.extra_data
|
||||
if not isinstance(extra_data, dict):
|
||||
try:
|
||||
extra_data = json.loads(self.extra_data)
|
||||
except Exception:
|
||||
raise ValidationError(_("Expected JSON"))
|
||||
|
||||
if extra_data and 'days' in extra_data:
|
||||
try:
|
||||
if type(extra_data['days']) is bool:
|
||||
raise ValueError
|
||||
if float(extra_data['days']) != int(extra_data['days']):
|
||||
raise ValueError
|
||||
days = int(extra_data['days'])
|
||||
if days < 0:
|
||||
raise ValueError
|
||||
except ValueError:
|
||||
raise ValidationError(_("days must be a positive integer."))
|
||||
return self.extra_data
|
||||
|
||||
def clean_extra_data(self):
|
||||
if not self.unified_job_template:
|
||||
return self.extra_data
|
||||
|
||||
# Compare class by string name because it's hard to import SystemJobTemplate
|
||||
if type(self.unified_job_template).__name__ is not 'SystemJobTemplate':
|
||||
return self.extra_data
|
||||
|
||||
return self._clean_extra_data_system_jobs()
|
||||
|
||||
def __unicode__(self):
|
||||
return u'%s_t%s_%s_%s' % (self.name, self.unified_job_template.id, self.id, self.next_run)
|
||||
@@ -137,6 +97,13 @@ class Schedule(CommonModel):
|
||||
def get_absolute_url(self, request=None):
|
||||
return reverse('api:schedule_detail', kwargs={'pk': self.pk}, request=request)
|
||||
|
||||
def get_job_kwargs(self):
|
||||
config_data = self.prompts_dict()
|
||||
prompts, rejected, errors = self.unified_job_template._accept_or_ignore_job_kwargs(**config_data)
|
||||
if errors:
|
||||
logger.info('Errors creating scheduled job: {}'.format(errors))
|
||||
return prompts
|
||||
|
||||
def update_computed_fields(self):
|
||||
future_rs = dateutil.rrule.rrulestr(self.rrule, forceset=True)
|
||||
next_run_actual = future_rs.after(now())
|
||||
|
||||
Reference in New Issue
Block a user