mirror of
https://github.com/ZwareBear/awx.git
synced 2026-04-19 14:31:48 -05:00
Add migration to carry out corresponding schema change Add data migration to delete inventory sources which are the custom type Split migration into two files data migration touches same rows as schema migration
112 lines
4.7 KiB
Python
112 lines
4.7 KiB
Python
import logging
|
|
|
|
from django.utils.encoding import smart_text
|
|
|
|
from awx.main.utils.common import set_current_apps
|
|
from awx.main.utils.common import parse_yaml_or_json
|
|
|
|
logger = logging.getLogger('awx.main.migrations')
|
|
|
|
|
|
def _get_instance_id(from_dict, new_id, default=''):
|
|
"""logic mostly duplicated with inventory_import command Command._get_instance_id
|
|
frozen in time here, for purposes of migrations
|
|
"""
|
|
instance_id = default
|
|
for key in new_id.split('.'):
|
|
if not hasattr(from_dict, 'get'):
|
|
instance_id = default
|
|
break
|
|
instance_id = from_dict.get(key, default)
|
|
from_dict = instance_id
|
|
return smart_text(instance_id)
|
|
|
|
|
|
def _get_instance_id_for_upgrade(host, new_id):
|
|
if host.instance_id:
|
|
# this should not have happened, but nothing to really do about it...
|
|
logger.debug('Unexpectedly, host {}-{} has instance_id set'.format(host.name, host.pk))
|
|
return None
|
|
host_vars = parse_yaml_or_json(host.variables)
|
|
new_id_value = _get_instance_id(host_vars, new_id)
|
|
if not new_id_value:
|
|
# another source type with overwrite_vars or pesky users could have done this
|
|
logger.info('Host {}-{} has no {} var, probably due to separate modifications'.format(host.name, host.pk, new_id))
|
|
return None
|
|
if len(new_id) > 255:
|
|
# this should never happen
|
|
logger.warn('Computed instance id "{}"" for host {}-{} is too long'.format(new_id_value, host.name, host.pk))
|
|
return None
|
|
return new_id_value
|
|
|
|
|
|
def set_new_instance_id(apps, source, new_id):
|
|
"""This methods adds an instance_id in cases where there was not one before"""
|
|
from django.conf import settings
|
|
|
|
id_from_settings = getattr(settings, '{}_INSTANCE_ID_VAR'.format(source.upper()))
|
|
if id_from_settings != new_id:
|
|
# User applied an instance ID themselves, so nope on out of there
|
|
logger.warn('You have an instance ID set for {}, not migrating'.format(source))
|
|
return
|
|
logger.debug('Migrating inventory instance_id for {} to {}'.format(source, new_id))
|
|
Host = apps.get_model('main', 'Host')
|
|
modified_ct = 0
|
|
for host in Host.objects.filter(inventory_sources__source=source).iterator():
|
|
new_id_value = _get_instance_id_for_upgrade(host, new_id)
|
|
if not new_id_value:
|
|
continue
|
|
host.instance_id = new_id_value
|
|
host.save(update_fields=['instance_id'])
|
|
modified_ct += 1
|
|
if modified_ct:
|
|
logger.info('Migrated instance ID for {} hosts imported by {} source'.format(modified_ct, source))
|
|
|
|
|
|
def back_out_new_instance_id(apps, source, new_id):
|
|
Host = apps.get_model('main', 'Host')
|
|
modified_ct = 0
|
|
for host in Host.objects.filter(inventory_sources__source=source).iterator():
|
|
host_vars = parse_yaml_or_json(host.variables)
|
|
predicted_id_value = _get_instance_id(host_vars, new_id)
|
|
if predicted_id_value != host.instance_id:
|
|
logger.debug('Host {}-{} did not get its instance_id from {}, skipping'.format(host.name, host.pk, new_id))
|
|
continue
|
|
host.instance_id = ''
|
|
host.save(update_fields=['instance_id'])
|
|
modified_ct += 1
|
|
if modified_ct:
|
|
logger.info('Reverse migrated instance ID for {} hosts imported by {} source'.format(modified_ct, source))
|
|
|
|
|
|
def delete_cloudforms_inv_source(apps, schema_editor):
|
|
set_current_apps(apps)
|
|
InventorySource = apps.get_model('main', 'InventorySource')
|
|
InventoryUpdate = apps.get_model('main', 'InventoryUpdate')
|
|
CredentialType = apps.get_model('main', 'CredentialType')
|
|
InventoryUpdate.objects.filter(inventory_source__source='cloudforms').delete()
|
|
InventorySource.objects.filter(source='cloudforms').delete()
|
|
ct = CredentialType.objects.filter(namespace='cloudforms').first()
|
|
if ct:
|
|
ct.credentials.all().delete()
|
|
ct.delete()
|
|
|
|
|
|
def delete_custom_inv_source(apps, schema_editor):
|
|
set_current_apps(apps)
|
|
InventorySource = apps.get_model('main', 'InventorySource')
|
|
InventoryUpdate = apps.get_model('main', 'InventoryUpdate')
|
|
ct, deletions = InventoryUpdate.objects.filter(source='custom').delete()
|
|
if ct:
|
|
logger.info('deleted {}'.format((ct, deletions)))
|
|
update_ct = deletions['main.InventoryUpdate']
|
|
if update_ct:
|
|
logger.info('Deleted {} custom inventory script sources.'.format(update_ct))
|
|
ct, deletions = InventorySource.objects.filter(source='custom').delete()
|
|
if ct:
|
|
logger.info('deleted {}'.format((ct, deletions)))
|
|
src_ct = deletions['main.InventorySource']
|
|
if src_ct:
|
|
logger.info('Deleted {} custom inventory script updates.'.format(src_ct))
|
|
logger.warning('Custom inventory scripts have been removed, see awx-manage XXXXX')
|