Merge pull request #11654 from jbradberry/django-3.2-upgrade

Django 3.2 upgrade
This commit is contained in:
Jeff Bradberry
2022-03-17 10:34:22 -04:00
committed by GitHub
222 changed files with 1592 additions and 1929 deletions

View File

@@ -3,6 +3,7 @@
# Django
from django.conf import settings # noqa
from django.db import connection
from django.db.models.signals import pre_delete # noqa
# AWX
@@ -97,6 +98,93 @@ User.add_to_class('can_access_with_errors', check_user_access_with_errors)
User.add_to_class('accessible_objects', user_accessible_objects)
def convert_jsonfields_to_jsonb():
if connection.vendor != 'postgresql':
return
# fmt: off
fields = [ # Table name, expensive or not, tuple of column names
('conf_setting', False, (
'value',
)),
('main_instancegroup', False, (
'policy_instance_list',
)),
('main_jobtemplate', False, (
'survey_spec',
)),
('main_notificationtemplate', False, (
'notification_configuration',
'messages',
)),
('main_project', False, (
'playbook_files',
'inventory_files',
)),
('main_schedule', False, (
'extra_data',
'char_prompts',
'survey_passwords',
)),
('main_workflowjobtemplate', False, (
'survey_spec',
'char_prompts',
)),
('main_workflowjobtemplatenode', False, (
'char_prompts',
'extra_data',
'survey_passwords',
)),
('main_activitystream', True, (
'setting', # NN = NOT NULL
'deleted_actor',
)),
('main_job', True, (
'survey_passwords', # NN
'artifacts', # NN
)),
('main_joblaunchconfig', True, (
'extra_data', # NN
'survey_passwords', # NN
'char_prompts', # NN
)),
('main_notification', True, (
'body', # NN
)),
('main_unifiedjob', True, (
'job_env', # NN
)),
('main_workflowjob', True, (
'survey_passwords', # NN
'char_prompts', # NN
)),
('main_workflowjobnode', True, (
'char_prompts', # NN
'ancestor_artifacts', # NN
'extra_data', # NN
'survey_passwords', # NN
)),
]
# fmt: on
with connection.cursor() as cursor:
for table, expensive, columns in fields:
cursor.execute(
"""
select count(1) from information_schema.columns
where
table_name = %s and
column_name in %s and
data_type != 'jsonb';
""",
(table, columns),
)
if cursor.fetchone()[0]:
from awx.main.tasks.system import migrate_json_fields
migrate_json_fields.apply_async([table, expensive, columns])
def cleanup_created_modified_by(sender, **kwargs):
# work around a bug in django-polymorphic that doesn't properly
# handle cascades for reverse foreign keys on the polymorphic base model

View File

@@ -3,14 +3,13 @@
# AWX
from awx.api.versioning import reverse
from awx.main.fields import JSONField
from awx.main.models.base import accepts_json
# Django
from django.db import models
from django.conf import settings
from django.utils.encoding import smart_str
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
__all__ = ['ActivityStream']
@@ -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 = JSONField(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 = JSONField(blank=True)
setting = models.JSONField(default=dict, null=True, blank=True)
def __str__(self):
operation = self.operation if 'operation' in self.__dict__ else '_delayed_'

View File

@@ -9,7 +9,7 @@ from urllib.parse import urljoin
from django.conf import settings
from django.db import models
from django.utils.text import Truncator
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ValidationError
# AWX

View File

@@ -4,7 +4,7 @@
# Django
from django.db import models
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.utils.timezone import now
# Django-Taggit

View File

@@ -15,9 +15,9 @@ from jinja2 import sandbox
# Django
from django.db import models
from django.utils.translation import ugettext_lazy as _, ugettext_noop
from django.utils.translation import gettext_lazy as _, gettext_noop
from django.core.exceptions import ValidationError
from django.utils.encoding import force_text
from django.utils.encoding import force_str
from django.utils.functional import cached_property
from django.utils.timezone import now
@@ -230,7 +230,7 @@ class Credential(PasswordFieldsModel, CommonModelNameNotUnique, ResourceMixin):
def display_inputs(self):
field_val = self.inputs.copy()
for k, v in field_val.items():
if force_text(v).startswith('$encrypted$'):
if force_str(v).startswith('$encrypted$'):
field_val[k] = '$encrypted$'
return field_val
@@ -579,34 +579,34 @@ class ManagedCredentialType(SimpleNamespace):
ManagedCredentialType(
namespace='ssh',
kind='ssh',
name=ugettext_noop('Machine'),
name=gettext_noop('Machine'),
inputs={
'fields': [
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'password', 'label': ugettext_noop('Password'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
{'id': 'ssh_key_data', 'label': ugettext_noop('SSH Private Key'), 'type': 'string', 'format': 'ssh_private_key', 'secret': True, 'multiline': True},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{'id': 'password', 'label': gettext_noop('Password'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
{'id': 'ssh_key_data', 'label': gettext_noop('SSH Private Key'), 'type': 'string', 'format': 'ssh_private_key', 'secret': True, 'multiline': True},
{
'id': 'ssh_public_key_data',
'label': ugettext_noop('Signed SSH Certificate'),
'label': gettext_noop('Signed SSH Certificate'),
'type': 'string',
'multiline': True,
'secret': True,
},
{'id': 'ssh_key_unlock', 'label': ugettext_noop('Private Key Passphrase'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
{'id': 'ssh_key_unlock', 'label': gettext_noop('Private Key Passphrase'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
{
'id': 'become_method',
'label': ugettext_noop('Privilege Escalation Method'),
'label': gettext_noop('Privilege Escalation Method'),
'type': 'string',
'help_text': ugettext_noop(
'help_text': gettext_noop(
'Specify a method for "become" operations. This is ' 'equivalent to specifying the --become-method ' 'Ansible parameter.'
),
},
{
'id': 'become_username',
'label': ugettext_noop('Privilege Escalation Username'),
'label': gettext_noop('Privilege Escalation Username'),
'type': 'string',
},
{'id': 'become_password', 'label': ugettext_noop('Privilege Escalation Password'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
{'id': 'become_password', 'label': gettext_noop('Privilege Escalation Password'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
],
},
)
@@ -614,14 +614,14 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='scm',
kind='scm',
name=ugettext_noop('Source Control'),
name=gettext_noop('Source Control'),
managed=True,
inputs={
'fields': [
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'password', 'label': ugettext_noop('Password'), 'type': 'string', 'secret': True},
{'id': 'ssh_key_data', 'label': ugettext_noop('SCM Private Key'), 'type': 'string', 'format': 'ssh_private_key', 'secret': True, 'multiline': True},
{'id': 'ssh_key_unlock', 'label': ugettext_noop('Private Key Passphrase'), 'type': 'string', 'secret': True},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{'id': 'password', 'label': gettext_noop('Password'), 'type': 'string', 'secret': True},
{'id': 'ssh_key_data', 'label': gettext_noop('SCM Private Key'), 'type': 'string', 'format': 'ssh_private_key', 'secret': True, 'multiline': True},
{'id': 'ssh_key_unlock', 'label': gettext_noop('Private Key Passphrase'), 'type': 'string', 'secret': True},
],
},
)
@@ -629,17 +629,17 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='vault',
kind='vault',
name=ugettext_noop('Vault'),
name=gettext_noop('Vault'),
managed=True,
inputs={
'fields': [
{'id': 'vault_password', 'label': ugettext_noop('Vault Password'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
{'id': 'vault_password', 'label': gettext_noop('Vault Password'), 'type': 'string', 'secret': True, 'ask_at_runtime': True},
{
'id': 'vault_id',
'label': ugettext_noop('Vault Identifier'),
'label': gettext_noop('Vault Identifier'),
'type': 'string',
'format': 'vault_id',
'help_text': ugettext_noop(
'help_text': gettext_noop(
'Specify an (optional) Vault ID. This is '
'equivalent to specifying the --vault-id '
'Ansible parameter for providing multiple Vault '
@@ -655,32 +655,32 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='net',
kind='net',
name=ugettext_noop('Network'),
name=gettext_noop('Network'),
managed=True,
inputs={
'fields': [
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{
'id': 'password',
'label': ugettext_noop('Password'),
'label': gettext_noop('Password'),
'type': 'string',
'secret': True,
},
{'id': 'ssh_key_data', 'label': ugettext_noop('SSH Private Key'), 'type': 'string', 'format': 'ssh_private_key', 'secret': True, 'multiline': True},
{'id': 'ssh_key_data', 'label': gettext_noop('SSH Private Key'), 'type': 'string', 'format': 'ssh_private_key', 'secret': True, 'multiline': True},
{
'id': 'ssh_key_unlock',
'label': ugettext_noop('Private Key Passphrase'),
'label': gettext_noop('Private Key Passphrase'),
'type': 'string',
'secret': True,
},
{
'id': 'authorize',
'label': ugettext_noop('Authorize'),
'label': gettext_noop('Authorize'),
'type': 'boolean',
},
{
'id': 'authorize_password',
'label': ugettext_noop('Authorize Password'),
'label': gettext_noop('Authorize Password'),
'type': 'string',
'secret': True,
},
@@ -695,23 +695,23 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='aws',
kind='cloud',
name=ugettext_noop('Amazon Web Services'),
name=gettext_noop('Amazon Web Services'),
managed=True,
inputs={
'fields': [
{'id': 'username', 'label': ugettext_noop('Access Key'), 'type': 'string'},
{'id': 'username', 'label': gettext_noop('Access Key'), 'type': 'string'},
{
'id': 'password',
'label': ugettext_noop('Secret Key'),
'label': gettext_noop('Secret Key'),
'type': 'string',
'secret': True,
},
{
'id': 'security_token',
'label': ugettext_noop('STS Token'),
'label': gettext_noop('STS Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop(
'help_text': gettext_noop(
'Security Token Service (STS) is a web service '
'that enables you to request temporary, '
'limited-privilege credentials for AWS Identity '
@@ -726,38 +726,38 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='openstack',
kind='cloud',
name=ugettext_noop('OpenStack'),
name=gettext_noop('OpenStack'),
managed=True,
inputs={
'fields': [
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{
'id': 'password',
'label': ugettext_noop('Password (API Key)'),
'label': gettext_noop('Password (API Key)'),
'type': 'string',
'secret': True,
},
{
'id': 'host',
'label': ugettext_noop('Host (Authentication URL)'),
'label': gettext_noop('Host (Authentication URL)'),
'type': 'string',
'help_text': ugettext_noop('The host to authenticate with. For example, ' 'https://openstack.business.com/v2.0/'),
'help_text': gettext_noop('The host to authenticate with. For example, ' 'https://openstack.business.com/v2.0/'),
},
{
'id': 'project',
'label': ugettext_noop('Project (Tenant Name)'),
'label': gettext_noop('Project (Tenant Name)'),
'type': 'string',
},
{
'id': 'project_domain_name',
'label': ugettext_noop('Project (Domain Name)'),
'label': gettext_noop('Project (Domain Name)'),
'type': 'string',
},
{
'id': 'domain',
'label': ugettext_noop('Domain Name'),
'label': gettext_noop('Domain Name'),
'type': 'string',
'help_text': ugettext_noop(
'help_text': gettext_noop(
'OpenStack domains define administrative boundaries. '
'It is only needed for Keystone v3 authentication '
'URLs. Refer to the documentation for '
@@ -766,13 +766,13 @@ ManagedCredentialType(
},
{
'id': 'region',
'label': ugettext_noop('Region Name'),
'label': gettext_noop('Region Name'),
'type': 'string',
'help_text': ugettext_noop('For some cloud providers, like OVH, region must be specified'),
'help_text': gettext_noop('For some cloud providers, like OVH, region must be specified'),
},
{
'id': 'verify_ssl',
'label': ugettext_noop('Verify SSL'),
'label': gettext_noop('Verify SSL'),
'type': 'boolean',
'default': True,
},
@@ -784,20 +784,20 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='vmware',
kind='cloud',
name=ugettext_noop('VMware vCenter'),
name=gettext_noop('VMware vCenter'),
managed=True,
inputs={
'fields': [
{
'id': 'host',
'label': ugettext_noop('VCenter Host'),
'label': gettext_noop('VCenter Host'),
'type': 'string',
'help_text': ugettext_noop('Enter the hostname or IP address that corresponds ' 'to your VMware vCenter.'),
'help_text': gettext_noop('Enter the hostname or IP address that corresponds ' 'to your VMware vCenter.'),
},
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{
'id': 'password',
'label': ugettext_noop('Password'),
'label': gettext_noop('Password'),
'type': 'string',
'secret': True,
},
@@ -809,20 +809,20 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='satellite6',
kind='cloud',
name=ugettext_noop('Red Hat Satellite 6'),
name=gettext_noop('Red Hat Satellite 6'),
managed=True,
inputs={
'fields': [
{
'id': 'host',
'label': ugettext_noop('Satellite 6 URL'),
'label': gettext_noop('Satellite 6 URL'),
'type': 'string',
'help_text': ugettext_noop('Enter the URL that corresponds to your Red Hat ' 'Satellite 6 server. For example, https://satellite.example.org'),
'help_text': gettext_noop('Enter the URL that corresponds to your Red Hat ' 'Satellite 6 server. For example, https://satellite.example.org'),
},
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{
'id': 'password',
'label': ugettext_noop('Password'),
'label': gettext_noop('Password'),
'type': 'string',
'secret': True,
},
@@ -834,21 +834,21 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='gce',
kind='cloud',
name=ugettext_noop('Google Compute Engine'),
name=gettext_noop('Google Compute Engine'),
managed=True,
inputs={
'fields': [
{
'id': 'username',
'label': ugettext_noop('Service Account Email Address'),
'label': gettext_noop('Service Account Email Address'),
'type': 'string',
'help_text': ugettext_noop('The email address assigned to the Google Compute ' 'Engine service account.'),
'help_text': gettext_noop('The email address assigned to the Google Compute ' 'Engine service account.'),
},
{
'id': 'project',
'label': 'Project',
'type': 'string',
'help_text': ugettext_noop(
'help_text': gettext_noop(
'The Project ID is the GCE assigned identification. '
'It is often constructed as three words or two words '
'followed by a three-digit number. Examples: project-id-000 '
@@ -857,12 +857,12 @@ ManagedCredentialType(
},
{
'id': 'ssh_key_data',
'label': ugettext_noop('RSA Private Key'),
'label': gettext_noop('RSA Private Key'),
'type': 'string',
'format': 'ssh_private_key',
'secret': True,
'multiline': True,
'help_text': ugettext_noop('Paste the contents of the PEM file associated ' 'with the service account email.'),
'help_text': gettext_noop('Paste the contents of the PEM file associated ' 'with the service account email.'),
},
],
'required': ['username', 'ssh_key_data'],
@@ -872,36 +872,36 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='azure_rm',
kind='cloud',
name=ugettext_noop('Microsoft Azure Resource Manager'),
name=gettext_noop('Microsoft Azure Resource Manager'),
managed=True,
inputs={
'fields': [
{
'id': 'subscription',
'label': ugettext_noop('Subscription ID'),
'label': gettext_noop('Subscription ID'),
'type': 'string',
'help_text': ugettext_noop('Subscription ID is an Azure construct, which is ' 'mapped to a username.'),
'help_text': gettext_noop('Subscription ID is an Azure construct, which is ' 'mapped to a username.'),
},
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{
'id': 'password',
'label': ugettext_noop('Password'),
'label': gettext_noop('Password'),
'type': 'string',
'secret': True,
},
{'id': 'client', 'label': ugettext_noop('Client ID'), 'type': 'string'},
{'id': 'client', 'label': gettext_noop('Client ID'), 'type': 'string'},
{
'id': 'secret',
'label': ugettext_noop('Client Secret'),
'label': gettext_noop('Client Secret'),
'type': 'string',
'secret': True,
},
{'id': 'tenant', 'label': ugettext_noop('Tenant ID'), 'type': 'string'},
{'id': 'tenant', 'label': gettext_noop('Tenant ID'), 'type': 'string'},
{
'id': 'cloud_environment',
'label': ugettext_noop('Azure Cloud Environment'),
'label': gettext_noop('Azure Cloud Environment'),
'type': 'string',
'help_text': ugettext_noop('Environment variable AZURE_CLOUD_ENVIRONMENT when' ' using Azure GovCloud or Azure stack.'),
'help_text': gettext_noop('Environment variable AZURE_CLOUD_ENVIRONMENT when' ' using Azure GovCloud or Azure stack.'),
},
],
'required': ['subscription'],
@@ -911,16 +911,16 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='github_token',
kind='token',
name=ugettext_noop('GitHub Personal Access Token'),
name=gettext_noop('GitHub Personal Access Token'),
managed=True,
inputs={
'fields': [
{
'id': 'token',
'label': ugettext_noop('Token'),
'label': gettext_noop('Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('This token needs to come from your profile settings in GitHub'),
'help_text': gettext_noop('This token needs to come from your profile settings in GitHub'),
}
],
'required': ['token'],
@@ -930,16 +930,16 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='gitlab_token',
kind='token',
name=ugettext_noop('GitLab Personal Access Token'),
name=gettext_noop('GitLab Personal Access Token'),
managed=True,
inputs={
'fields': [
{
'id': 'token',
'label': ugettext_noop('Token'),
'label': gettext_noop('Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('This token needs to come from your profile settings in GitLab'),
'help_text': gettext_noop('This token needs to come from your profile settings in GitLab'),
}
],
'required': ['token'],
@@ -949,12 +949,12 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='insights',
kind='insights',
name=ugettext_noop('Insights'),
name=gettext_noop('Insights'),
managed=True,
inputs={
'fields': [
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'password', 'label': ugettext_noop('Password'), 'type': 'string', 'secret': True},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{'id': 'password', 'label': gettext_noop('Password'), 'type': 'string', 'secret': True},
],
'required': ['username', 'password'],
},
@@ -973,23 +973,23 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='rhv',
kind='cloud',
name=ugettext_noop('Red Hat Virtualization'),
name=gettext_noop('Red Hat Virtualization'),
managed=True,
inputs={
'fields': [
{'id': 'host', 'label': ugettext_noop('Host (Authentication URL)'), 'type': 'string', 'help_text': ugettext_noop('The host to authenticate with.')},
{'id': 'username', 'label': ugettext_noop('Username'), 'type': 'string'},
{'id': 'host', 'label': gettext_noop('Host (Authentication URL)'), 'type': 'string', 'help_text': gettext_noop('The host to authenticate with.')},
{'id': 'username', 'label': gettext_noop('Username'), 'type': 'string'},
{
'id': 'password',
'label': ugettext_noop('Password'),
'label': gettext_noop('Password'),
'type': 'string',
'secret': True,
},
{
'id': 'ca_file',
'label': ugettext_noop('CA File'),
'label': gettext_noop('CA File'),
'type': 'string',
'help_text': ugettext_noop('Absolute file path to the CA file to use (optional)'),
'help_text': gettext_noop('Absolute file path to the CA file to use (optional)'),
},
],
'required': ['host', 'username', 'password'],
@@ -1017,38 +1017,38 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='controller',
kind='cloud',
name=ugettext_noop('Red Hat Ansible Automation Platform'),
name=gettext_noop('Red Hat Ansible Automation Platform'),
managed=True,
inputs={
'fields': [
{
'id': 'host',
'label': ugettext_noop('Red Hat Ansible Automation Platform'),
'label': gettext_noop('Red Hat Ansible Automation Platform'),
'type': 'string',
'help_text': ugettext_noop('Red Hat Ansible Automation Platform base URL to authenticate with.'),
'help_text': gettext_noop('Red Hat Ansible Automation Platform base URL to authenticate with.'),
},
{
'id': 'username',
'label': ugettext_noop('Username'),
'label': gettext_noop('Username'),
'type': 'string',
'help_text': ugettext_noop(
'help_text': gettext_noop(
'Red Hat Ansible Automation Platform username id to authenticate as.' 'This should not be set if an OAuth token is being used.'
),
},
{
'id': 'password',
'label': ugettext_noop('Password'),
'label': gettext_noop('Password'),
'type': 'string',
'secret': True,
},
{
'id': 'oauth_token',
'label': ugettext_noop('OAuth Token'),
'label': gettext_noop('OAuth Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('An OAuth token to use to authenticate with.' 'This should not be set if username/password are being used.'),
'help_text': gettext_noop('An OAuth token to use to authenticate with.' 'This should not be set if username/password are being used.'),
},
{'id': 'verify_ssl', 'label': ugettext_noop('Verify SSL'), 'type': 'boolean', 'secret': False},
{'id': 'verify_ssl', 'label': gettext_noop('Verify SSL'), 'type': 'boolean', 'secret': False},
],
'required': ['host'],
},
@@ -1071,30 +1071,30 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='kubernetes_bearer_token',
kind='kubernetes',
name=ugettext_noop('OpenShift or Kubernetes API Bearer Token'),
name=gettext_noop('OpenShift or Kubernetes API Bearer Token'),
inputs={
'fields': [
{
'id': 'host',
'label': ugettext_noop('OpenShift or Kubernetes API Endpoint'),
'label': gettext_noop('OpenShift or Kubernetes API Endpoint'),
'type': 'string',
'help_text': ugettext_noop('The OpenShift or Kubernetes API Endpoint to authenticate with.'),
'help_text': gettext_noop('The OpenShift or Kubernetes API Endpoint to authenticate with.'),
},
{
'id': 'bearer_token',
'label': ugettext_noop('API authentication bearer token'),
'label': gettext_noop('API authentication bearer token'),
'type': 'string',
'secret': True,
},
{
'id': 'verify_ssl',
'label': ugettext_noop('Verify SSL'),
'label': gettext_noop('Verify SSL'),
'type': 'boolean',
'default': True,
},
{
'id': 'ssl_ca_cert',
'label': ugettext_noop('Certificate Authority data'),
'label': gettext_noop('Certificate Authority data'),
'type': 'string',
'secret': True,
'multiline': True,
@@ -1107,31 +1107,31 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='registry',
kind='registry',
name=ugettext_noop('Container Registry'),
name=gettext_noop('Container Registry'),
inputs={
'fields': [
{
'id': 'host',
'label': ugettext_noop('Authentication URL'),
'label': gettext_noop('Authentication URL'),
'type': 'string',
'help_text': ugettext_noop('Authentication endpoint for the container registry.'),
'help_text': gettext_noop('Authentication endpoint for the container registry.'),
'default': 'quay.io',
},
{
'id': 'username',
'label': ugettext_noop('Username'),
'label': gettext_noop('Username'),
'type': 'string',
},
{
'id': 'password',
'label': ugettext_noop('Password or Token'),
'label': gettext_noop('Password or Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('A password or token used to authenticate with'),
'help_text': gettext_noop('A password or token used to authenticate with'),
},
{
'id': 'verify_ssl',
'label': ugettext_noop('Verify SSL'),
'label': gettext_noop('Verify SSL'),
'type': 'boolean',
'default': True,
},
@@ -1144,27 +1144,27 @@ ManagedCredentialType(
ManagedCredentialType(
namespace='galaxy_api_token',
kind='galaxy',
name=ugettext_noop('Ansible Galaxy/Automation Hub API Token'),
name=gettext_noop('Ansible Galaxy/Automation Hub API Token'),
inputs={
'fields': [
{
'id': 'url',
'label': ugettext_noop('Galaxy Server URL'),
'label': gettext_noop('Galaxy Server URL'),
'type': 'string',
'help_text': ugettext_noop('The URL of the Galaxy instance to connect to.'),
'help_text': gettext_noop('The URL of the Galaxy instance to connect to.'),
},
{
'id': 'auth_url',
'label': ugettext_noop('Auth Server URL'),
'label': gettext_noop('Auth Server URL'),
'type': 'string',
'help_text': ugettext_noop('The URL of a Keycloak server token_endpoint, if using ' 'SSO auth.'),
'help_text': gettext_noop('The URL of a Keycloak server token_endpoint, if using ' 'SSO auth.'),
},
{
'id': 'token',
'label': ugettext_noop('API Token'),
'label': gettext_noop('API Token'),
'type': 'string',
'secret': True,
'help_text': ugettext_noop('A token to use for authentication against the Galaxy instance.'),
'help_text': gettext_noop('A token to use for authentication against the Galaxy instance.'),
},
],
'required': ['url'],

View File

@@ -10,13 +10,13 @@ from django.db import models, DatabaseError, connection
from django.utils.dateparse import parse_datetime
from django.utils.text import Truncator
from django.utils.timezone import utc, now
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import force_text
from django.utils.translation import gettext_lazy as _
from django.utils.encoding import force_str
from awx.api.versioning import reverse
from awx.main import consumers
from awx.main.fields import JSONBlob
from awx.main.managers import DeferJobCreatedManager
from awx.main.fields import JSONField
from awx.main.constants import MINIMAL_EVENTS
from awx.main.models.base import CreatedModifiedModel
from awx.main.utils import ignore_inventory_computed_fields, camelcase_to_underscore
@@ -209,10 +209,7 @@ class BasePlaybookEvent(CreatedModifiedModel):
max_length=100,
choices=EVENT_CHOICES,
)
event_data = JSONField(
blank=True,
default=dict,
)
event_data = JSONBlob(default=dict, blank=True)
failed = models.BooleanField(
default=False,
editable=False,
@@ -396,7 +393,7 @@ class BasePlaybookEvent(CreatedModifiedModel):
connection.on_commit(_send_notifications)
for field in ('playbook', 'play', 'task', 'role'):
value = force_text(event_data.get(field, '')).strip()
value = force_str(event_data.get(field, '')).strip()
if value != getattr(self, field):
setattr(self, field, value)
if settings.LOG_AGGREGATOR_ENABLED:
@@ -648,10 +645,7 @@ class BaseCommandEvent(CreatedModifiedModel):
class Meta:
abstract = True
event_data = JSONField(
blank=True,
default=dict,
)
event_data = JSONBlob(default=dict, blank=True)
uuid = models.CharField(
max_length=1024,
default='',

View File

@@ -1,5 +1,5 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from awx.api.versioning import reverse
from awx.main.models.base import CommonModel

View File

@@ -9,7 +9,7 @@ from django.core.validators import MinValueValidator
from django.db import models, connection
from django.db.models.signals import post_save, post_delete
from django.dispatch import receiver
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.conf import settings
from django.utils.timezone import now, timedelta
@@ -19,7 +19,6 @@ from solo.models import SingletonModel
from awx import __version__ as awx_application_version
from awx.api.versioning import reverse
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.models.base import BaseModel, HasEditsMixin, prevent_search
from awx.main.models.unified_jobs import UnifiedJob
@@ -253,7 +252,7 @@ class Instance(HasPolicyEditsMixin, BaseModel):
if uuid is not None and self.uuid != uuid:
if self.uuid is not None:
logger.warn(f'Self-reported uuid of {self.hostname} changed from {self.uuid} to {uuid}')
logger.warning(f'Self-reported uuid of {self.hostname} changed from {self.uuid} to {uuid}')
self.uuid = uuid
update_fields.append('uuid')
@@ -328,8 +327,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_minimum = models.IntegerField(default=0, help_text=_("Static minimum number of Instances to automatically assign to this group"))
policy_instance_list = JSONField(
default=[], blank=True, help_text=_("List of exact-match Instances that will always be automatically assigned to this group")
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")
)
POLICY_FIELDS = frozenset(('policy_instance_list', 'policy_instance_minimum', 'policy_instance_percentage'))

View File

@@ -14,7 +14,7 @@ import yaml
# Django
from django.conf import settings
from django.db import models, connection
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.db import transaction
from django.core.exceptions import ValidationError
from django.utils.timezone import now
@@ -29,7 +29,6 @@ from awx.main.constants import CLOUD_PROVIDERS
from awx.main.consumers import emit_channel_notification
from awx.main.fields import (
ImplicitRoleField,
JSONBField,
SmartFilterField,
OrderedManyToManyField,
)
@@ -488,7 +487,7 @@ class Host(CommonModelNameNotUnique, RelatedJobsMixin):
editable=False,
help_text=_('Inventory source(s) that created or modified this host.'),
)
ansible_facts = JSONBField(
ansible_facts = models.JSONField(
blank=True,
default=dict,
help_text=_('Arbitrary JSON structure of most recent ansible_facts, per-host.'),

View File

@@ -19,7 +19,7 @@ from django.db import models
# from django.core.cache import cache
from django.utils.encoding import smart_str
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import FieldDoesNotExist
# REST Framework
@@ -44,7 +44,7 @@ from awx.main.models.notifications import (
JobNotificationMixin,
)
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 (
ResourceMixin,
SurveyJobTemplateMixin,
@@ -546,9 +546,10 @@ class Job(UnifiedJob, JobOptions, SurveyJobMixin, JobNotificationMixin, TaskMana
editable=False,
through='JobHostSummary',
)
artifacts = JSONField(
blank=True,
artifacts = models.JSONField(
default=dict,
null=True,
blank=True,
editable=False,
)
scm_revision = models.CharField(
@@ -885,7 +886,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 = JSONField(blank=True, default=dict)
char_prompts = models.JSONField(default=dict, null=True, blank=True)
def prompts_dict(self, display=False):
data = {}
@@ -938,12 +939,13 @@ class LaunchTimeConfig(LaunchTimeConfigBase):
abstract = True
# 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(
JSONField(
blank=True,
models.JSONField(
default=dict,
editable=False,
null=True,
blank=True,
)
)
# Credentials needed for non-unified job / unified JT models

View File

@@ -3,7 +3,7 @@
# Django
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
# AWX
from awx.api.versioning import reverse

View File

@@ -15,7 +15,7 @@ from django.core.exceptions import ValidationError
from django.db import models
from django.db.models.query import QuerySet
from django.utils.crypto import get_random_string
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
# AWX
from awx.main.models.base import prevent_search
@@ -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 JSONField, AskForField
from awx.main.fields import AskForField
from awx.main.constants import ACTIVE_STATES
@@ -103,12 +103,7 @@ class SurveyJobTemplateMixin(models.Model):
survey_enabled = models.BooleanField(
default=False,
)
survey_spec = prevent_search(
JSONField(
blank=True,
default=dict,
)
)
survey_spec = prevent_search(models.JSONField(default=dict, blank=True))
ask_variables_on_launch = AskForField(blank=True, default=False, allows_field='extra_vars')
def survey_password_variables(self):
@@ -370,10 +365,11 @@ class SurveyJobMixin(models.Model):
abstract = True
survey_passwords = prevent_search(
JSONField(
blank=True,
models.JSONField(
default=dict,
editable=False,
null=True,
blank=True,
)
)

View File

@@ -10,8 +10,8 @@ from django.db import models
from django.conf import settings
from django.core.mail.message import EmailMessage
from django.db import connection
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_str, force_text
from django.utils.translation import gettext_lazy as _
from django.utils.encoding import smart_str, force_str
from jinja2 import sandbox, ChainableUndefined
from jinja2.exceptions import TemplateSyntaxError, UndefinedError, SecurityError
@@ -28,7 +28,6 @@ from awx.main.notifications.mattermost_backend import MattermostBackend
from awx.main.notifications.grafana_backend import GrafanaBackend
from awx.main.notifications.rocketchat_backend import RocketChatBackend
from awx.main.notifications.irc_backend import IrcBackend
from awx.main.fields import JSONField
logger = logging.getLogger('awx.main.models.notifications')
@@ -70,12 +69,12 @@ class NotificationTemplate(CommonModelNameNotUnique):
choices=NOTIFICATION_TYPE_CHOICES,
)
notification_configuration = prevent_search(JSONField(blank=False))
notification_configuration = prevent_search(models.JSONField(default=dict))
def default_messages():
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):
potential_template = self.messages.get(condition, {})
@@ -187,7 +186,7 @@ class NotificationTemplate(CommonModelNameNotUnique):
def display_notification_configuration(self):
field_val = self.notification_configuration.copy()
for field in self.notification_class.init_parameters:
if field in field_val and force_text(field_val[field]).startswith('$encrypted$'):
if field in field_val and force_str(field_val[field]).startswith('$encrypted$'):
field_val[field] = '$encrypted$'
return field_val
@@ -237,7 +236,7 @@ class Notification(CreatedModifiedModel):
default='',
editable=False,
)
body = JSONField(blank=True)
body = models.JSONField(default=dict, null=True, blank=True)
def get_absolute_url(self, request=None):
return reverse('api:notification_detail', kwargs={'pk': self.pk}, request=request)
@@ -515,7 +514,7 @@ class JobNotificationMixin(object):
try:
notification_templates = self.get_notification_templates()
except Exception:
logger.warn("No notification template defined for emitting notification")
logger.warning("No notification template defined for emitting notification")
return
if not notification_templates:

View File

@@ -6,7 +6,7 @@ import re
from django.core.validators import RegexValidator
from django.db import models, connection
from django.utils.timezone import now
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.conf import settings
# Django OAuth Toolkit

View File

@@ -8,7 +8,7 @@ from django.db import models
from django.contrib.auth.models import User
from django.contrib.sessions.models import Session
from django.utils.timezone import now as tz_now
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
# AWX

View File

@@ -9,8 +9,8 @@ import urllib.parse as urlparse
# Django
from django.conf import settings
from django.db import models
from django.utils.translation import ugettext_lazy as _
from django.utils.encoding import smart_str, smart_text
from django.utils.translation import gettext_lazy as _
from django.utils.encoding import smart_str
from django.utils.text import slugify
from django.core.exceptions import ValidationError
from django.utils.timezone import now, make_aware, get_default_timezone
@@ -38,7 +38,6 @@ from awx.main.models.rbac import (
ROLE_SINGLETON_SYSTEM_ADMINISTRATOR,
ROLE_SINGLETON_SYSTEM_AUDITOR,
)
from awx.main.fields import JSONField
__all__ = ['Project', 'ProjectUpdate']
@@ -214,7 +213,7 @@ class ProjectOptions(models.Model):
for filename in filenames:
playbook = could_be_playbook(project_path, dirpath, filename)
if playbook is not None:
results.append(smart_text(playbook))
results.append(smart_str(playbook))
return sorted(results, key=lambda x: smart_str(x).lower())
@property
@@ -230,7 +229,7 @@ class ProjectOptions(models.Model):
for filename in filenames:
inv_path = could_be_inventory(project_path, dirpath, filename)
if inv_path is not None:
results.append(smart_text(inv_path))
results.append(smart_str(inv_path))
if len(results) > max_inventory_listing:
break
if len(results) > max_inventory_listing:
@@ -294,17 +293,17 @@ class Project(UnifiedJobTemplate, ProjectOptions, ResourceMixin, CustomVirtualEn
help_text=_('The last revision fetched by a project update'),
)
playbook_files = JSONField(
playbook_files = models.JSONField(
default=list,
blank=True,
default=[],
editable=False,
verbose_name=_('Playbook Files'),
help_text=_('List of playbooks found in the project'),
)
inventory_files = JSONField(
inventory_files = models.JSONField(
default=list,
blank=True,
default=[],
editable=False,
verbose_name=_('Inventory Files'),
help_text=_('Suggested list of content that could be Ansible inventory in the project'),

View File

@@ -11,7 +11,7 @@ import re
from django.db import models, transaction, connection
from django.contrib.contenttypes.models import ContentType
from django.contrib.contenttypes.fields import GenericForeignKey
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
# AWX
from awx.api.versioning import reverse

View File

@@ -14,7 +14,7 @@ from dateutil.zoneinfo import get_zonefile_instance
from django.db import models
from django.db.models.query import QuerySet
from django.utils.timezone import now, make_aware
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
# AWX
from awx.api.versioning import reverse
@@ -103,7 +103,7 @@ class Schedule(PrimordialModel, LaunchTimeConfig):
for zone in all_zones:
if fname.endswith(zone):
return zone
logger.warn('Could not detect valid zoneinfo for {}'.format(self.rrule))
logger.warning('Could not detect valid zoneinfo for {}'.format(self.rrule))
return ''
@property

View File

@@ -19,9 +19,9 @@ from collections import OrderedDict
from django.conf import settings
from django.db import models, connection
from django.core.exceptions import NON_FIELD_ERRORS
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.utils.timezone import now
from django.utils.encoding import smart_text
from django.utils.encoding import smart_str
from django.contrib.contenttypes.models import ContentType
# REST Framework
@@ -54,7 +54,7 @@ from awx.main.utils import polymorphic
from awx.main.constants import ACTIVE_STATES, CAN_CANCEL
from awx.main.redact import UriCleaner, REPLACE_STR
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']
@@ -357,7 +357,7 @@ class UnifiedJobTemplate(PolymorphicModel, CommonModelNameNotUnique, ExecutionEn
validated_kwargs = kwargs.copy()
if unallowed_fields:
if parent_field_name is None:
logger.warn('Fields {} are not allowed as overrides to spawn from {}.'.format(', '.join(unallowed_fields), self))
logger.warning('Fields {} are not allowed as overrides to spawn from {}.'.format(', '.join(unallowed_fields), self))
for f in unallowed_fields:
validated_kwargs.pop(f)
@@ -653,9 +653,10 @@ class UnifiedJob(
editable=False,
)
job_env = prevent_search(
JSONField(
blank=True,
models.JSONField(
default=dict,
null=True,
blank=True,
editable=False,
)
)
@@ -704,7 +705,7 @@ class UnifiedJob(
'Credential',
related_name='%(class)ss',
)
installed_collections = JSONBField(
installed_collections = models.JSONField(
blank=True,
default=dict,
editable=False,
@@ -1090,7 +1091,7 @@ class UnifiedJob(
# function assume a str-based fd will be returned; decode
# .write() calls on the fly to maintain this interface
_write = fd.write
fd.write = lambda s: _write(smart_text(s))
fd.write = lambda s: _write(smart_str(s))
tbl = self._meta.db_table + 'event'
created_by_cond = ''
if self.has_unpartitioned_events:
@@ -1205,7 +1206,7 @@ class UnifiedJob(
try:
extra_data_dict = parse_yaml_or_json(extra_data, silent_failure=False)
except Exception as e:
logger.warn("Exception deserializing extra vars: " + str(e))
logger.warning("Exception deserializing extra vars: " + str(e))
evars = self.extra_vars_dict
evars.update(extra_data_dict)
self.update_fields(extra_vars=json.dumps(evars))
@@ -1273,7 +1274,7 @@ class UnifiedJob(
id=self.id,
name=self.name,
url=self.get_ui_url(),
created_by=smart_text(self.created_by),
created_by=smart_str(self.created_by),
started=self.started.isoformat() if self.started is not None else None,
finished=self.finished.isoformat() if self.finished is not None else None,
status=self.status,

View File

@@ -11,7 +11,7 @@ from urllib.parse import urljoin
# Django
from django.db import connection, models
from django.conf import settings
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import gettext_lazy as _
from django.core.exceptions import ObjectDoesNotExist
# from django import settings as tower_settings
@@ -40,7 +40,6 @@ from awx.main.models.mixins import (
from awx.main.models.jobs import LaunchTimeConfigBase, LaunchTimeConfig, JobTemplate
from awx.main.models.credential import Credential
from awx.main.redact import REPLACE_STR
from awx.main.fields import JSONField
from awx.main.utils import schedule_task_manager
@@ -232,9 +231,10 @@ class WorkflowJobNode(WorkflowNodeBase):
default=None,
on_delete=models.CASCADE,
)
ancestor_artifacts = JSONField(
blank=True,
ancestor_artifacts = models.JSONField(
default=dict,
null=True,
blank=True,
editable=False,
)
do_not_run = models.BooleanField(