From d80759cd7ac3d042bbe3ff7e37132ee56181cc98 Mon Sep 17 00:00:00 2001 From: Martin Slemr Date: Fri, 3 Feb 2023 14:22:21 +0100 Subject: [PATCH] HostMetrics migration --- awx/api/serializers.py | 13 +++++- awx/api/urls/host_metric.py | 4 +- awx/api/views/__init__.py | 10 ++++- awx/main/access.py | 8 +--- .../migrations/0175_add_hostmetric_fields.py | 43 +++++++++++++++++++ awx/main/models/inventory.py | 12 +++++- 6 files changed, 79 insertions(+), 11 deletions(-) create mode 100644 awx/main/migrations/0175_add_hostmetric_fields.py diff --git a/awx/api/serializers.py b/awx/api/serializers.py index 7770838735..5989adb4db 100644 --- a/awx/api/serializers.py +++ b/awx/api/serializers.py @@ -5392,7 +5392,18 @@ class HostMetricSerializer(BaseSerializer): class Meta: model = HostMetric - fields = ("hostname", "first_automation", "last_automation") + fields = ( + "id", + "hostname", + "url", + "first_automation", + "last_automation", + "last_deleted", + "automated_counter", + "deleted_counter", + "deleted", + "used_in_inventories", + ) class InstanceGroupSerializer(BaseSerializer): diff --git a/awx/api/urls/host_metric.py b/awx/api/urls/host_metric.py index 547c995c10..d464fb82c5 100644 --- a/awx/api/urls/host_metric.py +++ b/awx/api/urls/host_metric.py @@ -3,8 +3,8 @@ from django.urls import re_path -from awx.api.views import HostMetricList +from awx.api.views import HostMetricList, HostMetricDetail -urls = [re_path(r'$^', HostMetricList.as_view(), name='host_metric_list')] +urls = [re_path(r'$^', HostMetricList.as_view(), name='host_metric_list'), re_path(r'^(?P[0-9]+)/$', HostMetricDetail.as_view(), name='host_metric_detail')] __all__ = ['urls'] diff --git a/awx/api/views/__init__.py b/awx/api/views/__init__.py index 729f993b74..1845b55c2e 100644 --- a/awx/api/views/__init__.py +++ b/awx/api/views/__init__.py @@ -1549,10 +1549,18 @@ class HostRelatedSearchMixin(object): class HostMetricList(ListAPIView): - always_allow_superuser = False name = _("Host Metrics List") model = models.HostMetric serializer_class = serializers.HostMetricSerializer + permission_classes = (IsSystemAdminOrAuditor,) + search_fields = ('hostname', 'deleted') + + +class HostMetricDetail(RetrieveDestroyAPIView): + name = _("Host Metric Detail") + model = models.HostMetric + serializer_class = serializers.HostMetricSerializer + permission_classes = (IsSystemAdminOrAuditor,) class HostList(HostRelatedSearchMixin, ListCreateAPIView): diff --git a/awx/main/access.py b/awx/main/access.py index 938619119e..185ab1e061 100644 --- a/awx/main/access.py +++ b/awx/main/access.py @@ -886,17 +886,13 @@ class OrganizationAccess(NotificationAttachMixin, BaseAccess): class HostMetricAccess(BaseAccess): """ - - I can see host metrics when a super user or system auditor. - - I can delete host metrics when a super user. + - I can see host metrics when I'm a super user or system auditor. + - I can delete host metrics when I'm a super user. """ model = HostMetric def get_queryset(self): - # if self.user.is_superuser or self.user.is_system_auditor: - # return self.model.objects.filter(Q(user__isnull=True) | Q(user=self.user)) - # else: - # return self.model.objects.filter(user=self.user) if self.user.is_superuser or self.user.is_system_auditor: qs = self.model.objects.all() else: diff --git a/awx/main/migrations/0175_add_hostmetric_fields.py b/awx/main/migrations/0175_add_hostmetric_fields.py new file mode 100644 index 0000000000..d273a6b6ea --- /dev/null +++ b/awx/main/migrations/0175_add_hostmetric_fields.py @@ -0,0 +1,43 @@ +# Generated by Django 3.2.16 on 2023-02-03 09:40 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ('main', '0174_ensure_org_ee_admin_roles'), + ] + + operations = [ + migrations.AlterField(model_name='hostmetric', name='hostname', field=models.CharField(max_length=512, primary_key=False, serialize=True, unique=True)), + migrations.AddField( + model_name='hostmetric', + name='last_deleted', + field=models.DateTimeField(db_index=True, null=True, help_text='When the host was last deleted'), + ), + migrations.AddField( + model_name='hostmetric', + name='automated_counter', + field=models.BigIntegerField(default=0, help_text='How many times was the host automated'), + ), + migrations.AddField( + model_name='hostmetric', + name='deleted_counter', + field=models.BigIntegerField(default=0, help_text='How many times was the host deleted'), + ), + migrations.AddField( + model_name='hostmetric', + name='deleted', + field=models.BooleanField( + default=False, help_text='Boolean flag saying whether the host is deleted and therefore not counted into the subscription consumption' + ), + ), + migrations.AddField( + model_name='hostmetric', + name='used_in_inventories', + field=models.BigIntegerField(null=True, help_text='How many inventories contain this host'), + ), + migrations.AddField( + model_name='hostmetric', name='id', field=models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID') + ), + ] diff --git a/awx/main/models/inventory.py b/awx/main/models/inventory.py index 7b55c51851..577c03645c 100644 --- a/awx/main/models/inventory.py +++ b/awx/main/models/inventory.py @@ -820,9 +820,19 @@ class Group(CommonModelNameNotUnique, RelatedJobsMixin): class HostMetric(models.Model): - hostname = models.CharField(primary_key=True, max_length=512) + hostname = models.CharField(unique=True, max_length=512) first_automation = models.DateTimeField(auto_now_add=True, null=False, db_index=True, help_text=_('When the host was first automated against')) last_automation = models.DateTimeField(db_index=True, help_text=_('When the host was last automated against')) + last_deleted = models.DateTimeField(null=True, db_index=True, help_text=_('When the host was last deleted')) + automated_counter = models.BigIntegerField(default=0, help_text=_('How many times was the host automated')) + deleted_counter = models.BigIntegerField(default=0, help_text=_('How many times was the host deleted')) + deleted = models.BooleanField( + default=False, help_text=_('Boolean flag saying whether the host is deleted and therefore not counted into the subscription consumption') + ) + used_in_inventories = models.BigIntegerField(null=True, help_text=_('How many inventories contain this host')) + + def get_absolute_url(self, request=None): + return reverse('api:host_metric_detail', kwargs={'pk': self.pk}, request=request) class InventorySourceOptions(BaseModel):