From 72195702539add107605d9244c0fe29ead1afd56 Mon Sep 17 00:00:00 2001 From: Grant Gainey Date: Tue, 10 Sep 2024 20:02:20 -0400 Subject: [PATCH] DRAFT pulp_labels POC --- pulp_file/app/viewsets.py | 2 +- .../migrations/0123_content_pulp_labels.py | 19 +++++++++++++++++++ pulpcore/app/models/content.py | 3 +++ pulpcore/app/serializers/content.py | 6 ++++-- pulpcore/app/viewsets/content.py | 12 ++++++++++-- 5 files changed, 37 insertions(+), 5 deletions(-) create mode 100644 pulpcore/app/migrations/0123_content_pulp_labels.py diff --git a/pulp_file/app/viewsets.py b/pulp_file/app/viewsets.py index 214d310f819..05d8dd95d28 100644 --- a/pulp_file/app/viewsets.py +++ b/pulp_file/app/viewsets.py @@ -82,7 +82,7 @@ class FileContentViewSet(SingleArtifactContentUploadViewSet): "effect": "allow", }, { - "action": ["create"], + "action": ["create", "set_label", "unset_label"], "principal": "authenticated", "effect": "allow", "condition": [ diff --git a/pulpcore/app/migrations/0123_content_pulp_labels.py b/pulpcore/app/migrations/0123_content_pulp_labels.py new file mode 100644 index 00000000000..de9d4de0daa --- /dev/null +++ b/pulpcore/app/migrations/0123_content_pulp_labels.py @@ -0,0 +1,19 @@ +# Generated by Django 4.2.15 on 2024-09-08 23:15 + +import django.contrib.postgres.fields.hstore +from django.db import migrations + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0122_record_last_replication_timestamp'), + ] + + operations = [ + migrations.AddField( + model_name='content', + name='pulp_labels', + field=django.contrib.postgres.fields.hstore.HStoreField(default=dict), + ), + ] diff --git a/pulpcore/app/models/content.py b/pulpcore/app/models/content.py index 5205715cab4..2d4c8b46f81 100644 --- a/pulpcore/app/models/content.py +++ b/pulpcore/app/models/content.py @@ -16,6 +16,7 @@ from itertools import chain from django.conf import settings +from django.contrib.postgres.fields import HStoreField from django.core import validators from django.db import IntegrityError, models, transaction from django.forms.models import model_to_dict @@ -515,6 +516,7 @@ class Content(MasterModel, QueryMixin): Fields: upstream_id (models.UUIDField) : identifier of content imported from an 'upstream' Pulp timestamp_of_interest (models.DateTimeField): timestamp that prevents orphan cleanup + pulp_labels (HStoreField): Dictionary of string values. Relations: @@ -528,6 +530,7 @@ class Content(MasterModel, QueryMixin): TYPE = "content" repo_key_fields = () # Used by pulpcore.plugin.repo_version_utils.remove_duplicates upstream_id = models.UUIDField(null=True) # Used by PulpImport/Export processing + pulp_labels = HStoreField(default=dict) _artifacts = models.ManyToManyField(Artifact, through="ContentArtifact") timestamp_of_interest = models.DateTimeField(auto_now=True) diff --git a/pulpcore/app/serializers/content.py b/pulpcore/app/serializers/content.py index a7ec3ee312a..5f1282db79e 100644 --- a/pulpcore/app/serializers/content.py +++ b/pulpcore/app/serializers/content.py @@ -5,12 +5,14 @@ from rest_framework.validators import UniqueValidator from pulpcore.app import models -from pulpcore.app.serializers import base, fields, DetailRelatedField +from pulpcore.app.serializers import base, fields, pulp_labels_validator, DetailRelatedField from pulpcore.app.util import get_domain class NoArtifactContentSerializer(base.ModelSerializer): pulp_href = base.DetailIdentityField(view_name_pattern=r"contents(-.*/.*)-detail") + pulp_labels = serializers.HStoreField(required=False, validators=[pulp_labels_validator]) + repository = DetailRelatedField( help_text=_("A URI of a repository the new content unit should be associated with."), required=False, @@ -104,7 +106,7 @@ def create(self, validated_data): class Meta: model = models.Content - fields = base.ModelSerializer.Meta.fields + ("repository",) + fields = base.ModelSerializer.Meta.fields + ("repository", "pulp_labels",) class SingleArtifactContentSerializer(NoArtifactContentSerializer): diff --git a/pulpcore/app/viewsets/content.py b/pulpcore/app/viewsets/content.py index 8e49e487a27..d1487121c0d 100644 --- a/pulpcore/app/viewsets/content.py +++ b/pulpcore/app/viewsets/content.py @@ -15,7 +15,8 @@ SigningServiceSerializer, ) from pulpcore.app.util import get_viewset_for_model -from pulpcore.app.viewsets.base import NamedModelViewSet +from pulpcore.app.viewsets.base import NamedModelViewSet, LabelsMixin +from pulpcore.app.viewsets.custom_filters import LabelFilter from .custom_filters import ( ArtifactRepositoryVersionFilter, @@ -127,6 +128,8 @@ class ContentFilter(BaseFilterSet): orphaned_for: Return Content which has been orphaned for a given number of minutes; -1 uses ORPHAN_PROTECTION_TIME value. + pulp_label_select: + Return Content which has has the specified label """ repository_version = ContentRepositoryVersionFilter() @@ -135,6 +138,7 @@ class ContentFilter(BaseFilterSet): orphaned_for = OrphanedFilter( help_text="Minutes Content has been orphaned for. -1 uses ORPHAN_PROTECTION_TIME." ) + pulp_label_select = LabelFilter() class BaseContentViewSet(NamedModelViewSet): @@ -199,7 +203,11 @@ def routable(cls): class ContentViewSet( - BaseContentViewSet, mixins.CreateModelMixin, mixins.RetrieveModelMixin, mixins.ListModelMixin + BaseContentViewSet, + mixins.CreateModelMixin, + mixins.RetrieveModelMixin, + mixins.ListModelMixin, + LabelsMixin ): """ Content viewset that supports POST and GET by default.