diff --git a/CHANGES/3008.feature b/CHANGES/3008.feature new file mode 100644 index 0000000000..56c7c5eba2 --- /dev/null +++ b/CHANGES/3008.feature @@ -0,0 +1 @@ +Added support for Domains. diff --git a/pulp_rpm/app/__init__.py b/pulp_rpm/app/__init__.py index 7d579dcf94..593103479f 100644 --- a/pulp_rpm/app/__init__.py +++ b/pulp_rpm/app/__init__.py @@ -10,3 +10,4 @@ class PulpRpmPluginAppConfig(PulpPluginAppConfig): label = "rpm" version = "3.20.0.dev" python_package_name = "pulp-rpm" + domain_compatible = True diff --git a/pulp_rpm/app/migrations/0049_domains.py b/pulp_rpm/app/migrations/0049_domains.py new file mode 100644 index 0000000000..3ee3bda90f --- /dev/null +++ b/pulp_rpm/app/migrations/0049_domains.py @@ -0,0 +1,115 @@ +# Generated by Django 3.2.18 on 2023-04-05 16:39 + +from django.db import migrations, models +import django.db.models.deletion +import pulpcore.app.util + + +class Migration(migrations.Migration): + + dependencies = [ + ('core', '0102_add_domain_relations'), + ('rpm', '0048_artifacts_dependencies_fix'), + ] + + operations = [ + migrations.AddField( + model_name='distributiontree', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_distributiontree', to='core.domain'), + ), + migrations.AddField( + model_name='modulemd', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_modulemd', to='core.domain'), + ), + migrations.AddField( + model_name='modulemddefaults', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_modulemddefaults', to='core.domain'), + ), + migrations.AddField( + model_name='modulemdobsolete', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_modulemdobsolete', to='core.domain'), + ), + migrations.AddField( + model_name='package', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_package', to='core.domain'), + ), + migrations.AddField( + model_name='packagecategory', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_packagecategory', to='core.domain'), + ), + migrations.AddField( + model_name='packageenvironment', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_packageenvironment', to='core.domain'), + ), + migrations.AddField( + model_name='packagegroup', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_packagegroup', to='core.domain'), + ), + migrations.AddField( + model_name='packagelangpacks', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_packagelangpacks', to='core.domain'), + ), + migrations.AddField( + model_name='repometadatafile', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_repometadatafile', to='core.domain'), + ), + migrations.AddField( + model_name='updaterecord', + name='_pulp_domain', + field=models.ForeignKey(default=pulpcore.app.util.get_domain_pk, on_delete=django.db.models.deletion.PROTECT, related_name='rpm_updaterecord', to='core.domain'), + ), + migrations.AlterUniqueTogether( + name='distributiontree', + unique_together={('_pulp_domain', 'digest')}, + ), + migrations.AlterUniqueTogether( + name='modulemd', + unique_together={('_pulp_domain', 'name', 'stream', 'version', 'context', 'arch')}, + ), + migrations.AlterUniqueTogether( + name='modulemddefaults', + unique_together={('_pulp_domain', 'digest')}, + ), + migrations.AlterUniqueTogether( + name='modulemdobsolete', + unique_together={('_pulp_domain', 'modified', 'module_name', 'module_stream')}, + ), + migrations.AlterUniqueTogether( + name='package', + unique_together={('_pulp_domain', 'name', 'epoch', 'version', 'release', 'arch', 'checksum_type', 'pkgId')}, + ), + migrations.AlterUniqueTogether( + name='packagecategory', + unique_together={('_pulp_domain', 'digest')}, + ), + migrations.AlterUniqueTogether( + name='packageenvironment', + unique_together={('_pulp_domain', 'digest')}, + ), + migrations.AlterUniqueTogether( + name='packagegroup', + unique_together={('_pulp_domain', 'digest')}, + ), + migrations.AlterUniqueTogether( + name='packagelangpacks', + unique_together={('_pulp_domain', 'digest')}, + ), + migrations.AlterUniqueTogether( + name='repometadatafile', + unique_together={('_pulp_domain', 'data_type', 'checksum', 'relative_path')}, + ), + migrations.AlterUniqueTogether( + name='updaterecord', + unique_together={('_pulp_domain', 'digest')}, + ), + ] diff --git a/pulp_rpm/app/models/advisory.py b/pulp_rpm/app/models/advisory.py index ac87d5f5eb..8cc2b2757c 100644 --- a/pulp_rpm/app/models/advisory.py +++ b/pulp_rpm/app/models/advisory.py @@ -8,6 +8,7 @@ BaseModel, Content, ) +from pulpcore.plugin.util import get_domain_pk from pulp_rpm.app.constants import ( CR_UPDATE_COLLECTION_ATTRS, @@ -102,6 +103,8 @@ class UpdateRecord(Content): # UpdateCollection or UpdateCollectionPackage. digest = models.TextField(unique=True) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + @classmethod def natural_key_fields(cls): """ @@ -228,6 +231,7 @@ def get_module_list(self): class Meta: default_related_name = "%(app_label)s_%(model_name)s" + unique_together = ("_pulp_domain", "digest") class UpdateCollection(BaseModel): diff --git a/pulp_rpm/app/models/comps.py b/pulp_rpm/app/models/comps.py index 0641498f3b..9cf9129fd6 100644 --- a/pulp_rpm/app/models/comps.py +++ b/pulp_rpm/app/models/comps.py @@ -5,6 +5,7 @@ from django.db import models from pulpcore.plugin.models import Content +from pulpcore.plugin.util import get_domain_pk from pulp_rpm.app.constants import ( LIBCOMPS_CATEGORY_ATTRS, @@ -77,8 +78,11 @@ class PackageGroup(Content): repo_key_fields = ("id",) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + class Meta: default_related_name = "%(app_label)s_%(model_name)s" + unique_together = ("_pulp_domain", "digest") @classmethod def natural_key_fields(cls): @@ -234,8 +238,11 @@ class PackageCategory(Content): repo_key_fields = ("id",) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + class Meta: default_related_name = "%(app_label)s_%(model_name)s" + unique_together = ("_pulp_domain", "digest") @classmethod def natural_key_fields(cls): @@ -361,8 +368,11 @@ class PackageEnvironment(Content): repo_key_fields = ("id",) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + class Meta: default_related_name = "%(app_label)s_%(model_name)s" + unique_together = ("_pulp_domain", "digest") @classmethod def natural_key_fields(cls): @@ -465,8 +475,11 @@ class PackageLangpacks(Content): digest = models.TextField(unique=True) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + class Meta: default_related_name = "%(app_label)s_%(model_name)s" + unique_together = ("_pulp_domain", "digest") @classmethod def natural_key_fields(cls): diff --git a/pulp_rpm/app/models/custom_metadata.py b/pulp_rpm/app/models/custom_metadata.py index f1263aaa23..dd317008d3 100644 --- a/pulp_rpm/app/models/custom_metadata.py +++ b/pulp_rpm/app/models/custom_metadata.py @@ -3,6 +3,7 @@ from django.db import models from pulpcore.plugin.models import Content +from pulpcore.plugin.util import get_domain_pk from pulp_rpm.app.constants import CHECKSUM_CHOICES log = getLogger(__name__) @@ -32,9 +33,11 @@ class RepoMetadataFile(Content): repo_key_fields = ("data_type",) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + class Meta: default_related_name = "%(app_label)s_%(model_name)s" - unique_together = ("data_type", "checksum", "relative_path") + unique_together = ("_pulp_domain", "data_type", "checksum", "relative_path") @property def unsupported_metadata_type(self): diff --git a/pulp_rpm/app/models/distribution.py b/pulp_rpm/app/models/distribution.py index b322d0df57..cf222e7da0 100644 --- a/pulp_rpm/app/models/distribution.py +++ b/pulp_rpm/app/models/distribution.py @@ -12,6 +12,7 @@ ContentArtifact, Repository, ) +from pulpcore.plugin.util import get_domain_pk log = getLogger(__name__) @@ -94,6 +95,8 @@ class DistributionTree(Content): digest = models.TextField(null=False) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + def repositories(self): """ Return the subrepos in this DistributionTree. @@ -134,7 +137,7 @@ def artifacts(self): class Meta: default_related_name = "%(app_label)s_%(model_name)s" - unique_together = ("digest",) + unique_together = ("_pulp_domain", "digest") class Checksum(BaseModel): diff --git a/pulp_rpm/app/models/modulemd.py b/pulp_rpm/app/models/modulemd.py index eda89a44ec..e37116551b 100644 --- a/pulp_rpm/app/models/modulemd.py +++ b/pulp_rpm/app/models/modulemd.py @@ -3,6 +3,7 @@ from django.db import models from pulpcore.plugin.models import Content +from pulpcore.plugin.util import get_domain_pk from pulp_rpm.app.models.package import Package @@ -65,9 +66,11 @@ class Modulemd(Content): snippet = models.TextField() + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + class Meta: default_related_name = "%(app_label)s_%(model_name)s" - unique_together = ("name", "stream", "version", "context", "arch") + unique_together = ("_pulp_domain", "name", "stream", "version", "context", "arch") class ModulemdDefaults(Content): @@ -98,6 +101,8 @@ class ModulemdDefaults(Content): repo_key_fields = ("module",) + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + @classmethod def natural_key_fields(cls): """ @@ -107,6 +112,7 @@ def natural_key_fields(cls): class Meta: default_related_name = "%(app_label)s_%(model_name)s" + unique_together = ("_pulp_domain", "digest") class ModulemdObsolete(Content): @@ -151,6 +157,8 @@ class ModulemdObsolete(Content): snippet = models.TextField() + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + class Meta: default_related_name = "%(app_label)s_%(model_name)s" - unique_together = ("modified", "module_name", "module_stream") + unique_together = ("_pulp_domain", "modified", "module_name", "module_stream") diff --git a/pulp_rpm/app/models/package.py b/pulp_rpm/app/models/package.py index 3f82a89851..9eed6c87ae 100644 --- a/pulp_rpm/app/models/package.py +++ b/pulp_rpm/app/models/package.py @@ -8,6 +8,7 @@ from django.db.models.functions import RowNumber from pulpcore.plugin.models import Content, ContentManager +from pulpcore.plugin.util import get_domain_pk from pulp_rpm.app.constants import ( CHECKSUM_CHOICES, @@ -236,6 +237,8 @@ class Package(Content): # E.g. glibc-2.26.11.3.2.nosrc.rpm vs glibc-2.26.11.3.2.src.rpm repo_key_fields = ("name", "epoch", "version", "release", "arch", "location_href") + _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT) + @property def filename(self): """ @@ -283,7 +286,16 @@ def nevra_short(self): class Meta: default_related_name = "%(app_label)s_%(model_name)s" - unique_together = ("name", "epoch", "version", "release", "arch", "checksum_type", "pkgId") + unique_together = ( + "_pulp_domain", + "name", + "epoch", + "version", + "release", + "arch", + "checksum_type", + "pkgId", + ) class ReadonlyMeta: readonly = ["evr"] diff --git a/pulp_rpm/app/models/repository.py b/pulp_rpm/app/models/repository.py index 85ee6da3f7..99bbbf4505 100644 --- a/pulp_rpm/app/models/repository.py +++ b/pulp_rpm/app/models/repository.py @@ -454,7 +454,7 @@ def content_handler(self, path): return base_url = "{}/".format( urlpath_sanitize( - settings.CONTENT_ORIGIN, settings.CONTENT_PATH_PREFIX, self.base_path + settings.CONTENT_ORIGIN, settings.CONTENT_PATH_PREFIX, self.pulp_domain.name, self.base_path ) ) val = textwrap.dedent( diff --git a/pulp_rpm/app/serializers/advisory.py b/pulp_rpm/app/serializers/advisory.py index d060343448..09a90d0d36 100644 --- a/pulp_rpm/app/serializers/advisory.py +++ b/pulp_rpm/app/serializers/advisory.py @@ -10,6 +10,7 @@ ModelSerializer, NoArtifactContentUploadSerializer, ) +from pulpcore.plugin.util import get_domain from pulp_rpm.app.advisory import hash_update_record from pulp_rpm.app.fields import ( @@ -231,6 +232,15 @@ def validate(self, data): validated_data = super().validate(update_record_data) return validated_data + # pulpcore 3.22 feature + # when uploading content second time I don't get error but already existing content + def retrieve(self, validated_data): + content = UpdateRecord.objects.filter( + id=validated_data["id"], + pulp_domain=get_domain(), + ) + return content.first() + class Meta: fields = NoArtifactContentUploadSerializer.Meta.fields + ( "id", diff --git a/pulp_rpm/app/serializers/comps.py b/pulp_rpm/app/serializers/comps.py index 4b94ea9c5d..4380118131 100644 --- a/pulp_rpm/app/serializers/comps.py +++ b/pulp_rpm/app/serializers/comps.py @@ -177,5 +177,13 @@ class CompsXmlSerializer(serializers.Serializer): write_only=True, ) + # TODO: determine what comps is uploaded + # def retrieve(self, validated_data): + # content = UpdateRecord.objects.filter( + # digest=validated_data["id"], + # pulp_domain=get_domain(), + # ) + # return content.first() + class Meta: fields = ("file", "repository", "replace") diff --git a/pulp_rpm/app/serializers/custom_metadata.py b/pulp_rpm/app/serializers/custom_metadata.py index fbe5014e76..f035f9c80f 100644 --- a/pulp_rpm/app/serializers/custom_metadata.py +++ b/pulp_rpm/app/serializers/custom_metadata.py @@ -5,6 +5,7 @@ ContentChecksumSerializer, SingleArtifactContentUploadSerializer, ) +from pulpcore.plugin.util import get_domain from pulp_rpm.app.models import RepoMetadataFile @@ -19,6 +20,16 @@ class RepoMetadataFileSerializer(SingleArtifactContentUploadSerializer, ContentC checksum = serializers.CharField(help_text=_("Checksum for the file.")) relative_path = serializers.CharField(help_text=_("Relative path of the file.")) + # Mirror unique_together from the Model + def retrieve(self, validated_data): + content = RepoMetadataFile.objects.filter( + data_type=validated_data["data_type"], + checksum=validated_data["checksum"], + relative_path=validated_data["relative_path"], + pulp_domain=get_domain(), + ) + return content.first() + class Meta: fields = ( ContentChecksumSerializer.Meta.fields diff --git a/pulp_rpm/app/serializers/package.py b/pulp_rpm/app/serializers/package.py index cbf841d675..a376b1c51f 100644 --- a/pulp_rpm/app/serializers/package.py +++ b/pulp_rpm/app/serializers/package.py @@ -11,6 +11,9 @@ SingleArtifactContentUploadSerializer, ) +# get_domain will be needed when upload part is fixed +# from pulpcore.plugin.util import get_domain + from pulp_rpm.app.models import Package from pulp_rpm.app.shared_utils import read_crpackage_from_artifact, format_nvra @@ -270,6 +273,7 @@ def deferred_validate(self, data): data.update(new_pkg) return data + # TODO: add domain check def retrieve(self, data): try: pkg = Package.createrepo_to_dict(read_crpackage_from_artifact(data["artifact"])) diff --git a/pulp_rpm/app/tasks/comps.py b/pulp_rpm/app/tasks/comps.py index 57ef437a16..5def6da357 100644 --- a/pulp_rpm/app/tasks/comps.py +++ b/pulp_rpm/app/tasks/comps.py @@ -8,6 +8,8 @@ from pulpcore.plugin.models import PulpTemporaryFile, CreatedResource from pulpcore.plugin.models import Content +from pulpcore.plugin.util import get_domain + from pulp_rpm.app.comps import strdict_to_dict, dict_digest from pulp_rpm.app.models import ( @@ -42,7 +44,9 @@ def parse_comps_components(comps_file): if comps.langpacks: langpack_dict = PackageLangpacks.libcomps_to_dict(comps.langpacks) langpack, created = PackageLangpacks.objects.get_or_create( - matches=strdict_to_dict(comps.langpacks), digest=dict_digest(langpack_dict) + matches=strdict_to_dict(comps.langpacks), + digest=dict_digest(langpack_dict), + _pulp_domain=get_domain() ) if created: created_objects.append(langpack) @@ -52,6 +56,7 @@ def parse_comps_components(comps_file): for category in comps.categories: category_dict = PackageCategory.libcomps_to_dict(category) category_dict["digest"] = dict_digest(category_dict) + category_dict["_pulp_domain"] = get_domain() packagecategory, created = PackageCategory.objects.get_or_create(**category_dict) if created: created_objects.append(packagecategory) @@ -61,6 +66,7 @@ def parse_comps_components(comps_file): for environment in comps.environments: environment_dict = PackageEnvironment.libcomps_to_dict(environment) environment_dict["digest"] = dict_digest(environment_dict) + environment_dict["_pulp_domain"] = get_domain() packageenvironment, created = PackageEnvironment.objects.get_or_create( **environment_dict ) @@ -72,6 +78,7 @@ def parse_comps_components(comps_file): for group in comps.groups: group_dict = PackageGroup.libcomps_to_dict(group) group_dict["digest"] = dict_digest(group_dict) + group_dict["_pulp_domain"] = get_domain() packagegroup, created = PackageGroup.objects.get_or_create(**group_dict) if created: created_objects.append(packagegroup) diff --git a/pulp_rpm/app/tasks/copy.py b/pulp_rpm/app/tasks/copy.py index e8902ae294..be2e56778d 100644 --- a/pulp_rpm/app/tasks/copy.py +++ b/pulp_rpm/app/tasks/copy.py @@ -2,6 +2,7 @@ from django.db.models import Q from pulpcore.plugin.models import Content, RepositoryVersion +from pulpcore.plugin.util import get_domain from pulp_rpm.app.depsolving import Solver from pulp_rpm.app.models import ( @@ -145,6 +146,8 @@ def process_entry(entry): else: content_filter = Q() + content_filter &= Q(pulp_domain=get_domain()) + return ( source_repo_version, dest_repo_version, diff --git a/pulp_rpm/app/tasks/publishing.py b/pulp_rpm/app/tasks/publishing.py index 942d7a9284..ced33595a9 100644 --- a/pulp_rpm/app/tasks/publishing.py +++ b/pulp_rpm/app/tasks/publishing.py @@ -22,6 +22,7 @@ PublishedMetadata, RepositoryContent, ) +from pulpcore.plugin.util import get_domain from pulp_rpm.app.comps import dict_to_strdict from pulp_rpm.app.constants import ALLOWED_CHECKSUM_ERROR_MSG, CHECKSUM_TYPES, PACKAGES_DIRECTORY diff --git a/pulp_rpm/app/urls.py b/pulp_rpm/app/urls.py index f4686280ad..e90889e2dd 100644 --- a/pulp_rpm/app/urls.py +++ b/pulp_rpm/app/urls.py @@ -3,7 +3,10 @@ from .viewsets import CopyViewSet, CompsXmlViewSet -V3_API_ROOT = settings.V3_API_ROOT_NO_FRONT_SLASH +if settings.DOMAIN_ENABLED: + V3_API_ROOT = settings.V3_DOMAIN_API_ROOT_NO_FRONT_SLASH +else: + V3_API_ROOT = settings.V3_API_ROOT_NO_FRONT_SLASH urlpatterns = [ path(f"{V3_API_ROOT}rpm/copy/", CopyViewSet.as_view({"post": "create"})), diff --git a/pulp_rpm/app/viewsets/acs.py b/pulp_rpm/app/viewsets/acs.py index 88b9b79183..2411e369fc 100644 --- a/pulp_rpm/app/viewsets/acs.py +++ b/pulp_rpm/app/viewsets/acs.py @@ -49,15 +49,15 @@ class RpmAlternateContentSourceViewSet(AlternateContentSourceViewSet, RolesMixin "action": ["retrieve"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.view_rpmalternatecontentsource", + "condition": "has_model_or_domain_or_obj_perms:rpm.view_rpmalternatecontentsource", }, { "action": ["create"], "principal": "authenticated", "effect": "allow", "condition": [ - "has_remote_param_model_or_obj_perms:rpm.view_rpmremote", - "has_model_perms:rpm.add_rpmalternatecontentsource", + "has_remote_param_model_or_domain_or_obj_perms:rpm.view_rpmremote", + "has_model_or_domain_perms:rpm.add_rpmalternatecontentsource", ], }, { @@ -65,8 +65,8 @@ class RpmAlternateContentSourceViewSet(AlternateContentSourceViewSet, RolesMixin "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.view_rpmalternatecontentsource", - "has_model_perms:rpm.refresh_rpmalternatecontentsource", + "has_model_or_domain_or_obj_perms:rpm.view_rpmalternatecontentsource", + "has_model_or_domain_perms:rpm.refresh_rpmalternatecontentsource", ], }, { @@ -74,9 +74,9 @@ class RpmAlternateContentSourceViewSet(AlternateContentSourceViewSet, RolesMixin "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.change_rpmalternatecontentsource", - "has_model_or_obj_perms:rpm.view_rpmalternatecontentsource", - "has_remote_param_model_or_obj_perms:rpm.view_rpmremote", + "has_model_or_domain_or_obj_perms:rpm.change_rpmalternatecontentsource", + "has_model_or_domain_or_obj_perms:rpm.view_rpmalternatecontentsource", + "has_remote_param_model_or_domain_or_obj_perms:rpm.view_rpmremote", ], }, { @@ -84,15 +84,16 @@ class RpmAlternateContentSourceViewSet(AlternateContentSourceViewSet, RolesMixin "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.delete_rpmalternatecontentsource", - "has_model_or_obj_perms:rpm.view_rpmalternatecontentsource", + "has_model_or_domain_or_obj_perms:rpm.delete_rpmalternatecontentsource", + "has_model_or_domain_or_obj_perms:rpm.view_rpmalternatecontentsource", ], }, { "action": ["list_roles", "add_role", "remove_role"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.manage_roles_rpmalternatecontentsource", + "condition": "has_model_or_domain_or_obj_perms:" + "rpm.manage_roles_rpmalternatecontentsource", }, ], "queryset_scoping": {"function": "scope_queryset"}, diff --git a/pulp_rpm/app/viewsets/repository.py b/pulp_rpm/app/viewsets/repository.py index 0bb401a654..74edf00ab3 100644 --- a/pulp_rpm/app/viewsets/repository.py +++ b/pulp_rpm/app/viewsets/repository.py @@ -65,15 +65,15 @@ class RpmRepositoryViewSet(RepositoryViewSet, ModifyRepositoryActionMixin, Roles "action": ["retrieve"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.view_rpmrepository", + "condition": "has_model_or_domain_or_obj_perms:rpm.view_rpmrepository", }, { "action": ["create"], "principal": "authenticated", "effect": "allow", "condition": [ - "has_remote_param_model_or_obj_perms:rpm.view_rpmremote", - "has_model_perms:rpm.add_rpmrepository", + "has_remote_param_model_or_domain_or_obj_perms:rpm.view_rpmremote", + "has_model_or_domain_perms:rpm.add_rpmrepository", ], }, { @@ -81,9 +81,9 @@ class RpmRepositoryViewSet(RepositoryViewSet, ModifyRepositoryActionMixin, Roles "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.change_rpmrepository", - "has_model_or_obj_perms:rpm.view_rpmrepository", - "has_remote_param_model_or_obj_perms:rpm.view_rpmremote", + "has_model_or_domain_or_obj_perms:rpm.change_rpmrepository", + "has_model_or_domain_or_obj_perms:rpm.view_rpmrepository", + "has_remote_param_model_or_domain_or_obj_perms:rpm.view_rpmremote", ], }, { @@ -91,8 +91,8 @@ class RpmRepositoryViewSet(RepositoryViewSet, ModifyRepositoryActionMixin, Roles "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.modify_content_rpmrepository", - "has_model_or_obj_perms:rpm.view_rpmrepository", + "has_model_or_domain_or_obj_perms:rpm.modify_content_rpmrepository", + "has_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, { @@ -100,8 +100,8 @@ class RpmRepositoryViewSet(RepositoryViewSet, ModifyRepositoryActionMixin, Roles "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.delete_rpmrepository", - "has_model_or_obj_perms:rpm.view_rpmrepository", + "has_model_or_domain_or_obj_perms:rpm.delete_rpmrepository", + "has_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, { @@ -109,16 +109,16 @@ class RpmRepositoryViewSet(RepositoryViewSet, ModifyRepositoryActionMixin, Roles "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.sync_rpmrepository", - "has_model_or_obj_perms:rpm.view_rpmrepository", - "has_remote_param_model_or_obj_perms:rpm.view_rpmremote", + "has_model_or_domain_or_obj_perms:rpm.sync_rpmrepository", + "has_model_or_domain_or_obj_perms:rpm.view_rpmrepository", + "has_remote_param_model_or_domain_or_obj_perms:rpm.view_rpmremote", ], }, { "action": ["list_roles", "add_role", "remove_role"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.manage_roles_rpmrepository", + "condition": "has_model_or_domain_or_obj_perms:rpm.manage_roles_rpmrepository", }, ], "queryset_scoping": {"function": "scope_queryset"}, @@ -262,15 +262,15 @@ class RpmRepositoryVersionViewSet(RepositoryVersionViewSet): "action": ["list", "retrieve"], "principal": "authenticated", "effect": "allow", - "condition": "has_repository_model_or_obj_perms:rpm.view_rpmrepository", + "condition": "has_repository_model_or_domain_or_obj_perms:rpm.view_rpmrepository", }, { "action": ["destroy"], "principal": "authenticated", "effect": "allow", "condition": [ - "has_repository_model_or_obj_perms:rpm.delete_rpmrepository", - "has_repository_model_or_obj_perms:rpm.view_rpmrepository", + "has_repository_model_or_domain_or_obj_perms:rpm.delete_rpmrepository", + "has_repository_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, { @@ -278,8 +278,8 @@ class RpmRepositoryVersionViewSet(RepositoryVersionViewSet): "principal": "authenticated", "effect": "allow", "condition": [ - "has_repository_model_or_obj_perms:rpm.delete_rpmrepository_version", - "has_repository_model_or_obj_perms:rpm.view_rpmrepository", + "has_repository_model_or_domain_or_obj_perms:rpm.delete_rpmrepository_version", + "has_repository_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, { @@ -287,8 +287,8 @@ class RpmRepositoryVersionViewSet(RepositoryVersionViewSet): "principal": "authenticated", "effect": "allow", "condition": [ - "has_repository_model_or_obj_perms:rpm.repair_rpmrepository", - "has_repository_model_or_obj_perms:rpm.view_rpmrepository", + "has_repository_model_or_domain_or_obj_perms:rpm.repair_rpmrepository", + "has_repository_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, ], @@ -316,21 +316,21 @@ class RpmRemoteViewSet(RemoteViewSet, RolesMixin): "action": ["retrieve"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.view_rpmremote", + "condition": "has_model_or_domain_or_obj_perms:rpm.view_rpmremote", }, { "action": ["create"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_perms:rpm.add_rpmremote", + "condition": "has_model_or_domain_perms:rpm.add_rpmremote", }, { "action": ["update", "partial_update"], "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.change_rpmremote", - "has_model_or_obj_perms:rpm.view_rpmremote", + "has_model_or_domain_or_obj_perms:rpm.change_rpmremote", + "has_model_or_domain_or_obj_perms:rpm.view_rpmremote", ], }, { @@ -338,15 +338,15 @@ class RpmRemoteViewSet(RemoteViewSet, RolesMixin): "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.delete_rpmremote", - "has_model_or_obj_perms:rpm.view_rpmremote", + "has_model_or_domain_or_obj_perms:rpm.delete_rpmremote", + "has_model_or_domain_or_obj_perms:rpm.view_rpmremote", ], }, { "action": ["list_roles", "add_role", "remove_role"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.manage_roles_rpmremote", + "condition": "has_model_or_domain_or_obj_perms:rpm.manage_roles_rpmremote", }, ], "queryset_scoping": {"function": "scope_queryset"}, @@ -395,21 +395,21 @@ class UlnRemoteViewSet(RemoteViewSet, RolesMixin): "action": ["retrieve"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.view_ulnremote", + "condition": "has_model_or_domain_or_obj_perms:rpm.view_ulnremote", }, { "action": ["create"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_perms:rpm.add_ulnremote", + "condition": "has_model_or_domain_perms:rpm.add_ulnremote", }, { "action": ["update", "partial_update"], "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.change_ulnremote", - "has_model_or_obj_perms:rpm.view_ulnremote", + "has_model_or_domain_or_obj_perms:rpm.change_ulnremote", + "has_model_or_domain_or_obj_perms:rpm.view_ulnremote", ], }, { @@ -417,15 +417,15 @@ class UlnRemoteViewSet(RemoteViewSet, RolesMixin): "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.delete_ulnremote", - "has_model_or_obj_perms:rpm.view_ulnremote", + "has_model_or_domain_or_obj_perms:rpm.delete_ulnremote", + "has_model_or_domain_or_obj_perms:rpm.view_ulnremote", ], }, { "action": ["list_roles", "add_role", "remove_role"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.manage_roles_ulnremote", + "condition": "has_model_or_domain_or_obj_perms:rpm.manage_roles_ulnremote", }, ], "queryset_scoping": {"function": "scope_queryset"}, @@ -474,15 +474,15 @@ class RpmPublicationViewSet(PublicationViewSet, RolesMixin): "action": ["retrieve"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.view_rpmpublication", + "condition": "has_model_or_domain_or_obj_perms:rpm.view_rpmpublication", }, { "action": ["create"], "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_perms:rpm.add_rpmpublication", - "has_repo_attr_model_or_obj_perms:rpm.view_rpmrepository", + "has_model_or_domain_perms:rpm.add_rpmpublication", + "has_repo_attr_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, { @@ -490,15 +490,15 @@ class RpmPublicationViewSet(PublicationViewSet, RolesMixin): "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.delete_rpmpublication", - "has_model_or_obj_perms:rpm.view_rpmpublication", + "has_model_or_domain_or_obj_perms:rpm.delete_rpmpublication", + "has_model_or_domain_or_obj_perms:rpm.view_rpmpublication", ], }, { "action": ["list_roles", "add_role", "remove_role"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.manage_roles_rpmpublication", + "condition": "has_model_or_domain_or_obj_perms:rpm.manage_roles_rpmpublication", }, ], "queryset_scoping": {"function": "scope_queryset"}, @@ -600,16 +600,16 @@ class RpmDistributionViewSet(DistributionViewSet, RolesMixin): "action": ["retrieve"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.view_rpmdistribution", + "condition": "has_model_or_domain_or_obj_perms:rpm.view_rpmdistribution", }, { "action": ["create"], "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_perms:rpm.add_rpmdistribution", - "has_publication_param_model_or_obj_perms:rpm.view_rpmpublication", - "has_repo_attr_model_or_obj_perms:rpm.view_rpmrepository", + "has_model_or_domain_perms:rpm.add_rpmdistribution", + "has_publication_param_model_or_domain_or_obj_perms:rpm.view_rpmpublication", + "has_repo_attr_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, { @@ -617,10 +617,10 @@ class RpmDistributionViewSet(DistributionViewSet, RolesMixin): "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.change_rpmdistribution", - "has_model_or_obj_perms:rpm.view_rpmdistribution", - "has_publication_param_model_or_obj_perms:rpm.view_rpmpublication", - "has_repo_attr_model_or_obj_perms:rpm.view_rpmrepository", + "has_model_or_domain_or_obj_perms:rpm.change_rpmdistribution", + "has_model_or_domain_or_obj_perms:rpm.view_rpmdistribution", + "has_publication_param_model_or_domain_or_obj_perms:rpm.view_rpmpublication", + "has_repo_attr_model_or_domain_or_obj_perms:rpm.view_rpmrepository", ], }, { @@ -628,15 +628,15 @@ class RpmDistributionViewSet(DistributionViewSet, RolesMixin): "principal": "authenticated", "effect": "allow", "condition": [ - "has_model_or_obj_perms:rpm.delete_rpmdistribution", - "has_model_or_obj_perms:rpm.view_rpmdistribution", + "has_model_or_domain_or_obj_perms:rpm.delete_rpmdistribution", + "has_model_or_domain_or_obj_perms:rpm.view_rpmdistribution", ], }, { "action": ["list_roles", "add_role", "remove_role"], "principal": "authenticated", "effect": "allow", - "condition": "has_model_or_obj_perms:rpm.manage_roles_rpmdistribution", + "condition": "has_model_or_domain_or_obj_perms:rpm.manage_roles_rpmdistribution", }, ], "queryset_scoping": {"function": "scope_queryset"}, diff --git a/pulp_rpm/tests/functional/api/test_domain.py b/pulp_rpm/tests/functional/api/test_domain.py new file mode 100644 index 0000000000..90adc5ed59 --- /dev/null +++ b/pulp_rpm/tests/functional/api/test_domain.py @@ -0,0 +1,47 @@ +import pytest +import uuid + +from django.conf import settings + +from pulpcore.client.pulp_rpm import RpmRepositorySyncURL + +from pulp_smash.pulp3.utils import gen_repo +from pulp_smash.pulp3.bindings import monitor_task + +from pulp_rpm.tests.functional.utils import gen_rpm_remote +from pulp_rpm.tests.functional.constants import ( + RPM_SIGNED_FIXTURE_URL, +) + + +if not settings.DOMAIN_ENABLED: + pytest.skip("Domains not enabled.", allow_module_level=True) + + +def test_domain_create( + domains_api_client, + gen_object_with_cleanup, + rpm_repository_api, + rpm_rpmremote_api, +): + """Test domain creation.""" + new_domain = str(uuid.uuid4()) + body = { + "name": new_domain, + "storage_class": "pulpcore.app.models.storage.FileSystem", + "storage_settings": {"MEDIA_ROOT": "/var/lib/pulp/media/"}, + } + domain = gen_object_with_cleanup(domains_api_client, body) + domain_name = domain.name + assert domain_name == new_domain + + # sync remote in default domain (not specified) + remote = gen_object_with_cleanup(rpm_rpmremote_api, gen_rpm_remote(RPM_SIGNED_FIXTURE_URL)) + repo = gen_object_with_cleanup(rpm_repository_api, gen_repo(remote=remote.pulp_href)) + sync_url = RpmRepositorySyncURL(remote=remote.pulp_href) + sync_response = rpm_repository_api.sync(repo.pulp_href, sync_url) + monitor_task(sync_response.task) + + assert rpm_repository_api.list(pulp_domain="default").count == 1 + # check that newly created domain doesn't have any repo + assert rpm_repository_api.list(pulp_domain=new_domain).count == 0 diff --git a/pulp_rpm/tests/functional/api/test_pulpimport.py b/pulp_rpm/tests/functional/api/test_pulpimport.py index a5b0bb3a23..280d7c9e30 100644 --- a/pulp_rpm/tests/functional/api/test_pulpimport.py +++ b/pulp_rpm/tests/functional/api/test_pulpimport.py @@ -11,12 +11,16 @@ from pulp_rpm.tests.functional.constants import RPM_KICKSTART_FIXTURE_URL, RPM_UNSIGNED_FIXTURE_URL +from pulpcore.app import settings + from pulpcore.client.pulp_rpm import RpmRepositorySyncURL NUM_REPOS = 2 ExportFileInfo = namedtuple("ExportFileInfo", "output_file_info") +if settings.DOMAIN_ENABLED: + pytest.skip("Domains do not support import.", allow_module_level=True) @pytest.fixture def import_export_repositories(