diff --git a/app/config_management/migrations/0011_remove_configgroupsoftware_is_global_and_more.py b/app/config_management/migrations/0011_remove_configgroupsoftware_is_global_and_more.py new file mode 100644 index 00000000..8a7e383d --- /dev/null +++ b/app/config_management/migrations/0011_remove_configgroupsoftware_is_global_and_more.py @@ -0,0 +1,122 @@ +# Generated by Django 5.1.9 on 2025-06-06 02:43 + +import access.models.tenancy_abstract +import django.db.models.deletion +from django.db import migrations, models + + +class Migration(migrations.Migration): + + dependencies = [ + ("access", "0012_teamusers_model_notes_alter_teamusers_id_and_more"), + ("config_management", "0010_remove_configgroupsoftware_is_global_and_more"), + ("core", "0028_delete_history"), + ] + + operations = [ + migrations.RemoveField( + model_name="configgroupsoftware", + name="is_global", + ), + migrations.AlterField( + model_name="configgroupsoftware", + name="id", + field=models.AutoField( + help_text="ID of the item", + primary_key=True, + serialize=False, + unique=True, + verbose_name="ID", + ), + ), + migrations.AlterField( + model_name="configgroupsoftware", + name="model_notes", + field=models.TextField( + blank=True, + help_text="Tid bits of information", + null=True, + verbose_name="Notes", + ), + ), + migrations.AlterField( + model_name="configgroupsoftware", + name="organization", + field=models.ForeignKey( + help_text="Tenant this belongs to", + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="access.tenant", + validators=[ + access.models.tenancy_abstract.TenancyAbstractModel.validatate_organization_exists + ], + verbose_name="Tenant", + ), + ), + migrations.CreateModel( + name="ConfigGroupSoftwareAuditHistory", + fields=[ + ( + "centurionaudit_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.centurionaudit", + ), + ), + ( + "model", + models.ForeignKey( + help_text="Model this history belongs to", + on_delete=django.db.models.deletion.CASCADE, + related_name="audit_history", + to="config_management.configgroupsoftware", + verbose_name="Model", + ), + ), + ], + options={ + "verbose_name": "Config Group Software History", + "verbose_name_plural": "Config Group Software Histories", + "db_table": "config_management_configgroupsoftware_audithistory", + "managed": True, + }, + bases=("core.centurionaudit", models.Model), + ), + migrations.CreateModel( + name="ConfigGroupSoftwareCenturionModelNote", + fields=[ + ( + "centurionmodelnote_ptr", + models.OneToOneField( + auto_created=True, + on_delete=django.db.models.deletion.CASCADE, + parent_link=True, + primary_key=True, + serialize=False, + to="core.centurionmodelnote", + ), + ), + ( + "model", + models.ForeignKey( + help_text="Model this note belongs to", + on_delete=django.db.models.deletion.CASCADE, + related_name="+", + to="config_management.configgroupsoftware", + verbose_name="Model", + ), + ), + ], + options={ + "verbose_name": "Config Group Software Note", + "verbose_name_plural": "Config Group Software Notes", + "db_table": "config_management_configgroupsoftware_centurionmodelnote", + "managed": True, + }, + bases=("core.centurionmodelnote", models.Model), + ), + ] diff --git a/app/config_management/models/groups.py b/app/config_management/models/groups.py index 4d8f2568..99ceadaf 100644 --- a/app/config_management/models/groups.py +++ b/app/config_management/models/groups.py @@ -233,7 +233,7 @@ class ConfigGroups( for key, value in value.items(): key: str = str(key).lower() - + key = re.sub('\s|\.|\-', '_', key) # make an '_' char if type(value) is dict: @@ -289,7 +289,7 @@ class ConfigGroups( for software in softwares: if software.action: - + if int(software.action) == 1: state = 'present' @@ -309,7 +309,8 @@ class ConfigGroups( software_actions['software'] = software_actions['software'] + [ software_action ] - if len(software_actions['software']) > 0: # don't add empty software as it prevents parent software from being added + if len(software_actions['software']) > 0: + # don't add empty software as it prevents parent software from being added if 'software' not in config.keys(): @@ -332,6 +333,9 @@ class ConfigGroups( +class ConfigGroupHosts( + CenturionModel, +): def validate_host_no_parent_group(self): @@ -342,7 +346,10 @@ class ConfigGroups( """ if False: - raise ValidationError(f'host {self} is already a member of this chain as it;s a member of group ""') + raise ValidationError( + message = f'host {self} ' \ + 'is already a member of this chain as it;s a member of group ""' + ) host = models.ForeignKey( @@ -365,30 +372,14 @@ class ConfigGroups( verbose_name = 'Group', ) - - def get_url_kwargs_notes(self): - - return FeatureNotUsed + modified = AutoLastModifiedField() @property def parent_object(self): """ Fetch the parent object """ - + return self.group - def save_history(self, before: dict, after: dict) -> bool: - - from config_management.models.config_groups_hosts_history import ConfigGroupHostsHistory - - history = super().save_history( - before = before, - after = after, - history_model = ConfigGroupHostsHistory, - ) - - - return history - class ConfigGroupSoftware( diff --git a/app/config_management/serializers/centurionaudit_configgrouphosts.py b/app/config_management/serializers/centurionaudit_configgrouphosts.py new file mode 100644 index 00000000..2bc9a2e3 --- /dev/null +++ b/app/config_management/serializers/centurionaudit_configgrouphosts.py @@ -0,0 +1,56 @@ +from rest_framework import serializers + +from drf_spectacular.utils import extend_schema_serializer + +from api.serializers import common + +from centurion.models.meta import ConfigGroupHostsAuditHistory # pylint: disable=E0401:import-error disable=E0611:no-name-in-module + +from core.serializers.centurionaudit import ( + BaseSerializer, + ViewSerializer as AuditHistoryViewSerializer +) + + + + +@extend_schema_serializer(component_name = 'ConfigGroupHostsAuditHistoryModelSerializer') +class ModelSerializer( + common.CommonModelSerializer, + BaseSerializer +): + """Git Group Audit History Base Model""" + + + _urls = serializers.SerializerMethodField('get_url') + + + class Meta: + + model = ConfigGroupHostsAuditHistory + + fields = [ + 'id', + 'organization', + 'display_name', + 'content_type', + 'model', + 'before', + 'after', + 'action', + 'user', + 'created', + '_urls', + ] + + read_only_fields = fields + + + +@extend_schema_serializer(component_name = 'ConfigGroupHostsAuditHistoryViewSerializer') +class ViewSerializer( + ModelSerializer, + AuditHistoryViewSerializer, +): + """Git Group Audit History Base View Model""" + pass diff --git a/app/config_management/serializers/centurionmodelnote_configgrouphosts.py b/app/config_management/serializers/centurionmodelnote_configgrouphosts.py new file mode 100644 index 00000000..d16aa18b --- /dev/null +++ b/app/config_management/serializers/centurionmodelnote_configgrouphosts.py @@ -0,0 +1,87 @@ +from rest_framework import serializers + +from drf_spectacular.utils import extend_schema_serializer + +from access.serializers.organization import (TenantBaseSerializer) + +from centurion.models.meta import ConfigGroupHostsCenturionModelNote # pylint: disable=E0401:import-error disable=E0611:no-name-in-module + +from core.serializers.centurionmodelnote import ( # pylint: disable=W0611:unused-import + BaseSerializer, + ModelSerializer as BaseModelModelSerializer, + ViewSerializer as BaseModelViewSerializer +) + + + +@extend_schema_serializer(component_name = 'ConfigGroupHostsModelNoteModelSerializer') +class ModelSerializer( + BaseModelModelSerializer, +): + + + _urls = serializers.SerializerMethodField('get_url') + + def get_url(self, item) -> dict: + + return { + '_self': item.get_url( request = self._context['view'].request ), + } + + + class Meta: + + model = ConfigGroupHostsCenturionModelNote + + fields = [ + 'id', + 'organization', + 'display_name', + 'body', + 'created_by', + 'modified_by', + 'content_type', + 'model', + 'created', + 'modified', + '_urls', + ] + + read_only_fields = [ + 'id', + 'display_name', + 'organization', + 'created_by', + 'modified_by', + 'content_type', + 'model', + 'created', + 'modified', + '_urls', + ] + + + + def validate(self, attrs): + + is_valid = False + + note_model = self.Meta.model.model.field.related_model + + attrs['model'] = note_model.objects.get( + id = int( self.context['view'].kwargs['model_id'] ) + ) + + + is_valid = super().validate(attrs) + + return is_valid + + +@extend_schema_serializer(component_name = 'ConfigGroupHostsModelNoteViewSerializer') +class ViewSerializer( + ModelSerializer, + BaseModelViewSerializer, +): + + organization = TenantBaseSerializer( many = False, read_only = True )