mirror of
https://github.com/ansible/awx.git
synced 2026-03-01 00:38:45 -03:30
Replace all usage of customized json fields with the Django builtin
The event_data field on event models, however, is getting an overridden version that retains the underlying text data type for the column, to avoid a heavy data migration on those tables. Also, certain of the larger tables are getting these fields with the NOT NULL constraint turned off, to avoid a long migration. Remove the django.utils.six monkey patch we did at the beginning of the upgrade.
This commit is contained in:
@@ -6,8 +6,6 @@ import os
|
|||||||
import sys
|
import sys
|
||||||
import warnings
|
import warnings
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from pkg_resources import get_distribution
|
from pkg_resources import get_distribution
|
||||||
|
|
||||||
__version__ = get_distribution('awx').version
|
__version__ = get_distribution('awx').version
|
||||||
@@ -37,9 +35,6 @@ else:
|
|||||||
from django.db.models import indexes
|
from django.db.models import indexes
|
||||||
from django.db.backends.utils import names_digest
|
from django.db.backends.utils import names_digest
|
||||||
from django.db import connection
|
from django.db import connection
|
||||||
from django import utils
|
|
||||||
|
|
||||||
utils.six = six # FIXME: monkey patch to get us through for now
|
|
||||||
|
|
||||||
if HAS_DJANGO is True:
|
if HAS_DJANGO is True:
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from uuid import UUID
|
|||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.core.exceptions import PermissionDenied
|
from django.core.exceptions import PermissionDenied
|
||||||
|
from django.db.models import JSONField
|
||||||
from django.db.models.fields import PositiveIntegerField, BooleanField
|
from django.db.models.fields import PositiveIntegerField, BooleanField
|
||||||
from django.db.models.fields.related import ForeignKey
|
from django.db.models.fields.related import ForeignKey
|
||||||
from django.http import Http404
|
from django.http import Http404
|
||||||
@@ -22,7 +23,7 @@ from rest_framework.request import clone_request
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.api.fields import ChoiceNullField
|
from awx.api.fields import ChoiceNullField
|
||||||
from awx.main.fields import JSONField, ImplicitRoleField
|
from awx.main.fields import ImplicitRoleField
|
||||||
from awx.main.models import NotificationTemplate
|
from awx.main.models import NotificationTemplate
|
||||||
from awx.main.utils.execution_environments import get_default_pod_spec
|
from awx.main.utils.execution_environments import get_default_pod_spec
|
||||||
|
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ from awx.main.models import (
|
|||||||
)
|
)
|
||||||
from awx.main.models.base import VERBOSITY_CHOICES, NEW_JOB_TYPE_CHOICES
|
from awx.main.models.base import VERBOSITY_CHOICES, NEW_JOB_TYPE_CHOICES
|
||||||
from awx.main.models.rbac import get_roles_on_resource, role_summary_fields_generator
|
from awx.main.models.rbac import get_roles_on_resource, role_summary_fields_generator
|
||||||
from awx.main.fields import ImplicitRoleField, JSONBField
|
from awx.main.fields import ImplicitRoleField
|
||||||
from awx.main.utils import (
|
from awx.main.utils import (
|
||||||
get_type_for_model,
|
get_type_for_model,
|
||||||
get_model_for_type,
|
get_model_for_type,
|
||||||
@@ -1718,7 +1718,7 @@ class InventorySerializer(LabelsListMixin, BaseSerializerWithVariables):
|
|||||||
def validate_host_filter(self, host_filter):
|
def validate_host_filter(self, host_filter):
|
||||||
if host_filter:
|
if host_filter:
|
||||||
try:
|
try:
|
||||||
for match in JSONBField.get_lookups().keys():
|
for match in models.JSONField.get_lookups().keys():
|
||||||
if match == 'exact':
|
if match == 'exact':
|
||||||
# __exact is allowed
|
# __exact is allowed
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import jsonfield.fields
|
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
|
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ class Migration(migrations.Migration):
|
|||||||
('created', models.DateTimeField(default=None, editable=False)),
|
('created', models.DateTimeField(default=None, editable=False)),
|
||||||
('modified', models.DateTimeField(default=None, editable=False)),
|
('modified', models.DateTimeField(default=None, editable=False)),
|
||||||
('key', models.CharField(max_length=255)),
|
('key', models.CharField(max_length=255)),
|
||||||
('value', jsonfield.fields.JSONField(null=True)),
|
('value', models.JSONField(null=True)),
|
||||||
(
|
(
|
||||||
'user',
|
'user',
|
||||||
models.ForeignKey(related_name='settings', default=None, editable=False, to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True),
|
models.ForeignKey(related_name='settings', default=None, editable=False, to=settings.AUTH_USER_MODEL, on_delete=models.CASCADE, null=True),
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations, models
|
||||||
import awx.main.fields
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
dependencies = [('conf', '0002_v310_copy_tower_settings')]
|
dependencies = [('conf', '0002_v310_copy_tower_settings')]
|
||||||
|
|
||||||
operations = [migrations.AlterField(model_name='setting', name='value', field=awx.main.fields.JSONField(null=True))]
|
operations = [migrations.AlterField(model_name='setting', name='value', field=models.JSONField(null=True))]
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ from django.db import models
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.models.base import CreatedModifiedModel, prevent_search
|
from awx.main.models.base import CreatedModifiedModel, prevent_search
|
||||||
from awx.main.fields import JSONField
|
|
||||||
from awx.main.utils import encrypt_field
|
from awx.main.utils import encrypt_field
|
||||||
from awx.conf import settings_registry
|
from awx.conf import settings_registry
|
||||||
|
|
||||||
@@ -19,7 +18,7 @@ __all__ = ['Setting']
|
|||||||
class Setting(CreatedModifiedModel):
|
class Setting(CreatedModifiedModel):
|
||||||
|
|
||||||
key = models.CharField(max_length=255)
|
key = models.CharField(max_length=255)
|
||||||
value = JSONField(null=True)
|
value = models.JSONField(null=True)
|
||||||
user = prevent_search(models.ForeignKey('auth.User', related_name='settings', default=None, null=True, editable=False, on_delete=models.CASCADE))
|
user = prevent_search(models.ForeignKey('auth.User', related_name='settings', default=None, null=True, editable=False, on_delete=models.CASCADE))
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ from jinja2 import sandbox, StrictUndefined
|
|||||||
from jinja2.exceptions import UndefinedError, TemplateSyntaxError, SecurityError
|
from jinja2.exceptions import UndefinedError, TemplateSyntaxError, SecurityError
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.contrib.postgres.fields import JSONField as upstream_JSONBField
|
|
||||||
from django.core import exceptions as django_exceptions
|
from django.core import exceptions as django_exceptions
|
||||||
from django.core.serializers.json import DjangoJSONEncoder
|
from django.core.serializers.json import DjangoJSONEncoder
|
||||||
from django.db.models.signals import (
|
from django.db.models.signals import (
|
||||||
@@ -29,6 +28,7 @@ from django.db.models.fields.related_descriptors import (
|
|||||||
create_forward_many_to_many_manager,
|
create_forward_many_to_many_manager,
|
||||||
)
|
)
|
||||||
from django.utils.encoding import smart_str
|
from django.utils.encoding import smart_str
|
||||||
|
from django.db.models import JSONField
|
||||||
from django.utils.functional import cached_property
|
from django.utils.functional import cached_property
|
||||||
from django.utils.translation import gettext_lazy as _
|
from django.utils.translation import gettext_lazy as _
|
||||||
|
|
||||||
@@ -36,9 +36,6 @@ from django.utils.translation import gettext_lazy as _
|
|||||||
from jsonschema import Draft4Validator, FormatChecker
|
from jsonschema import Draft4Validator, FormatChecker
|
||||||
import jsonschema.exceptions
|
import jsonschema.exceptions
|
||||||
|
|
||||||
# Django-JSONField
|
|
||||||
from jsonfield import JSONField as upstream_JSONField
|
|
||||||
|
|
||||||
# DRF
|
# DRF
|
||||||
from rest_framework import serializers
|
from rest_framework import serializers
|
||||||
|
|
||||||
@@ -52,9 +49,9 @@ from awx.main import utils
|
|||||||
|
|
||||||
|
|
||||||
__all__ = [
|
__all__ = [
|
||||||
|
'JSONBlob',
|
||||||
'AutoOneToOneField',
|
'AutoOneToOneField',
|
||||||
'ImplicitRoleField',
|
'ImplicitRoleField',
|
||||||
'JSONField',
|
|
||||||
'SmartFilterField',
|
'SmartFilterField',
|
||||||
'OrderedManyToManyField',
|
'OrderedManyToManyField',
|
||||||
'update_role_parentage_for_instance',
|
'update_role_parentage_for_instance',
|
||||||
@@ -71,40 +68,9 @@ def __enum_validate__(validator, enums, instance, schema):
|
|||||||
Draft4Validator.VALIDATORS['enum'] = __enum_validate__
|
Draft4Validator.VALIDATORS['enum'] = __enum_validate__
|
||||||
|
|
||||||
|
|
||||||
class JSONField(upstream_JSONField):
|
class JSONBlob(JSONField):
|
||||||
def __init__(self, *args, **kwargs):
|
def get_internal_type(self):
|
||||||
super().__init__(*args, **kwargs)
|
return "TextField"
|
||||||
self.decoder_kwargs = {'cls': json.JSONDecoder} # FIXME
|
|
||||||
|
|
||||||
def db_type(self, connection):
|
|
||||||
return 'text'
|
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection):
|
|
||||||
if value in {'', None} and not self.null:
|
|
||||||
return {}
|
|
||||||
return super(JSONField, self).from_db_value(value, expression, connection)
|
|
||||||
|
|
||||||
|
|
||||||
class JSONBField(upstream_JSONBField):
|
|
||||||
def get_prep_lookup(self, lookup_type, value):
|
|
||||||
if isinstance(value, str) and value == "null":
|
|
||||||
return 'null'
|
|
||||||
return super(JSONBField, self).get_prep_lookup(lookup_type, value)
|
|
||||||
|
|
||||||
def get_db_prep_value(self, value, connection, prepared=False):
|
|
||||||
if connection.vendor == 'sqlite':
|
|
||||||
# sqlite (which we use for tests) does not support jsonb;
|
|
||||||
if hasattr(value, 'adapted'):
|
|
||||||
value = value.adapted # FIXME: Django 3.0 uses JsonAdapter, removed in 3.1
|
|
||||||
return json.dumps(value, cls=DjangoJSONEncoder)
|
|
||||||
return super(JSONBField, self).get_db_prep_value(value, connection, prepared)
|
|
||||||
|
|
||||||
def from_db_value(self, value, expression, connection):
|
|
||||||
# Work around a bug in django-jsonfield
|
|
||||||
# https://bitbucket.org/schinckel/django-jsonfield/issues/57/cannot-use-in-the-same-project-as-djangos
|
|
||||||
if isinstance(value, str):
|
|
||||||
return json.loads(value)
|
|
||||||
return value
|
|
||||||
|
|
||||||
|
|
||||||
# Based on AutoOneToOneField from django-annoying:
|
# Based on AutoOneToOneField from django-annoying:
|
||||||
@@ -391,7 +357,7 @@ class SmartFilterField(models.TextField):
|
|||||||
return super(SmartFilterField, self).get_prep_value(value)
|
return super(SmartFilterField, self).get_prep_value(value)
|
||||||
|
|
||||||
|
|
||||||
class JSONSchemaField(JSONBField):
|
class JSONSchemaField(models.JSONField):
|
||||||
"""
|
"""
|
||||||
A JSONB field that self-validates against a defined JSON schema
|
A JSONB field that self-validates against a defined JSON schema
|
||||||
(http://json-schema.org). This base class is intended to be overwritten by
|
(http://json-schema.org). This base class is intended to be overwritten by
|
||||||
@@ -404,8 +370,13 @@ class JSONSchemaField(JSONBField):
|
|||||||
# validation
|
# validation
|
||||||
empty_values = (None, '')
|
empty_values = (None, '')
|
||||||
|
|
||||||
|
def __init__(self, encoder=None, decoder=None, **options):
|
||||||
|
if encoder is None:
|
||||||
|
encoder = DjangoJSONEncoder
|
||||||
|
super().__init__(encoder=encoder, decoder=decoder, **options)
|
||||||
|
|
||||||
def get_default(self):
|
def get_default(self):
|
||||||
return copy.deepcopy(super(JSONBField, self).get_default())
|
return copy.deepcopy(super(models.JSONField, self).get_default())
|
||||||
|
|
||||||
def schema(self, model_instance):
|
def schema(self, model_instance):
|
||||||
raise NotImplementedError()
|
raise NotImplementedError()
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.utils.timezone
|
import django.utils.timezone
|
||||||
import jsonfield.fields
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
import taggit.managers
|
import taggit.managers
|
||||||
@@ -70,7 +69,7 @@ class Migration(migrations.Migration):
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
('event_data', jsonfield.fields.JSONField(default=dict, blank=True)),
|
('event_data', awx.main.fields.JSONBlob(default=dict, blank=True)),
|
||||||
('failed', models.BooleanField(default=False, editable=False)),
|
('failed', models.BooleanField(default=False, editable=False)),
|
||||||
('changed', models.BooleanField(default=False, editable=False)),
|
('changed', models.BooleanField(default=False, editable=False)),
|
||||||
('counter', models.PositiveIntegerField(default=0)),
|
('counter', models.PositiveIntegerField(default=0)),
|
||||||
@@ -433,7 +432,7 @@ class Migration(migrations.Migration):
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
('event_data', jsonfield.fields.JSONField(default=dict, blank=True)),
|
('event_data', awx.main.fields.JSONBlob(default=dict, blank=True)),
|
||||||
('failed', models.BooleanField(default=False, editable=False)),
|
('failed', models.BooleanField(default=False, editable=False)),
|
||||||
('changed', models.BooleanField(default=False, editable=False)),
|
('changed', models.BooleanField(default=False, editable=False)),
|
||||||
('host_name', models.CharField(default='', max_length=1024, editable=False)),
|
('host_name', models.CharField(default='', max_length=1024, editable=False)),
|
||||||
@@ -623,7 +622,7 @@ class Migration(migrations.Migration):
|
|||||||
('dtend', models.DateTimeField(default=None, null=True, editable=False)),
|
('dtend', models.DateTimeField(default=None, null=True, editable=False)),
|
||||||
('rrule', models.CharField(max_length=255)),
|
('rrule', models.CharField(max_length=255)),
|
||||||
('next_run', models.DateTimeField(default=None, null=True, editable=False)),
|
('next_run', models.DateTimeField(default=None, null=True, editable=False)),
|
||||||
('extra_data', jsonfield.fields.JSONField(default=dict, blank=True)),
|
('extra_data', models.JSONField(default=dict, null=True, blank=True)),
|
||||||
(
|
(
|
||||||
'created_by',
|
'created_by',
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
@@ -751,7 +750,7 @@ class Migration(migrations.Migration):
|
|||||||
('elapsed', models.DecimalField(editable=False, max_digits=12, decimal_places=3)),
|
('elapsed', models.DecimalField(editable=False, max_digits=12, decimal_places=3)),
|
||||||
('job_args', models.TextField(default='', editable=False, blank=True)),
|
('job_args', models.TextField(default='', editable=False, blank=True)),
|
||||||
('job_cwd', models.CharField(default='', max_length=1024, editable=False, blank=True)),
|
('job_cwd', models.CharField(default='', max_length=1024, editable=False, blank=True)),
|
||||||
('job_env', jsonfield.fields.JSONField(default=dict, editable=False, blank=True)),
|
('job_env', models.JSONField(default=dict, editable=False, null=True, blank=True)),
|
||||||
('job_explanation', models.TextField(default='', editable=False, blank=True)),
|
('job_explanation', models.TextField(default='', editable=False, blank=True)),
|
||||||
('start_args', models.TextField(default='', editable=False, blank=True)),
|
('start_args', models.TextField(default='', editable=False, blank=True)),
|
||||||
('result_stdout_text', models.TextField(default='', editable=False, blank=True)),
|
('result_stdout_text', models.TextField(default='', editable=False, blank=True)),
|
||||||
@@ -1035,7 +1034,7 @@ class Migration(migrations.Migration):
|
|||||||
('host_config_key', models.CharField(default='', max_length=1024, blank=True)),
|
('host_config_key', models.CharField(default='', max_length=1024, blank=True)),
|
||||||
('ask_variables_on_launch', models.BooleanField(default=False)),
|
('ask_variables_on_launch', models.BooleanField(default=False)),
|
||||||
('survey_enabled', models.BooleanField(default=False)),
|
('survey_enabled', models.BooleanField(default=False)),
|
||||||
('survey_spec', jsonfield.fields.JSONField(default=dict, blank=True)),
|
('survey_spec', models.JSONField(default=dict, blank=True)),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ('name',),
|
'ordering': ('name',),
|
||||||
|
|||||||
@@ -12,7 +12,6 @@ import django.db.models.deletion
|
|||||||
from django.conf import settings
|
from django.conf import settings
|
||||||
from django.utils.timezone import now
|
from django.utils.timezone import now
|
||||||
|
|
||||||
import jsonfield.fields
|
|
||||||
import taggit.managers
|
import taggit.managers
|
||||||
|
|
||||||
|
|
||||||
@@ -199,7 +198,7 @@ class Migration(migrations.Migration):
|
|||||||
),
|
),
|
||||||
('recipients', models.TextField(default='', editable=False, blank=True)),
|
('recipients', models.TextField(default='', editable=False, blank=True)),
|
||||||
('subject', models.TextField(default='', editable=False, blank=True)),
|
('subject', models.TextField(default='', editable=False, blank=True)),
|
||||||
('body', jsonfield.fields.JSONField(default=dict, blank=True)),
|
('body', models.JSONField(default=dict, null=True, blank=True)),
|
||||||
],
|
],
|
||||||
options={
|
options={
|
||||||
'ordering': ('pk',),
|
'ordering': ('pk',),
|
||||||
@@ -230,7 +229,7 @@ class Migration(migrations.Migration):
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
('notification_configuration', jsonfield.fields.JSONField(default=dict)),
|
('notification_configuration', models.JSONField(default=dict)),
|
||||||
(
|
(
|
||||||
'created_by',
|
'created_by',
|
||||||
models.ForeignKey(
|
models.ForeignKey(
|
||||||
@@ -324,9 +323,7 @@ class Migration(migrations.Migration):
|
|||||||
('module', models.CharField(max_length=128)),
|
('module', models.CharField(max_length=128)),
|
||||||
(
|
(
|
||||||
'facts',
|
'facts',
|
||||||
awx.main.fields.JSONBField(
|
models.JSONField(default=dict, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True),
|
||||||
default=dict, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
(
|
(
|
||||||
'host',
|
'host',
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import awx.main.models.notifications
|
import awx.main.models.notifications
|
||||||
import jsonfield.fields
|
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
import awx.main.models.workflow
|
import awx.main.models.workflow
|
||||||
import awx.main.fields
|
import awx.main.fields
|
||||||
@@ -221,7 +220,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
name='char_prompts',
|
name='char_prompts',
|
||||||
field=jsonfield.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
@@ -260,7 +259,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplatenode',
|
model_name='workflowjobtemplatenode',
|
||||||
name='char_prompts',
|
name='char_prompts',
|
||||||
field=jsonfield.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplatenode',
|
model_name='workflowjobtemplatenode',
|
||||||
@@ -308,12 +307,12 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='job',
|
model_name='job',
|
||||||
name='artifacts',
|
name='artifacts',
|
||||||
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
name='ancestor_artifacts',
|
name='ancestor_artifacts',
|
||||||
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
# Job timeout settings
|
# Job timeout settings
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
@@ -381,9 +380,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='project',
|
model_name='project',
|
||||||
name='playbook_files',
|
name='playbook_files',
|
||||||
field=jsonfield.fields.JSONField(
|
field=models.JSONField(default=list, help_text='List of playbooks found in the project', verbose_name='Playbook Files', editable=False, blank=True),
|
||||||
default=[], help_text='List of playbooks found in the project', verbose_name='Playbook Files', editable=False, blank=True
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
# Job events to stdout
|
# Job events to stdout
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
@@ -539,7 +536,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjob',
|
model_name='workflowjob',
|
||||||
name='survey_passwords',
|
name='survey_passwords',
|
||||||
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplate',
|
model_name='workflowjobtemplate',
|
||||||
@@ -549,85 +546,83 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplate',
|
model_name='workflowjobtemplate',
|
||||||
name='survey_spec',
|
name='survey_spec',
|
||||||
field=jsonfield.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, blank=True),
|
||||||
),
|
),
|
||||||
# JSON field changes
|
# JSON field changes
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='adhoccommandevent',
|
model_name='adhoccommandevent',
|
||||||
name='event_data',
|
name='event_data',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=awx.main.fields.JSONBlob(default=dict, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='job',
|
model_name='job',
|
||||||
name='artifacts',
|
name='artifacts',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='job',
|
model_name='job',
|
||||||
name='survey_passwords',
|
name='survey_passwords',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='jobevent',
|
model_name='jobevent',
|
||||||
name='event_data',
|
name='event_data',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=awx.main.fields.JSONBlob(default=dict, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='jobtemplate',
|
model_name='jobtemplate',
|
||||||
name='survey_spec',
|
name='survey_spec',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='notification',
|
model_name='notification',
|
||||||
name='body',
|
name='body',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='notificationtemplate',
|
model_name='notificationtemplate',
|
||||||
name='notification_configuration',
|
name='notification_configuration',
|
||||||
field=awx.main.fields.JSONField(default=dict),
|
field=models.JSONField(default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='project',
|
model_name='project',
|
||||||
name='playbook_files',
|
name='playbook_files',
|
||||||
field=awx.main.fields.JSONField(
|
field=models.JSONField(default=list, help_text='List of playbooks found in the project', verbose_name='Playbook Files', editable=False, blank=True),
|
||||||
default=[], help_text='List of playbooks found in the project', verbose_name='Playbook Files', editable=False, blank=True
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='schedule',
|
model_name='schedule',
|
||||||
name='extra_data',
|
name='extra_data',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='unifiedjob',
|
model_name='unifiedjob',
|
||||||
name='job_env',
|
name='job_env',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='workflowjob',
|
model_name='workflowjob',
|
||||||
name='survey_passwords',
|
name='survey_passwords',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
name='ancestor_artifacts',
|
name='ancestor_artifacts',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
name='char_prompts',
|
name='char_prompts',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='workflowjobtemplate',
|
model_name='workflowjobtemplate',
|
||||||
name='survey_spec',
|
name='survey_spec',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='workflowjobtemplatenode',
|
model_name='workflowjobtemplatenode',
|
||||||
name='char_prompts',
|
name='char_prompts',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
# Job Project Update
|
# Job Project Update
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
|
|||||||
@@ -108,14 +108,12 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='fact',
|
model_name='fact',
|
||||||
name='facts',
|
name='facts',
|
||||||
field=awx.main.fields.JSONBField(
|
field=models.JSONField(default=dict, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True),
|
||||||
default=dict, help_text='Arbitrary JSON structure of module facts captured at timestamp for a single host.', blank=True
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='host',
|
model_name='host',
|
||||||
name='ansible_facts',
|
name='ansible_facts',
|
||||||
field=awx.main.fields.JSONBField(default=dict, help_text='Arbitrary JSON structure of most recent ansible_facts, per-host.', blank=True),
|
field=models.JSONField(default=dict, help_text='Arbitrary JSON structure of most recent ansible_facts, per-host.', blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='host',
|
model_name='host',
|
||||||
@@ -177,8 +175,8 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='project',
|
model_name='project',
|
||||||
name='inventory_files',
|
name='inventory_files',
|
||||||
field=awx.main.fields.JSONField(
|
field=models.JSONField(
|
||||||
default=[],
|
default=list,
|
||||||
help_text='Suggested list of content that could be Ansible inventory in the project',
|
help_text='Suggested list of content that could be Ansible inventory in the project',
|
||||||
verbose_name='Inventory Files',
|
verbose_name='Inventory Files',
|
||||||
editable=False,
|
editable=False,
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
from django.db import migrations
|
from django.db import migrations, models
|
||||||
import awx.main.fields
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@@ -15,6 +14,6 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='activitystream',
|
model_name='activitystream',
|
||||||
name='setting',
|
name='setting',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='schedule',
|
model_name='schedule',
|
||||||
name='char_prompts',
|
name='char_prompts',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='schedule',
|
model_name='schedule',
|
||||||
@@ -37,7 +37,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='schedule',
|
model_name='schedule',
|
||||||
name='survey_passwords',
|
name='survey_passwords',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
@@ -47,12 +47,12 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
name='extra_data',
|
name='extra_data',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobnode',
|
model_name='workflowjobnode',
|
||||||
name='survey_passwords',
|
name='survey_passwords',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplatenode',
|
model_name='workflowjobtemplatenode',
|
||||||
@@ -62,12 +62,12 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplatenode',
|
model_name='workflowjobtemplatenode',
|
||||||
name='extra_data',
|
name='extra_data',
|
||||||
field=awx.main.fields.JSONField(default=dict, blank=True),
|
field=models.JSONField(default=dict, null=True, blank=True),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplatenode',
|
model_name='workflowjobtemplatenode',
|
||||||
name='survey_passwords',
|
name='survey_passwords',
|
||||||
field=awx.main.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
# Run data migration before removing the old credential field
|
# Run data migration before removing the old credential field
|
||||||
migrations.RunPython(migration_utils.set_current_apps_for_migrations, migrations.RunPython.noop),
|
migrations.RunPython(migration_utils.set_current_apps_for_migrations, migrations.RunPython.noop),
|
||||||
@@ -85,9 +85,9 @@ class Migration(migrations.Migration):
|
|||||||
name='JobLaunchConfig',
|
name='JobLaunchConfig',
|
||||||
fields=[
|
fields=[
|
||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('extra_data', awx.main.fields.JSONField(blank=True, default=dict)),
|
('extra_data', models.JSONField(blank=True, null=True, default=dict)),
|
||||||
('survey_passwords', awx.main.fields.JSONField(blank=True, default=dict, editable=False)),
|
('survey_passwords', models.JSONField(blank=True, null=True, default=dict, editable=False)),
|
||||||
('char_prompts', awx.main.fields.JSONField(blank=True, default=dict)),
|
('char_prompts', models.JSONField(blank=True, null=True, default=dict)),
|
||||||
('credentials', models.ManyToManyField(related_name='joblaunchconfigs', to='main.Credential')),
|
('credentials', models.ManyToManyField(related_name='joblaunchconfigs', to='main.Credential')),
|
||||||
(
|
(
|
||||||
'inventory',
|
'inventory',
|
||||||
|
|||||||
@@ -2,10 +2,11 @@
|
|||||||
# Generated by Django 1.11.7 on 2017-12-14 15:13
|
# Generated by Django 1.11.7 on 2017-12-14 15:13
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import awx.main.fields
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
import django.db.models.deletion
|
import django.db.models.deletion
|
||||||
|
|
||||||
|
import awx.main.fields
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
|
|
||||||
@@ -20,7 +21,7 @@ class Migration(migrations.Migration):
|
|||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('created', models.DateTimeField(default=None, editable=False)),
|
('created', models.DateTimeField(default=None, editable=False)),
|
||||||
('modified', models.DateTimeField(default=None, editable=False)),
|
('modified', models.DateTimeField(default=None, editable=False)),
|
||||||
('event_data', awx.main.fields.JSONField(blank=True, default=dict)),
|
('event_data', awx.main.fields.JSONBlob(blank=True, default=dict)),
|
||||||
('uuid', models.CharField(default='', editable=False, max_length=1024)),
|
('uuid', models.CharField(default='', editable=False, max_length=1024)),
|
||||||
('counter', models.PositiveIntegerField(default=0, editable=False)),
|
('counter', models.PositiveIntegerField(default=0, editable=False)),
|
||||||
('stdout', models.TextField(default='', editable=False)),
|
('stdout', models.TextField(default='', editable=False)),
|
||||||
@@ -84,7 +85,7 @@ class Migration(migrations.Migration):
|
|||||||
max_length=100,
|
max_length=100,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
('event_data', awx.main.fields.JSONField(blank=True, default=dict)),
|
('event_data', awx.main.fields.JSONBlob(blank=True, default=dict)),
|
||||||
('failed', models.BooleanField(default=False, editable=False)),
|
('failed', models.BooleanField(default=False, editable=False)),
|
||||||
('changed', models.BooleanField(default=False, editable=False)),
|
('changed', models.BooleanField(default=False, editable=False)),
|
||||||
('uuid', models.CharField(default='', editable=False, max_length=1024)),
|
('uuid', models.CharField(default='', editable=False, max_length=1024)),
|
||||||
@@ -114,7 +115,7 @@ class Migration(migrations.Migration):
|
|||||||
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
|
||||||
('created', models.DateTimeField(default=None, editable=False)),
|
('created', models.DateTimeField(default=None, editable=False)),
|
||||||
('modified', models.DateTimeField(default=None, editable=False)),
|
('modified', models.DateTimeField(default=None, editable=False)),
|
||||||
('event_data', awx.main.fields.JSONField(blank=True, default=dict)),
|
('event_data', awx.main.fields.JSONBlob(blank=True, default=dict)),
|
||||||
('uuid', models.CharField(default='', editable=False, max_length=1024)),
|
('uuid', models.CharField(default='', editable=False, max_length=1024)),
|
||||||
('counter', models.PositiveIntegerField(default=0, editable=False)),
|
('counter', models.PositiveIntegerField(default=0, editable=False)),
|
||||||
('stdout', models.TextField(default='', editable=False)),
|
('stdout', models.TextField(default='', editable=False)),
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
from decimal import Decimal
|
from decimal import Decimal
|
||||||
import awx.main.fields
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@@ -16,8 +15,8 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='instancegroup',
|
model_name='instancegroup',
|
||||||
name='policy_instance_list',
|
name='policy_instance_list',
|
||||||
field=awx.main.fields.JSONField(
|
field=models.JSONField(
|
||||||
default=[], help_text='List of exact-match Instances that will always be automatically assigned to this group', blank=True
|
default=list, help_text='List of exact-match Instances that will always be automatically assigned to this group', blank=True
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
|
|||||||
@@ -2,9 +2,7 @@
|
|||||||
# Generated by Django 1.11.11 on 2018-05-21 19:51
|
# Generated by Django 1.11.11 on 2018-05-21 19:51
|
||||||
from __future__ import unicode_literals
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
import awx.main.fields
|
from django.db import models, migrations
|
||||||
import awx.main.models.activity_stream
|
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@@ -17,6 +15,6 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='activitystream',
|
model_name='activitystream',
|
||||||
name='deleted_actor',
|
name='deleted_actor',
|
||||||
field=awx.main.fields.JSONField(null=True),
|
field=models.JSONField(null=True),
|
||||||
),
|
),
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -17,7 +17,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjob',
|
model_name='workflowjob',
|
||||||
name='char_prompts',
|
name='char_prompts',
|
||||||
field=awx.main.fields.JSONField(blank=True, default=dict),
|
field=models.JSONField(blank=True, null=True, default=dict),
|
||||||
),
|
),
|
||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjob',
|
model_name='workflowjob',
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from __future__ import unicode_literals
|
|||||||
|
|
||||||
from django.db import migrations, models
|
from django.db import migrations, models
|
||||||
|
|
||||||
import awx.main.fields
|
|
||||||
import awx.main.models.notifications
|
import awx.main.models.notifications
|
||||||
|
|
||||||
|
|
||||||
@@ -18,7 +17,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='notificationtemplate',
|
model_name='notificationtemplate',
|
||||||
name='messages',
|
name='messages',
|
||||||
field=awx.main.fields.JSONField(
|
field=models.JSONField(
|
||||||
default=awx.main.models.notifications.NotificationTemplate.default_messages,
|
default=awx.main.models.notifications.NotificationTemplate.default_messages,
|
||||||
help_text='Optional custom messages for notification template.',
|
help_text='Optional custom messages for notification template.',
|
||||||
null=True,
|
null=True,
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='workflowjobtemplate',
|
model_name='workflowjobtemplate',
|
||||||
name='char_prompts',
|
name='char_prompts',
|
||||||
field=awx.main.fields.JSONField(blank=True, default=dict),
|
field=models.JSONField(blank=True, null=True, default=dict),
|
||||||
),
|
),
|
||||||
migrations.AlterField(
|
migrations.AlterField(
|
||||||
model_name='joblaunchconfig',
|
model_name='joblaunchconfig',
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
# Generated by Django 2.2.16 on 2021-02-16 20:27
|
# Generated by Django 2.2.16 on 2021-02-16 20:27
|
||||||
|
|
||||||
import awx.main.fields
|
from django.db import migrations, models
|
||||||
from django.db import migrations
|
|
||||||
|
|
||||||
|
|
||||||
class Migration(migrations.Migration):
|
class Migration(migrations.Migration):
|
||||||
@@ -14,7 +13,7 @@ class Migration(migrations.Migration):
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='unifiedjob',
|
model_name='unifiedjob',
|
||||||
name='installed_collections',
|
name='installed_collections',
|
||||||
field=awx.main.fields.JSONBField(
|
field=models.JSONField(
|
||||||
blank=True, default=dict, editable=False, help_text='The Collections names and versions installed in the execution environment.'
|
blank=True, default=dict, editable=False, help_text='The Collections names and versions installed in the execution environment.'
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ from django.db import (
|
|||||||
migrations,
|
migrations,
|
||||||
models,
|
models,
|
||||||
)
|
)
|
||||||
import jsonfield.fields
|
|
||||||
import awx.main.fields
|
import awx.main.fields
|
||||||
|
|
||||||
from awx.main.migrations import _save_password_keys
|
from awx.main.migrations import _save_password_keys
|
||||||
@@ -30,7 +29,7 @@ SQUASHED_30 = {
|
|||||||
migrations.AddField(
|
migrations.AddField(
|
||||||
model_name='job',
|
model_name='job',
|
||||||
name='survey_passwords',
|
name='survey_passwords',
|
||||||
field=jsonfield.fields.JSONField(default=dict, editable=False, blank=True),
|
field=models.JSONField(default=dict, editable=False, null=True, blank=True),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
'0031_v302_migrate_survey_passwords': [
|
'0031_v302_migrate_survey_passwords': [
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.api.versioning import reverse
|
from awx.api.versioning import reverse
|
||||||
from awx.main.fields import JSONField
|
|
||||||
from awx.main.models.base import accepts_json
|
from awx.main.models.base import accepts_json
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
@@ -36,7 +35,7 @@ class ActivityStream(models.Model):
|
|||||||
operation = models.CharField(max_length=13, choices=OPERATION_CHOICES)
|
operation = models.CharField(max_length=13, choices=OPERATION_CHOICES)
|
||||||
timestamp = models.DateTimeField(auto_now_add=True)
|
timestamp = models.DateTimeField(auto_now_add=True)
|
||||||
changes = accepts_json(models.TextField(blank=True))
|
changes = accepts_json(models.TextField(blank=True))
|
||||||
deleted_actor = JSONField(null=True)
|
deleted_actor = models.JSONField(null=True)
|
||||||
action_node = models.CharField(
|
action_node = models.CharField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default='',
|
default='',
|
||||||
@@ -84,7 +83,7 @@ class ActivityStream(models.Model):
|
|||||||
o_auth2_application = models.ManyToManyField("OAuth2Application", blank=True)
|
o_auth2_application = models.ManyToManyField("OAuth2Application", blank=True)
|
||||||
o_auth2_access_token = models.ManyToManyField("OAuth2AccessToken", blank=True)
|
o_auth2_access_token = models.ManyToManyField("OAuth2AccessToken", blank=True)
|
||||||
|
|
||||||
setting = JSONField(blank=True)
|
setting = models.JSONField(default=dict, null=True, blank=True)
|
||||||
|
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
operation = self.operation if 'operation' in self.__dict__ else '_delayed_'
|
operation = self.operation if 'operation' in self.__dict__ else '_delayed_'
|
||||||
|
|||||||
@@ -15,8 +15,8 @@ from django.utils.encoding import force_str
|
|||||||
|
|
||||||
from awx.api.versioning import reverse
|
from awx.api.versioning import reverse
|
||||||
from awx.main import consumers
|
from awx.main import consumers
|
||||||
|
from awx.main.fields import JSONBlob
|
||||||
from awx.main.managers import DeferJobCreatedManager
|
from awx.main.managers import DeferJobCreatedManager
|
||||||
from awx.main.fields import JSONField
|
|
||||||
from awx.main.constants import MINIMAL_EVENTS
|
from awx.main.constants import MINIMAL_EVENTS
|
||||||
from awx.main.models.base import CreatedModifiedModel
|
from awx.main.models.base import CreatedModifiedModel
|
||||||
from awx.main.utils import ignore_inventory_computed_fields, camelcase_to_underscore
|
from awx.main.utils import ignore_inventory_computed_fields, camelcase_to_underscore
|
||||||
@@ -209,10 +209,7 @@ class BasePlaybookEvent(CreatedModifiedModel):
|
|||||||
max_length=100,
|
max_length=100,
|
||||||
choices=EVENT_CHOICES,
|
choices=EVENT_CHOICES,
|
||||||
)
|
)
|
||||||
event_data = JSONField(
|
event_data = JSONBlob(default=dict, blank=True)
|
||||||
blank=True,
|
|
||||||
default=dict,
|
|
||||||
)
|
|
||||||
failed = models.BooleanField(
|
failed = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
editable=False,
|
editable=False,
|
||||||
@@ -648,10 +645,7 @@ class BaseCommandEvent(CreatedModifiedModel):
|
|||||||
class Meta:
|
class Meta:
|
||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
event_data = JSONField(
|
event_data = JSONBlob(default=dict, blank=True)
|
||||||
blank=True,
|
|
||||||
default=dict,
|
|
||||||
)
|
|
||||||
uuid = models.CharField(
|
uuid = models.CharField(
|
||||||
max_length=1024,
|
max_length=1024,
|
||||||
default='',
|
default='',
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ from solo.models import SingletonModel
|
|||||||
from awx import __version__ as awx_application_version
|
from awx import __version__ as awx_application_version
|
||||||
from awx.api.versioning import reverse
|
from awx.api.versioning import reverse
|
||||||
from awx.main.managers import InstanceManager, InstanceGroupManager, UUID_DEFAULT
|
from awx.main.managers import InstanceManager, InstanceGroupManager, UUID_DEFAULT
|
||||||
from awx.main.fields import JSONField
|
|
||||||
from awx.main.constants import JOB_FOLDER_PREFIX
|
from awx.main.constants import JOB_FOLDER_PREFIX
|
||||||
from awx.main.models.base import BaseModel, HasEditsMixin, prevent_search
|
from awx.main.models.base import BaseModel, HasEditsMixin, prevent_search
|
||||||
from awx.main.models.unified_jobs import UnifiedJob
|
from awx.main.models.unified_jobs import UnifiedJob
|
||||||
@@ -322,8 +321,8 @@ class InstanceGroup(HasPolicyEditsMixin, BaseModel, RelatedJobsMixin):
|
|||||||
)
|
)
|
||||||
policy_instance_percentage = models.IntegerField(default=0, help_text=_("Percentage of Instances to automatically assign to this group"))
|
policy_instance_percentage = models.IntegerField(default=0, help_text=_("Percentage of Instances to automatically assign to this group"))
|
||||||
policy_instance_minimum = models.IntegerField(default=0, help_text=_("Static minimum number of Instances to automatically assign to this group"))
|
policy_instance_minimum = models.IntegerField(default=0, help_text=_("Static minimum number of Instances to automatically assign to this group"))
|
||||||
policy_instance_list = JSONField(
|
policy_instance_list = models.JSONField(
|
||||||
default=[], blank=True, help_text=_("List of exact-match Instances that will always be automatically assigned to this group")
|
default=list, blank=True, help_text=_("List of exact-match Instances that will always be automatically assigned to this group")
|
||||||
)
|
)
|
||||||
|
|
||||||
POLICY_FIELDS = frozenset(('policy_instance_list', 'policy_instance_minimum', 'policy_instance_percentage'))
|
POLICY_FIELDS = frozenset(('policy_instance_list', 'policy_instance_minimum', 'policy_instance_percentage'))
|
||||||
|
|||||||
@@ -29,7 +29,6 @@ from awx.main.constants import CLOUD_PROVIDERS
|
|||||||
from awx.main.consumers import emit_channel_notification
|
from awx.main.consumers import emit_channel_notification
|
||||||
from awx.main.fields import (
|
from awx.main.fields import (
|
||||||
ImplicitRoleField,
|
ImplicitRoleField,
|
||||||
JSONBField,
|
|
||||||
SmartFilterField,
|
SmartFilterField,
|
||||||
OrderedManyToManyField,
|
OrderedManyToManyField,
|
||||||
)
|
)
|
||||||
@@ -488,7 +487,7 @@ class Host(CommonModelNameNotUnique, RelatedJobsMixin):
|
|||||||
editable=False,
|
editable=False,
|
||||||
help_text=_('Inventory source(s) that created or modified this host.'),
|
help_text=_('Inventory source(s) that created or modified this host.'),
|
||||||
)
|
)
|
||||||
ansible_facts = JSONBField(
|
ansible_facts = models.JSONField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default=dict,
|
default=dict,
|
||||||
help_text=_('Arbitrary JSON structure of most recent ansible_facts, per-host.'),
|
help_text=_('Arbitrary JSON structure of most recent ansible_facts, per-host.'),
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ from awx.main.models.notifications import (
|
|||||||
JobNotificationMixin,
|
JobNotificationMixin,
|
||||||
)
|
)
|
||||||
from awx.main.utils import parse_yaml_or_json, getattr_dne, NullablePromptPseudoField
|
from awx.main.utils import parse_yaml_or_json, getattr_dne, NullablePromptPseudoField
|
||||||
from awx.main.fields import ImplicitRoleField, JSONField, AskForField
|
from awx.main.fields import ImplicitRoleField, AskForField
|
||||||
from awx.main.models.mixins import (
|
from awx.main.models.mixins import (
|
||||||
ResourceMixin,
|
ResourceMixin,
|
||||||
SurveyJobTemplateMixin,
|
SurveyJobTemplateMixin,
|
||||||
@@ -546,9 +546,10 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
|
|||||||
editable=False,
|
editable=False,
|
||||||
through='JobHostSummary',
|
through='JobHostSummary',
|
||||||
)
|
)
|
||||||
artifacts = JSONField(
|
artifacts = models.JSONField(
|
||||||
blank=True,
|
|
||||||
default=dict,
|
default=dict,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
scm_revision = models.CharField(
|
scm_revision = models.CharField(
|
||||||
@@ -885,7 +886,7 @@ class LaunchTimeConfigBase(BaseModel):
|
|||||||
)
|
)
|
||||||
# All standard fields are stored in this dictionary field
|
# All standard fields are stored in this dictionary field
|
||||||
# This is a solution to the nullable CharField problem, specific to prompting
|
# This is a solution to the nullable CharField problem, specific to prompting
|
||||||
char_prompts = JSONField(blank=True, default=dict)
|
char_prompts = models.JSONField(default=dict, null=True, blank=True)
|
||||||
|
|
||||||
def prompts_dict(self, display=False):
|
def prompts_dict(self, display=False):
|
||||||
data = {}
|
data = {}
|
||||||
@@ -938,12 +939,13 @@ class LaunchTimeConfig(LaunchTimeConfigBase):
|
|||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
# Special case prompting fields, even more special than the other ones
|
# Special case prompting fields, even more special than the other ones
|
||||||
extra_data = JSONField(blank=True, default=dict)
|
extra_data = models.JSONField(default=dict, null=True, blank=True)
|
||||||
survey_passwords = prevent_search(
|
survey_passwords = prevent_search(
|
||||||
JSONField(
|
models.JSONField(
|
||||||
blank=True,
|
|
||||||
default=dict,
|
default=dict,
|
||||||
editable=False,
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
# Credentials needed for non-unified job / unified JT models
|
# Credentials needed for non-unified job / unified JT models
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ from awx.main.utils import parse_yaml_or_json, get_custom_venv_choices, get_lice
|
|||||||
from awx.main.utils.execution_environments import get_default_execution_environment
|
from awx.main.utils.execution_environments import get_default_execution_environment
|
||||||
from awx.main.utils.encryption import decrypt_value, get_encryption_key, is_encrypted
|
from awx.main.utils.encryption import decrypt_value, get_encryption_key, is_encrypted
|
||||||
from awx.main.utils.polymorphic import build_polymorphic_ctypes_map
|
from awx.main.utils.polymorphic import build_polymorphic_ctypes_map
|
||||||
from awx.main.fields import JSONField, AskForField
|
from awx.main.fields import AskForField
|
||||||
from awx.main.constants import ACTIVE_STATES
|
from awx.main.constants import ACTIVE_STATES
|
||||||
|
|
||||||
|
|
||||||
@@ -103,12 +103,7 @@ class SurveyJobTemplateMixin(models.Model):
|
|||||||
survey_enabled = models.BooleanField(
|
survey_enabled = models.BooleanField(
|
||||||
default=False,
|
default=False,
|
||||||
)
|
)
|
||||||
survey_spec = prevent_search(
|
survey_spec = prevent_search(models.JSONField(default=dict, blank=True))
|
||||||
JSONField(
|
|
||||||
blank=True,
|
|
||||||
default=dict,
|
|
||||||
)
|
|
||||||
)
|
|
||||||
ask_variables_on_launch = AskForField(blank=True, default=False, allows_field='extra_vars')
|
ask_variables_on_launch = AskForField(blank=True, default=False, allows_field='extra_vars')
|
||||||
|
|
||||||
def survey_password_variables(self):
|
def survey_password_variables(self):
|
||||||
@@ -370,10 +365,11 @@ class SurveyJobMixin(models.Model):
|
|||||||
abstract = True
|
abstract = True
|
||||||
|
|
||||||
survey_passwords = prevent_search(
|
survey_passwords = prevent_search(
|
||||||
JSONField(
|
models.JSONField(
|
||||||
blank=True,
|
|
||||||
default=dict,
|
default=dict,
|
||||||
editable=False,
|
editable=False,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|||||||
@@ -28,7 +28,6 @@ from awx.main.notifications.mattermost_backend import MattermostBackend
|
|||||||
from awx.main.notifications.grafana_backend import GrafanaBackend
|
from awx.main.notifications.grafana_backend import GrafanaBackend
|
||||||
from awx.main.notifications.rocketchat_backend import RocketChatBackend
|
from awx.main.notifications.rocketchat_backend import RocketChatBackend
|
||||||
from awx.main.notifications.irc_backend import IrcBackend
|
from awx.main.notifications.irc_backend import IrcBackend
|
||||||
from awx.main.fields import JSONField
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger('awx.main.models.notifications')
|
logger = logging.getLogger('awx.main.models.notifications')
|
||||||
@@ -70,12 +69,12 @@ class NotificationTemplate(CommonModelNameNotUnique):
|
|||||||
choices=NOTIFICATION_TYPE_CHOICES,
|
choices=NOTIFICATION_TYPE_CHOICES,
|
||||||
)
|
)
|
||||||
|
|
||||||
notification_configuration = prevent_search(JSONField(blank=False))
|
notification_configuration = prevent_search(models.JSONField(default=dict))
|
||||||
|
|
||||||
def default_messages():
|
def default_messages():
|
||||||
return {'started': None, 'success': None, 'error': None, 'workflow_approval': None}
|
return {'started': None, 'success': None, 'error': None, 'workflow_approval': None}
|
||||||
|
|
||||||
messages = JSONField(null=True, blank=True, default=default_messages, help_text=_('Optional custom messages for notification template.'))
|
messages = models.JSONField(null=True, blank=True, default=default_messages, help_text=_('Optional custom messages for notification template.'))
|
||||||
|
|
||||||
def has_message(self, condition):
|
def has_message(self, condition):
|
||||||
potential_template = self.messages.get(condition, {})
|
potential_template = self.messages.get(condition, {})
|
||||||
@@ -237,7 +236,7 @@ class Notification(CreatedModifiedModel):
|
|||||||
default='',
|
default='',
|
||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
body = JSONField(blank=True)
|
body = models.JSONField(default=dict, null=True, blank=True)
|
||||||
|
|
||||||
def get_absolute_url(self, request=None):
|
def get_absolute_url(self, request=None):
|
||||||
return reverse('api:notification_detail', kwargs={'pk': self.pk}, request=request)
|
return reverse('api:notification_detail', kwargs={'pk': self.pk}, request=request)
|
||||||
|
|||||||
@@ -38,7 +38,6 @@ from awx.main.models.rbac import (
|
|||||||
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
|
||||||
ROLE_SINGLETON_SYSTEM_AUDITOR,
|
ROLE_SINGLETON_SYSTEM_AUDITOR,
|
||||||
)
|
)
|
||||||
from awx.main.fields import JSONField
|
|
||||||
|
|
||||||
__all__ = ['Project', 'ProjectUpdate']
|
__all__ = ['Project', 'ProjectUpdate']
|
||||||
|
|
||||||
@@ -294,17 +293,17 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
|
|||||||
help_text=_('The last revision fetched by a project update'),
|
help_text=_('The last revision fetched by a project update'),
|
||||||
)
|
)
|
||||||
|
|
||||||
playbook_files = JSONField(
|
playbook_files = models.JSONField(
|
||||||
|
default=list,
|
||||||
blank=True,
|
blank=True,
|
||||||
default=[],
|
|
||||||
editable=False,
|
editable=False,
|
||||||
verbose_name=_('Playbook Files'),
|
verbose_name=_('Playbook Files'),
|
||||||
help_text=_('List of playbooks found in the project'),
|
help_text=_('List of playbooks found in the project'),
|
||||||
)
|
)
|
||||||
|
|
||||||
inventory_files = JSONField(
|
inventory_files = models.JSONField(
|
||||||
|
default=list,
|
||||||
blank=True,
|
blank=True,
|
||||||
default=[],
|
|
||||||
editable=False,
|
editable=False,
|
||||||
verbose_name=_('Inventory Files'),
|
verbose_name=_('Inventory Files'),
|
||||||
help_text=_('Suggested list of content that could be Ansible inventory in the project'),
|
help_text=_('Suggested list of content that could be Ansible inventory in the project'),
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ from awx.main.utils import polymorphic
|
|||||||
from awx.main.constants import ACTIVE_STATES, CAN_CANCEL
|
from awx.main.constants import ACTIVE_STATES, CAN_CANCEL
|
||||||
from awx.main.redact import UriCleaner, REPLACE_STR
|
from awx.main.redact import UriCleaner, REPLACE_STR
|
||||||
from awx.main.consumers import emit_channel_notification
|
from awx.main.consumers import emit_channel_notification
|
||||||
from awx.main.fields import JSONField, JSONBField, AskForField, OrderedManyToManyField
|
from awx.main.fields import AskForField, OrderedManyToManyField
|
||||||
|
|
||||||
__all__ = ['UnifiedJobTemplate', 'UnifiedJob', 'StdoutMaxBytesExceeded']
|
__all__ = ['UnifiedJobTemplate', 'UnifiedJob', 'StdoutMaxBytesExceeded']
|
||||||
|
|
||||||
@@ -653,9 +653,10 @@ class UnifiedJob(
|
|||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
job_env = prevent_search(
|
job_env = prevent_search(
|
||||||
JSONField(
|
models.JSONField(
|
||||||
blank=True,
|
|
||||||
default=dict,
|
default=dict,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
@@ -704,7 +705,7 @@ class UnifiedJob(
|
|||||||
'Credential',
|
'Credential',
|
||||||
related_name='%(class)ss',
|
related_name='%(class)ss',
|
||||||
)
|
)
|
||||||
installed_collections = JSONBField(
|
installed_collections = models.JSONField(
|
||||||
blank=True,
|
blank=True,
|
||||||
default=dict,
|
default=dict,
|
||||||
editable=False,
|
editable=False,
|
||||||
|
|||||||
@@ -40,7 +40,6 @@ from awx.main.models.mixins import (
|
|||||||
from awx.main.models.jobs import LaunchTimeConfigBase, LaunchTimeConfig, JobTemplate
|
from awx.main.models.jobs import LaunchTimeConfigBase, LaunchTimeConfig, JobTemplate
|
||||||
from awx.main.models.credential import Credential
|
from awx.main.models.credential import Credential
|
||||||
from awx.main.redact import REPLACE_STR
|
from awx.main.redact import REPLACE_STR
|
||||||
from awx.main.fields import JSONField
|
|
||||||
from awx.main.utils import schedule_task_manager
|
from awx.main.utils import schedule_task_manager
|
||||||
|
|
||||||
|
|
||||||
@@ -232,9 +231,10 @@ class WorkflowJobNode(WorkflowNodeBase):
|
|||||||
default=None,
|
default=None,
|
||||||
on_delete=models.CASCADE,
|
on_delete=models.CASCADE,
|
||||||
)
|
)
|
||||||
ancestor_artifacts = JSONField(
|
ancestor_artifacts = models.JSONField(
|
||||||
blank=True,
|
|
||||||
default=dict,
|
default=dict,
|
||||||
|
null=True,
|
||||||
|
blank=True,
|
||||||
editable=False,
|
editable=False,
|
||||||
)
|
)
|
||||||
do_not_run = models.BooleanField(
|
do_not_run = models.BooleanField(
|
||||||
|
|||||||
@@ -180,8 +180,8 @@ def mk_job_template(
|
|||||||
|
|
||||||
jt.project = project
|
jt.project = project
|
||||||
|
|
||||||
jt.survey_spec = spec
|
if spec is not None:
|
||||||
if jt.survey_spec is not None:
|
jt.survey_spec = spec
|
||||||
jt.survey_enabled = True
|
jt.survey_enabled = True
|
||||||
|
|
||||||
if persisted:
|
if persisted:
|
||||||
@@ -212,8 +212,8 @@ def mk_workflow_job_template(name, extra_vars='', spec=None, organization=None,
|
|||||||
|
|
||||||
wfjt = WorkflowJobTemplate(name=name, extra_vars=extra_vars, organization=organization, webhook_service=webhook_service)
|
wfjt = WorkflowJobTemplate(name=name, extra_vars=extra_vars, organization=organization, webhook_service=webhook_service)
|
||||||
|
|
||||||
wfjt.survey_spec = spec
|
if spec:
|
||||||
if wfjt.survey_spec:
|
wfjt.survey_spec = spec
|
||||||
wfjt.survey_enabled = True
|
wfjt.survey_enabled = True
|
||||||
|
|
||||||
if persisted:
|
if persisted:
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ from django.core.serializers.json import DjangoJSONEncoder
|
|||||||
from django.db.backends.sqlite3.base import SQLiteCursorWrapper
|
from django.db.backends.sqlite3.base import SQLiteCursorWrapper
|
||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.fields import JSONBField
|
|
||||||
from awx.main.models.projects import Project
|
from awx.main.models.projects import Project
|
||||||
from awx.main.models.ha import Instance
|
from awx.main.models.ha import Instance
|
||||||
|
|
||||||
@@ -755,11 +754,6 @@ def get_db_prep_save(self, value, connection, **kwargs):
|
|||||||
return value
|
return value
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
|
||||||
def monkeypatch_jsonbfield_get_db_prep_save(mocker):
|
|
||||||
JSONBField.get_db_prep_save = get_db_prep_save
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture
|
@pytest.fixture
|
||||||
def oauth_application(admin):
|
def oauth_application(admin):
|
||||||
return Application.objects.create(name='test app', user=admin, client_type='confidential', authorization_grant_type='password')
|
return Application.objects.create(name='test app', user=admin, client_type='confidential', authorization_grant_type='password')
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ from unittest import mock
|
|||||||
|
|
||||||
# AWX
|
# AWX
|
||||||
from awx.main.utils.filters import SmartFilter, ExternalLoggerEnabled
|
from awx.main.utils.filters import SmartFilter, ExternalLoggerEnabled
|
||||||
from awx.main.models import Host
|
|
||||||
|
|
||||||
# Django
|
# Django
|
||||||
from django.db.models import Q
|
from django.db.models import Q
|
||||||
@@ -219,39 +218,6 @@ class TestSmartFilterQueryFromString:
|
|||||||
assert str(q) == str(q_expected)
|
assert str(q) == str(q_expected)
|
||||||
|
|
||||||
|
|
||||||
class TestSmartFilterQueryFromStringNoDB:
|
|
||||||
@pytest.mark.parametrize(
|
|
||||||
"filter_string,q_expected",
|
|
||||||
[
|
|
||||||
(
|
|
||||||
'ansible_facts__a="true" and ansible_facts__b="true" and ansible_facts__c="true"',
|
|
||||||
(
|
|
||||||
Q(**{u"ansible_facts__contains": {u"a": u"true"}})
|
|
||||||
& Q(**{u"ansible_facts__contains": {u"b": u"true"}})
|
|
||||||
& Q(**{u"ansible_facts__contains": {u"c": u"true"}})
|
|
||||||
),
|
|
||||||
),
|
|
||||||
(
|
|
||||||
'ansible_facts__a="true" or ansible_facts__b="true" or ansible_facts__c="true"',
|
|
||||||
(
|
|
||||||
Q(**{u"ansible_facts__contains": {u"a": u"true"}})
|
|
||||||
| Q(**{u"ansible_facts__contains": {u"b": u"true"}})
|
|
||||||
| Q(**{u"ansible_facts__contains": {u"c": u"true"}})
|
|
||||||
),
|
|
||||||
),
|
|
||||||
('search=foo', Q(Q(**{u"description__icontains": u"foo"}) | Q(**{u"name__icontains": u"foo"}))),
|
|
||||||
(
|
|
||||||
'search=foo and ansible_facts__a="null"',
|
|
||||||
Q(Q(**{u"description__icontains": u"foo"}) | Q(**{u"name__icontains": u"foo"})) & Q(**{u"ansible_facts__contains": {u"a": u"\"null\""}}),
|
|
||||||
),
|
|
||||||
('name=foo or name=bar and name=foobar', Q(name="foo") | Q(name="bar") & Q(name="foobar")),
|
|
||||||
],
|
|
||||||
)
|
|
||||||
def test_does_not_invoke_db(self, filter_string, q_expected):
|
|
||||||
q = SmartFilter.query_from_string(filter_string)
|
|
||||||
assert str(q.query) == str(Host.objects.filter(q_expected).query)
|
|
||||||
|
|
||||||
|
|
||||||
'''
|
'''
|
||||||
#('"facts__quoted_val"="f\"oo"', 1),
|
#('"facts__quoted_val"="f\"oo"', 1),
|
||||||
#('facts__facts__arr[]="foo"', 1),
|
#('facts__facts__arr[]="foo"', 1),
|
||||||
|
|||||||
@@ -188,13 +188,11 @@ class SmartFilter(object):
|
|||||||
'''
|
'''
|
||||||
|
|
||||||
def _json_path_to_contains(self, k, v):
|
def _json_path_to_contains(self, k, v):
|
||||||
from awx.main.fields import JSONBField # avoid a circular import
|
|
||||||
|
|
||||||
if not k.startswith(SmartFilter.SEARCHABLE_RELATIONSHIP):
|
if not k.startswith(SmartFilter.SEARCHABLE_RELATIONSHIP):
|
||||||
v = self.strip_quotes_traditional_logic(v)
|
v = self.strip_quotes_traditional_logic(v)
|
||||||
return (k, v)
|
return (k, v)
|
||||||
|
|
||||||
for match in JSONBField.get_lookups().keys():
|
for match in models.JSONField.get_lookups().keys():
|
||||||
match = '__{}'.format(match)
|
match = '__{}'.format(match)
|
||||||
if k.endswith(match):
|
if k.endswith(match):
|
||||||
if match == '__exact':
|
if match == '__exact':
|
||||||
|
|||||||
@@ -105,17 +105,6 @@ Upgrading to 4.0.0 causes error because imports changed.
|
|||||||
ImportError: cannot import name 'KeyVaultClient'
|
ImportError: cannot import name 'KeyVaultClient'
|
||||||
```
|
```
|
||||||
|
|
||||||
### django-jsonfield
|
|
||||||
|
|
||||||
Instead of calling a `loads()` operation, the returned value is casted into
|
|
||||||
a string in some cases, introduced in the change:
|
|
||||||
|
|
||||||
https://github.com/adamchainz/django-jsonfield/pull/14
|
|
||||||
|
|
||||||
This breaks a very large amount of AWX code that assumes these fields
|
|
||||||
are returned as dicts. Upgrading this library will require a refactor
|
|
||||||
to accommodate this change.
|
|
||||||
|
|
||||||
### pip and setuptools
|
### pip and setuptools
|
||||||
|
|
||||||
The offline installer needs to have functionality confirmed before upgrading these.
|
The offline installer needs to have functionality confirmed before upgrading these.
|
||||||
|
|||||||
Reference in New Issue
Block a user