Skip to content

Commit

Permalink
Add labels to domains
Browse files Browse the repository at this point in the history
fixes: #6236
  • Loading branch information
gerrod3 committed Feb 3, 2025
1 parent 21f2c21 commit cecae09
Show file tree
Hide file tree
Showing 6 changed files with 71 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGES/6236.feature
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Added support for labels on domains.
19 changes: 19 additions & 0 deletions pulpcore/app/migrations/0128_domain_pulp_labels.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# Generated by Django 4.2.16 on 2025-02-03 16:41

import django.contrib.postgres.fields.hstore
from django.db import migrations


class Migration(migrations.Migration):

dependencies = [
("core", "0127_remove_upstreampulp_pulp_label_select"),
]

operations = [
migrations.AddField(
model_name="domain",
name="pulp_labels",
field=django.contrib.postgres.fields.hstore.HStoreField(default=dict),
),
]
3 changes: 3 additions & 0 deletions pulpcore/app/models/domain.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
from django.core.files.storage import default_storage
from django.db import models
from django.contrib.postgres.fields import HStoreField
from django_lifecycle import hook, BEFORE_DELETE, BEFORE_UPDATE

from pulpcore.app.models import BaseModel, AutoAddObjPermsMixin
Expand All @@ -25,6 +26,7 @@ class Domain(BaseModel, AutoAddObjPermsMixin):
Fields:
name (models.SlugField): Unique name of domain
pulp_labels (HStoreField): Dictionary of string values
description (models.TextField): Optional description of domain
storage_class (models.TextField): Required storage class for backend
storage_settings (EncryptedJSONField): Settings needed to configure storage backend
Expand All @@ -33,6 +35,7 @@ class Domain(BaseModel, AutoAddObjPermsMixin):
"""

name = models.SlugField(null=False, unique=True)
pulp_labels = HStoreField(default=dict)
description = models.TextField(null=True)
# Storage class is required, optional settings are validated by serializer
storage_class = models.TextField(null=False)
Expand Down
9 changes: 8 additions & 1 deletion pulpcore/app/serializers/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,12 @@
from rest_framework.validators import UniqueValidator

from pulpcore.app.models import Domain
from pulpcore.app.serializers import IdentityField, ModelSerializer, HiddenFieldsMixin
from pulpcore.app.serializers import (
IdentityField,
ModelSerializer,
HiddenFieldsMixin,
pulp_labels_validator,
)


BACKEND_CHOICES = (
Expand Down Expand Up @@ -433,6 +438,7 @@ class DomainSerializer(BackendSettingsValidator, ModelSerializer):
description = serializers.CharField(
help_text=_("An optional description."), required=False, allow_null=True
)
pulp_labels = serializers.HStoreField(required=False, validators=[pulp_labels_validator])
storage_class = serializers.ChoiceField(
help_text=_("Backend storage class for domain."),
choices=BACKEND_CHOICES,
Expand Down Expand Up @@ -484,6 +490,7 @@ class Meta:
fields = ModelSerializer.Meta.fields + (
"name",
"description",
"pulp_labels",
"storage_class",
"storage_settings",
"redirect_to_object_storage",
Expand Down
6 changes: 5 additions & 1 deletion pulpcore/app/viewsets/domain.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,14 +14,17 @@
AsyncOperationResponseSerializer,
)
from pulpcore.app.tasks import migrate_backend
from pulpcore.app.viewsets import NamedModelViewSet, AsyncRemoveMixin, AsyncUpdateMixin
from pulpcore.app.viewsets import NamedModelViewSet, AsyncRemoveMixin, AsyncUpdateMixin, LabelsMixin
from pulpcore.app.viewsets.base import NAME_FILTER_OPTIONS
from pulpcore.app.viewsets.custom_filters import LabelFilter
from pulpcore.tasking.tasks import dispatch


class DomainFilter(BaseFilterSet):
"""FilterSet for Domain."""

pulp_label_select = LabelFilter()

class Meta:
model = Domain
fields = {"name": NAME_FILTER_OPTIONS}
Expand All @@ -34,6 +37,7 @@ class DomainViewSet(
mixins.RetrieveModelMixin,
AsyncUpdateMixin,
AsyncRemoveMixin,
LabelsMixin,
):
"""
ViewSet for Domain.
Expand Down
35 changes: 35 additions & 0 deletions pulpcore/tests/functional/api/test_crud_domains.py
Original file line number Diff line number Diff line change
Expand Up @@ -308,3 +308,38 @@ def test_special_domain_creation(pulpcore_bindings, gen_object_with_cleanup, pul
domain = gen_object_with_cleanup(pulpcore_bindings.DomainsApi, body, pulp_domain=random_name)
assert "default/api/v3/" in domain.pulp_href
assert random_name not in domain.pulp_href


@pytest.mark.parallel
def test_filter_domains_by_label(pulpcore_bindings, gen_object_with_cleanup):
"""Test filtering domains by label."""
# Create domains with different labels
body_a = {
"name": str(uuid.uuid4()),
"storage_class": "pulpcore.app.models.storage.FileSystem",
"storage_settings": {"MEDIA_ROOT": "/var/lib/pulp/media/"},
"pulp_labels": {"key_a": "label_a"}
}
domain_a = gen_object_with_cleanup(pulpcore_bindings.DomainsApi, body_a)

body_b = {
"name": str(uuid.uuid4()),
"storage_class": "pulpcore.app.models.storage.FileSystem",
"storage_settings": {"MEDIA_ROOT": "/var/lib/pulp/media/"},
"pulp_labels": {"key_b": "label_b"}
}
domain_b = gen_object_with_cleanup(pulpcore_bindings.DomainsApi, body_b)

# Filter by label key
domains = pulpcore_bindings.DomainsApi.list(pulp_label_select="key_a").results
assert len(domains) == 1
assert domains[0].pulp_href == domain_a.pulp_href

# Filter by label value
domains = pulpcore_bindings.DomainsApi.list(pulp_label_select="key_b=label_b").results
assert len(domains) == 1
assert domains[0].pulp_href == domain_b.pulp_href

# Filter by non-existent label
domains = pulpcore_bindings.DomainsApi.list(pulp_label_select="key_c").results
assert len(domains) == 0

0 comments on commit cecae09

Please sign in to comment.