diff --git a/awx/conf/migrations/0010_change_to_JSONField.py b/awx/conf/migrations/0010_change_to_JSONField.py new file mode 100644 index 0000000000..9f0eda78c5 --- /dev/null +++ b/awx/conf/migrations/0010_change_to_JSONField.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2 on 2023-06-09 19:51 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('conf', '0009_rename_proot_settings'), + ] + + operations = [ + migrations.AlterField( + model_name='setting', + name='value', + field=models.JSONField(null=True), + ), + ] diff --git a/awx/conf/models.py b/awx/conf/models.py index 900db1e185..25cf0cd584 100644 --- a/awx/conf/models.py +++ b/awx/conf/models.py @@ -8,7 +8,6 @@ import json from django.db import models # AWX -from awx.main.fields import JSONBlob from awx.main.models.base import CreatedModifiedModel, prevent_search from awx.main.utils import encrypt_field from awx.conf import settings_registry @@ -18,7 +17,7 @@ __all__ = ['Setting'] class Setting(CreatedModifiedModel): key = models.CharField(max_length=255) - value = JSONBlob(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)) def __str__(self): diff --git a/awx/main/migrations/0185_move_JSONBlob_to_JSONField.py b/awx/main/migrations/0185_move_JSONBlob_to_JSONField.py new file mode 100644 index 0000000000..643d6a5d59 --- /dev/null +++ b/awx/main/migrations/0185_move_JSONBlob_to_JSONField.py @@ -0,0 +1,142 @@ +# Generated by Django 4.2 on 2023-06-09 19:51 + +import awx.main.models.notifications +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('main', '0184_django_indexes'), + ('conf', '0010_change_to_JSONField'), + ] + + operations = [ + migrations.AlterField( + model_name='activitystream', + name='deleted_actor', + field=models.JSONField(null=True), + ), + migrations.AlterField( + model_name='activitystream', + name='setting', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='instancegroup', + name='policy_instance_list', + field=models.JSONField( + blank=True, default=list, help_text='List of exact-match Instances that will always be automatically assigned to this group' + ), + ), + migrations.AlterField( + model_name='job', + name='survey_passwords', + field=models.JSONField(blank=True, default=dict, editable=False), + ), + migrations.AlterField( + model_name='joblaunchconfig', + name='char_prompts', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='joblaunchconfig', + name='survey_passwords', + field=models.JSONField(blank=True, default=dict, editable=False), + ), + migrations.AlterField( + model_name='jobtemplate', + name='survey_spec', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='notification', + name='body', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='notificationtemplate', + name='messages', + field=models.JSONField( + blank=True, + default=awx.main.models.notifications.NotificationTemplate.default_messages, + help_text='Optional custom messages for notification template.', + null=True, + ), + ), + migrations.AlterField( + model_name='notificationtemplate', + name='notification_configuration', + field=models.JSONField(default=dict), + ), + migrations.AlterField( + model_name='project', + name='inventory_files', + field=models.JSONField( + blank=True, + default=list, + editable=False, + help_text='Suggested list of content that could be Ansible inventory in the project', + verbose_name='Inventory Files', + ), + ), + migrations.AlterField( + model_name='project', + name='playbook_files', + field=models.JSONField(blank=True, default=list, editable=False, help_text='List of playbooks found in the project', verbose_name='Playbook Files'), + ), + migrations.AlterField( + model_name='schedule', + name='char_prompts', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='schedule', + name='survey_passwords', + field=models.JSONField(blank=True, default=dict, editable=False), + ), + migrations.AlterField( + model_name='unifiedjob', + name='job_env', + field=models.JSONField(blank=True, default=dict, editable=False), + ), + migrations.AlterField( + model_name='workflowjob', + name='char_prompts', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='workflowjob', + name='survey_passwords', + field=models.JSONField(blank=True, default=dict, editable=False), + ), + migrations.AlterField( + model_name='workflowjobnode', + name='char_prompts', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='workflowjobnode', + name='survey_passwords', + field=models.JSONField(blank=True, default=dict, editable=False), + ), + migrations.AlterField( + model_name='workflowjobtemplate', + name='char_prompts', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='workflowjobtemplate', + name='survey_spec', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='workflowjobtemplatenode', + name='char_prompts', + field=models.JSONField(blank=True, default=dict), + ), + migrations.AlterField( + model_name='workflowjobtemplatenode', + name='survey_passwords', + field=models.JSONField(blank=True, default=dict, editable=False), + ), + ] diff --git a/awx/main/models/activity_stream.py b/awx/main/models/activity_stream.py index fad08377fd..7bce0c4fe0 100644 --- a/awx/main/models/activity_stream.py +++ b/awx/main/models/activity_stream.py @@ -3,7 +3,6 @@ # AWX from awx.api.versioning import reverse -from awx.main.fields import JSONBlob from awx.main.models.base import accepts_json # Django @@ -36,7 +35,7 @@ class ActivityStream(models.Model): operation = models.CharField(max_length=13, choices=OPERATION_CHOICES) timestamp = models.DateTimeField(auto_now_add=True) changes = accepts_json(models.TextField(blank=True)) - deleted_actor = JSONBlob(null=True) + deleted_actor = models.JSONField(null=True) action_node = models.CharField( blank=True, default='', @@ -84,7 +83,7 @@ class ActivityStream(models.Model): o_auth2_application = models.ManyToManyField("OAuth2Application", blank=True) o_auth2_access_token = models.ManyToManyField("OAuth2AccessToken", blank=True) - setting = JSONBlob(default=dict, blank=True) + setting = models.JSONField(default=dict, blank=True) def __str__(self): operation = self.operation if 'operation' in self.__dict__ else '_delayed_' diff --git a/awx/main/models/ha.py b/awx/main/models/ha.py index de0861c909..888eb8b92e 100644 --- a/awx/main/models/ha.py +++ b/awx/main/models/ha.py @@ -20,7 +20,7 @@ from solo.models import SingletonModel # AWX from awx import __version__ as awx_application_version from awx.api.versioning import reverse -from awx.main.fields import JSONBlob, ImplicitRoleField +from awx.main.fields import ImplicitRoleField from awx.main.managers import InstanceManager, UUID_DEFAULT from awx.main.constants import JOB_FOLDER_PREFIX from awx.main.models.base import BaseModel, HasEditsMixin, prevent_search @@ -406,7 +406,7 @@ class InstanceGroup(HasPolicyEditsMixin, BaseModel, RelatedJobsMixin, ResourceMi max_forks = models.IntegerField(default=0, help_text=_("Max forks to execute on this group. Zero means no limit.")) 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_list = JSONBlob( + policy_instance_list = models.JSONField( default=list, blank=True, help_text=_("List of exact-match Instances that will always be automatically assigned to this group") ) diff --git a/awx/main/models/jobs.py b/awx/main/models/jobs.py index 71e42d5567..edbc3de0bd 100644 --- a/awx/main/models/jobs.py +++ b/awx/main/models/jobs.py @@ -883,7 +883,7 @@ class LaunchTimeConfigBase(BaseModel): ) # All standard fields are stored in this dictionary field # This is a solution to the nullable CharField problem, specific to prompting - char_prompts = JSONBlob(default=dict, blank=True) + char_prompts = models.JSONField(default=dict, blank=True) # Define fields that are not really fields, but alias to char_prompts lookups limit = NullablePromptPseudoField('limit') @@ -960,7 +960,7 @@ class LaunchTimeConfig(LaunchTimeConfigBase): # Special case prompting fields, even more special than the other ones extra_data = JSONBlob(default=dict, blank=True) survey_passwords = prevent_search( - JSONBlob( + models.JSONField( default=dict, editable=False, blank=True, diff --git a/awx/main/models/mixins.py b/awx/main/models/mixins.py index f2998c4eb0..75b304a32a 100644 --- a/awx/main/models/mixins.py +++ b/awx/main/models/mixins.py @@ -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.encryption import decrypt_value, get_encryption_key, is_encrypted from awx.main.utils.polymorphic import build_polymorphic_ctypes_map -from awx.main.fields import AskForField, JSONBlob +from awx.main.fields import AskForField from awx.main.constants import ACTIVE_STATES @@ -103,7 +103,7 @@ class SurveyJobTemplateMixin(models.Model): survey_enabled = models.BooleanField( default=False, ) - survey_spec = prevent_search(JSONBlob(default=dict, blank=True)) + survey_spec = prevent_search(models.JSONField(default=dict, blank=True)) ask_inventory_on_launch = AskForField( blank=True, @@ -392,7 +392,7 @@ class SurveyJobMixin(models.Model): abstract = True survey_passwords = prevent_search( - JSONBlob( + models.JSONField( default=dict, editable=False, blank=True, diff --git a/awx/main/models/notifications.py b/awx/main/models/notifications.py index d74942c995..ef8304b6a6 100644 --- a/awx/main/models/notifications.py +++ b/awx/main/models/notifications.py @@ -17,7 +17,6 @@ from jinja2.exceptions import TemplateSyntaxError, UndefinedError, SecurityError # AWX from awx.api.versioning import reverse -from awx.main.fields import JSONBlob from awx.main.models.base import CommonModelNameNotUnique, CreatedModifiedModel, prevent_search from awx.main.utils import encrypt_field, decrypt_field, set_environ from awx.main.notifications.email_backend import CustomEmailBackend @@ -69,12 +68,12 @@ class NotificationTemplate(CommonModelNameNotUnique): choices=NOTIFICATION_TYPE_CHOICES, ) - notification_configuration = prevent_search(JSONBlob(default=dict)) + notification_configuration = prevent_search(models.JSONField(default=dict)) def default_messages(): return {'started': None, 'success': None, 'error': None, 'workflow_approval': None} - messages = JSONBlob(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): potential_template = self.messages.get(condition, {}) @@ -236,7 +235,7 @@ class Notification(CreatedModifiedModel): default='', editable=False, ) - body = JSONBlob(default=dict, blank=True) + body = models.JSONField(default=dict, blank=True) def get_absolute_url(self, request=None): return reverse('api:notification_detail', kwargs={'pk': self.pk}, request=request) diff --git a/awx/main/models/projects.py b/awx/main/models/projects.py index 859acd6fbf..e948ff3d66 100644 --- a/awx/main/models/projects.py +++ b/awx/main/models/projects.py @@ -33,7 +33,7 @@ from awx.main.models.mixins import ResourceMixin, TaskManagerProjectUpdateMixin, from awx.main.utils import update_scm_url, polymorphic from awx.main.utils.ansible import skip_directory, could_be_inventory, could_be_playbook from awx.main.utils.execution_environments import get_control_plane_execution_environment -from awx.main.fields import ImplicitRoleField, JSONBlob +from awx.main.fields import ImplicitRoleField from awx.main.models.rbac import ( ROLE_SINGLETON_SYSTEM_ADMINISTRATOR, ROLE_SINGLETON_SYSTEM_AUDITOR, @@ -303,7 +303,7 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn help_text=_('The last revision fetched by a project update'), ) - playbook_files = JSONBlob( + playbook_files = models.JSONField( default=list, blank=True, editable=False, @@ -311,7 +311,7 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn help_text=_('List of playbooks found in the project'), ) - inventory_files = JSONBlob( + inventory_files = models.JSONField( default=list, blank=True, editable=False, diff --git a/awx/main/models/unified_jobs.py b/awx/main/models/unified_jobs.py index 1e987fa982..8dcb5df849 100644 --- a/awx/main/models/unified_jobs.py +++ b/awx/main/models/unified_jobs.py @@ -55,7 +55,7 @@ from awx.main.utils import polymorphic from awx.main.constants import ACTIVE_STATES, CAN_CANCEL, JOB_VARIABLE_PREFIXES from awx.main.redact import UriCleaner, REPLACE_STR from awx.main.consumers import emit_channel_notification -from awx.main.fields import AskForField, OrderedManyToManyField, JSONBlob +from awx.main.fields import AskForField, OrderedManyToManyField __all__ = ['UnifiedJobTemplate', 'UnifiedJob', 'StdoutMaxBytesExceeded'] @@ -668,7 +668,7 @@ class UnifiedJob( editable=False, ) job_env = prevent_search( - JSONBlob( + models.JSONField( default=dict, blank=True, editable=False,