mirror of
https://github.com/ansible/awx.git
synced 2026-05-20 07:17:40 -02:30
Merge pull request #6645 from ansible/fallback-test
Fix reencryption migrations.
This commit is contained in:
@@ -102,4 +102,6 @@ def encrypt_field(instance, field_name, ask=False, subfield=None, skip_utf8=Fals
|
|||||||
|
|
||||||
|
|
||||||
def should_decrypt_field(value):
|
def should_decrypt_field(value):
|
||||||
return value.startswith('$encrypted$') and '$AESCBC$' not in value
|
if hasattr(value, 'startswith'):
|
||||||
|
return value.startswith('$encrypted$') and '$AESCBC$' not in value
|
||||||
|
return False
|
||||||
|
|||||||
@@ -22,6 +22,7 @@ from awx.main.utils import encrypt_field, decrypt_field
|
|||||||
from awx.main.utils.db import get_tower_migration_version
|
from awx.main.utils.db import get_tower_migration_version
|
||||||
from awx.conf import settings_registry
|
from awx.conf import settings_registry
|
||||||
from awx.conf.models import Setting
|
from awx.conf.models import Setting
|
||||||
|
from awx.conf.migrations._reencrypt import decrypt_field as old_decrypt_field
|
||||||
|
|
||||||
# FIXME: Gracefully handle when settings are accessed before the database is
|
# FIXME: Gracefully handle when settings are accessed before the database is
|
||||||
# ready (or during migrations).
|
# ready (or during migrations).
|
||||||
@@ -245,7 +246,13 @@ class SettingsWrapper(UserSettingsHolder):
|
|||||||
if settings_to_cache[setting.key] != SETTING_CACHE_NOTSET:
|
if settings_to_cache[setting.key] != SETTING_CACHE_NOTSET:
|
||||||
continue
|
continue
|
||||||
if self.registry.is_setting_encrypted(setting.key):
|
if self.registry.is_setting_encrypted(setting.key):
|
||||||
value = decrypt_field(setting, 'value')
|
try:
|
||||||
|
value = decrypt_field(setting, 'value')
|
||||||
|
except ValueError, e:
|
||||||
|
#TODO: Remove in Tower 3.3
|
||||||
|
logger.debug('encountered error decrypting field: %s - attempting fallback to old', e)
|
||||||
|
value = old_decrypt_field(setting, 'value')
|
||||||
|
|
||||||
else:
|
else:
|
||||||
value = setting.value
|
value = setting.value
|
||||||
settings_to_cache[setting.key] = get_cache_value(value)
|
settings_to_cache[setting.key] = get_cache_value(value)
|
||||||
|
|||||||
@@ -1,13 +1,32 @@
|
|||||||
|
from django.utils.translation import ugettext_lazy as _
|
||||||
|
|
||||||
from awx.main import utils
|
from awx.main import utils
|
||||||
from awx.conf.migrations._reencrypt import (
|
from awx.conf.migrations._reencrypt import (
|
||||||
decrypt_field,
|
decrypt_field,
|
||||||
should_decrypt_field,
|
should_decrypt_field,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
from awx.main.notifications.email_backend import CustomEmailBackend
|
||||||
|
from awx.main.notifications.slack_backend import SlackBackend
|
||||||
|
from awx.main.notifications.twilio_backend import TwilioBackend
|
||||||
|
from awx.main.notifications.pagerduty_backend import PagerDutyBackend
|
||||||
|
from awx.main.notifications.hipchat_backend import HipChatBackend
|
||||||
|
from awx.main.notifications.webhook_backend import WebhookBackend
|
||||||
|
from awx.main.notifications.irc_backend import IrcBackend
|
||||||
|
from awx.main.models.credential import Credential
|
||||||
|
|
||||||
__all__ = ['replace_aesecb_fernet']
|
__all__ = ['replace_aesecb_fernet']
|
||||||
|
|
||||||
|
|
||||||
|
NOTIFICATION_TYPES = [('email', _('Email'), CustomEmailBackend),
|
||||||
|
('slack', _('Slack'), SlackBackend),
|
||||||
|
('twilio', _('Twilio'), TwilioBackend),
|
||||||
|
('pagerduty', _('Pagerduty'), PagerDutyBackend),
|
||||||
|
('hipchat', _('HipChat'), HipChatBackend),
|
||||||
|
('webhook', _('Webhook'), WebhookBackend),
|
||||||
|
('irc', _('IRC'), IrcBackend)]
|
||||||
|
|
||||||
|
|
||||||
def replace_aesecb_fernet(apps, schema_editor):
|
def replace_aesecb_fernet(apps, schema_editor):
|
||||||
_notification_templates(apps)
|
_notification_templates(apps)
|
||||||
_credentials(apps)
|
_credentials(apps)
|
||||||
@@ -17,8 +36,10 @@ def replace_aesecb_fernet(apps, schema_editor):
|
|||||||
def _notification_templates(apps):
|
def _notification_templates(apps):
|
||||||
NotificationTemplate = apps.get_model('main', 'NotificationTemplate')
|
NotificationTemplate = apps.get_model('main', 'NotificationTemplate')
|
||||||
for nt in NotificationTemplate.objects.all():
|
for nt in NotificationTemplate.objects.all():
|
||||||
for field in filter(lambda x: nt.notification_class.init_parameters[x]['type'] == "password",
|
CLASS_FOR_NOTIFICATION_TYPE = dict([(x[0], x[2]) for x in NOTIFICATION_TYPES])
|
||||||
nt.notification_class.init_parameters):
|
notification_class = CLASS_FOR_NOTIFICATION_TYPE[nt.notification_type]
|
||||||
|
for field in filter(lambda x: notification_class.init_parameters[x]['type'] == "password",
|
||||||
|
notification_class.init_parameters):
|
||||||
if should_decrypt_field(nt.notification_configuration[field]):
|
if should_decrypt_field(nt.notification_configuration[field]):
|
||||||
value = decrypt_field(nt, 'notification_configuration', subfield=field)
|
value = decrypt_field(nt, 'notification_configuration', subfield=field)
|
||||||
nt.notification_configuration[field] = value
|
nt.notification_configuration[field] = value
|
||||||
@@ -26,21 +47,14 @@ def _notification_templates(apps):
|
|||||||
|
|
||||||
|
|
||||||
def _credentials(apps):
|
def _credentials(apps):
|
||||||
# this monkey-patch is necessary to make the implicit role generation save
|
# TODO: Try to not use the model directly imported from our
|
||||||
# signal use the correct Role model (the version active at this point in
|
# source (should use apps.get_model) to make the migration less britle.
|
||||||
# migration, not the one at HEAD)
|
for credential in Credential.objects.all():
|
||||||
orig_current_apps = utils.get_current_apps
|
for field_name, value in credential.inputs.items():
|
||||||
try:
|
if should_decrypt_field(value):
|
||||||
utils.get_current_apps = lambda: apps
|
value = decrypt_field(credential, field_name)
|
||||||
for credential in apps.get_model('main', 'Credential').objects.all():
|
credential.inputs[field_name] = value
|
||||||
for field_name, value in credential.inputs.items():
|
credential.save()
|
||||||
if should_decrypt_field(value):
|
|
||||||
value = decrypt_field(credential, field_name)
|
|
||||||
credential.inputs[field_name] = value
|
|
||||||
credential.save()
|
|
||||||
finally:
|
|
||||||
utils.get_current_apps = orig_current_apps
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def _unified_jobs(apps):
|
def _unified_jobs(apps):
|
||||||
|
|||||||
Reference in New Issue
Block a user