Remove ForeignKey relations involving CustomInventoryScript

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
This commit is contained in:
Alan Rominger
2021-04-15 09:45:14 -04:00
parent 33b6da4456
commit 8440e3f41d
9 changed files with 135 additions and 35 deletions

View File

@@ -43,7 +43,7 @@ from polymorphic.models import PolymorphicModel
# AWX
from awx.main.access import get_user_capabilities
from awx.main.constants import SCHEDULEABLE_PROVIDERS, ACTIVE_STATES, CENSOR_VALUE
from awx.main.constants import ACTIVE_STATES, CENSOR_VALUE
from awx.main.models import (
ActivityStream,
AdHocCommand,
@@ -91,6 +91,7 @@ from awx.main.models import (
WorkflowJobTemplate,
WorkflowJobTemplateNode,
StdoutMaxBytesExceeded,
CLOUD_INVENTORY_SOURCES,
)
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
@@ -4761,7 +4762,7 @@ class ScheduleSerializer(LaunchConfigurationBaseSerializer, SchedulePreviewSeria
return summary_fields
def validate_unified_job_template(self, value):
if type(value) == InventorySource and value.source not in SCHEDULEABLE_PROVIDERS:
if type(value) == InventorySource and value.source not in CLOUD_INVENTORY_SOURCES:
raise serializers.ValidationError(_('Inventory Source must be a cloud resource.'))
elif type(value) == Project and value.scm_type == '':
raise serializers.ValidationError(_('Manual Project cannot have a schedule set.'))

View File

@@ -7,7 +7,6 @@ from django.utils.translation import ugettext_lazy as _
__all__ = [
'CLOUD_PROVIDERS',
'SCHEDULEABLE_PROVIDERS',
'PRIVILEGE_ESCALATION_METHODS',
'ANSI_SGR_PATTERN',
'CAN_CANCEL',
@@ -16,10 +15,6 @@ __all__ = [
]
CLOUD_PROVIDERS = ('azure_rm', 'ec2', 'gce', 'vmware', 'openstack', 'rhv', 'satellite6', 'tower')
SCHEDULEABLE_PROVIDERS = CLOUD_PROVIDERS + (
'custom',
'scm',
)
PRIVILEGE_ESCALATION_METHODS = [
('sudo', _('Sudo')),
('su', _('Su')),

View File

@@ -0,0 +1,19 @@
# Generated by Django 2.2.16 on 2021-04-13 19:51
from django.db import migrations
# AWX migration utils
from awx.main.migrations._rbac import delete_all_custom_script_roles
from awx.main.migrations._inventory_source import delete_custom_inv_source
class Migration(migrations.Migration):
dependencies = [
('main', '0135_schedule_sort_fallback_to_id'),
]
operations = [
migrations.RunPython(delete_custom_inv_source),
migrations.RunPython(delete_all_custom_script_roles),
]

View File

@@ -0,0 +1,81 @@
# Generated by Django 2.2.16 on 2021-04-13 19:51
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('main', '0136_custom_inventory_scripts_removal_data'),
]
operations = [
migrations.RemoveField(
model_name='activitystream',
name='custom_inventory_script',
),
migrations.RemoveField(
model_name='inventorysource',
name='source_script',
),
migrations.RemoveField(
model_name='inventoryupdate',
name='source_script',
),
migrations.AlterField(
model_name='inventorysource',
name='source',
field=models.CharField(
choices=[
('file', 'File, Directory or Script'),
('scm', 'Sourced from a Project'),
('ec2', 'Amazon EC2'),
('gce', 'Google Compute Engine'),
('azure_rm', 'Microsoft Azure Resource Manager'),
('vmware', 'VMware vCenter'),
('satellite6', 'Red Hat Satellite 6'),
('openstack', 'OpenStack'),
('rhv', 'Red Hat Virtualization'),
('tower', 'Ansible Tower'),
],
default=None,
max_length=32,
),
),
migrations.AlterField(
model_name='inventoryupdate',
name='source',
field=models.CharField(
choices=[
('file', 'File, Directory or Script'),
('scm', 'Sourced from a Project'),
('ec2', 'Amazon EC2'),
('gce', 'Google Compute Engine'),
('azure_rm', 'Microsoft Azure Resource Manager'),
('vmware', 'VMware vCenter'),
('satellite6', 'Red Hat Satellite 6'),
('openstack', 'OpenStack'),
('rhv', 'Red Hat Virtualization'),
('tower', 'Ansible Tower'),
],
default=None,
max_length=32,
),
),
migrations.AlterUniqueTogether(
name='custominventoryscript',
unique_together=set(),
),
migrations.RemoveField(
model_name='custominventoryscript',
name='admin_role',
),
migrations.RemoveField(
model_name='custominventoryscript',
name='organization',
),
migrations.RemoveField(
model_name='custominventoryscript',
name='read_role',
),
]

View File

@@ -90,3 +90,22 @@ def delete_cloudforms_inv_source(apps, schema_editor):
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')

View File

@@ -47,6 +47,18 @@ def delete_all_user_roles(apps, schema_editor):
role.delete()
def delete_all_custom_script_roles(apps, schema_editor):
ContentType = apps.get_model('contenttypes', "ContentType")
Role = apps.get_model('main', "Role")
cis_type = ContentType.objects.get(model='custominventoryscript')
role_ct = 0
for role in Role.objects.filter(content_type=cis_type).iterator():
role.delete()
role_ct += 1
if role_ct:
logger.debug('Deleted roles corresponding to custom inventory sources.')
UNIFIED_ORG_LOOKUPS = {
# Job Templates had an implicit organization via their project
'jobtemplate': 'project',

View File

@@ -74,8 +74,6 @@ class ActivityStream(models.Model):
unified_job = models.ManyToManyField("UnifiedJob", blank=True, related_name='activity_stream_as_unified_job+')
ad_hoc_command = models.ManyToManyField("AdHocCommand", blank=True)
schedule = models.ManyToManyField("Schedule", blank=True)
# TODO: migrate away
custom_inventory_script = models.ManyToManyField("CustomInventoryScript", blank=True)
execution_environment = models.ManyToManyField("ExecutionEnvironment", blank=True)
notification_template = models.ManyToManyField("NotificationTemplate", blank=True)
notification = models.ManyToManyField("Notification", blank=True)

View File

@@ -62,7 +62,7 @@ PROJECT_UPDATE_JOB_TYPE_CHOICES = [
(PERM_INVENTORY_CHECK, _('Check')),
]
CLOUD_INVENTORY_SOURCES = list(CLOUD_PROVIDERS) + ['scm', 'custom']
CLOUD_INVENTORY_SOURCES = list(CLOUD_PROVIDERS) + ['scm']
VERBOSITY_CHOICES = [
(0, '0 (Normal)'),

View File

@@ -821,7 +821,6 @@ class InventorySourceOptions(BaseModel):
('openstack', _('OpenStack')),
('rhv', _('Red Hat Virtualization')),
('tower', _('Ansible Tower')),
('custom', _('Custom Script')),
]
# From the options of the Django management base command
@@ -845,14 +844,6 @@ class InventorySourceOptions(BaseModel):
blank=True,
default='',
)
# TODO: migrate away
source_script = models.ForeignKey(
'CustomInventoryScript',
null=True,
default=None,
blank=True,
on_delete=models.SET_NULL,
)
source_vars = models.TextField(
blank=True,
default='',
@@ -1329,7 +1320,6 @@ class InventoryUpdate(UnifiedJob, InventorySourceOptions, JobNotificationMixin,
class CustomInventoryScript(CommonModelNameNotUnique, ResourceMixin):
class Meta:
app_label = 'main'
unique_together = [('name', 'organization')]
ordering = ('name',)
script = prevent_search(
@@ -1339,21 +1329,6 @@ class CustomInventoryScript(CommonModelNameNotUnique, ResourceMixin):
help_text=_('Inventory script contents'),
)
)
organization = models.ForeignKey(
'Organization',
related_name='custom_inventory_scripts',
help_text=_('Organization owning this inventory script'),
blank=False,
null=True,
on_delete=models.SET_NULL,
)
admin_role = ImplicitRoleField(
parent_role='organization.admin_role',
)
read_role = ImplicitRoleField(
parent_role=['organization.auditor_role', 'organization.member_role', 'admin_role'],
)
def get_absolute_url(self, request=None):
return reverse('api:inventory_script_detail', kwargs={'pk': self.pk}, request=request)