pulp-python 3.11.2__tar.gz → 3.12.1__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (95) hide show
  1. {pulp-python-3.11.2 → pulp-python-3.12.1}/CHANGES.md +30 -2
  2. {pulp-python-3.11.2 → pulp-python-3.12.1}/PKG-INFO +2 -3
  3. pulp-python-3.12.1/functest_requirements.txt +8 -0
  4. pulp-python-3.12.1/pulp_python/app/__init__.py +66 -0
  5. pulp-python-3.12.1/pulp_python/app/global_access_conditions.py +30 -0
  6. pulp-python-3.12.1/pulp_python/app/migrations/0012_add_domain.py +37 -0
  7. pulp-python-3.12.1/pulp_python/app/migrations/0013_add_rbac_permissions.py +29 -0
  8. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/modelresource.py +4 -1
  9. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/models.py +34 -8
  10. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/pypi/serializers.py +4 -3
  11. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/pypi/views.py +122 -49
  12. pulp-python-3.12.1/pulp_python/app/replica.py +39 -0
  13. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/serializers.py +8 -1
  14. pulp-python-3.12.1/pulp_python/app/settings.py +9 -0
  15. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/tasks/publish.py +4 -2
  16. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/tasks/upload.py +14 -6
  17. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/urls.py +5 -1
  18. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/utils.py +15 -12
  19. pulp-python-3.12.1/pulp_python/app/viewsets.py +569 -0
  20. pulp-python-3.12.1/pulp_python/pytest_plugin.py +211 -0
  21. pulp-python-3.12.1/pulp_python/tests/functional/api/test_auto_publish.py +41 -0
  22. pulp-python-3.12.1/pulp_python/tests/functional/api/test_consume_content.py +33 -0
  23. pulp-python-3.12.1/pulp_python/tests/functional/api/test_crud_content_unit.py +110 -0
  24. pulp-python-3.12.1/pulp_python/tests/functional/api/test_crud_publications.py +109 -0
  25. pulp-python-3.12.1/pulp_python/tests/functional/api/test_crud_remotes.py +130 -0
  26. pulp-python-3.12.1/pulp_python/tests/functional/api/test_domains.py +264 -0
  27. pulp-python-3.12.1/pulp_python/tests/functional/api/test_download_content.py +89 -0
  28. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/tests/functional/api/test_export_import.py +33 -25
  29. pulp-python-3.12.1/pulp_python/tests/functional/api/test_full_mirror.py +73 -0
  30. pulp-python-3.12.1/pulp_python/tests/functional/api/test_pypi_apis.py +367 -0
  31. pulp-python-3.12.1/pulp_python/tests/functional/api/test_rbac.py +259 -0
  32. pulp-python-3.12.1/pulp_python/tests/functional/api/test_sync.py +317 -0
  33. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/tests/functional/constants.py +15 -34
  34. pulp-python-3.12.1/pulp_python/tests/functional/utils.py +55 -0
  35. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python.egg-info/PKG-INFO +2 -3
  36. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python.egg-info/SOURCES.txt +8 -7
  37. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python.egg-info/entry_points.txt +3 -0
  38. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python.egg-info/requires.txt +1 -1
  39. {pulp-python-3.11.2 → pulp-python-3.12.1}/pyproject.toml +1 -0
  40. {pulp-python-3.11.2 → pulp-python-3.12.1}/requirements.txt +1 -1
  41. {pulp-python-3.11.2 → pulp-python-3.12.1}/setup.py +6 -4
  42. {pulp-python-3.11.2 → pulp-python-3.12.1}/test_requirements.txt +1 -2
  43. pulp-python-3.11.2/functest_requirements.txt +0 -5
  44. pulp-python-3.11.2/pulp_python/app/__init__.py +0 -12
  45. pulp-python-3.11.2/pulp_python/app/settings.py +0 -4
  46. pulp-python-3.11.2/pulp_python/app/viewsets.py +0 -224
  47. pulp-python-3.11.2/pulp_python/tests/functional/api/test_auto_publish.py +0 -63
  48. pulp-python-3.11.2/pulp_python/tests/functional/api/test_consume_content.py +0 -141
  49. pulp-python-3.11.2/pulp_python/tests/functional/api/test_crud_content_unit.py +0 -229
  50. pulp-python-3.11.2/pulp_python/tests/functional/api/test_crud_publications.py +0 -282
  51. pulp-python-3.11.2/pulp_python/tests/functional/api/test_crud_remotes.py +0 -414
  52. pulp-python-3.11.2/pulp_python/tests/functional/api/test_download_content.py +0 -151
  53. pulp-python-3.11.2/pulp_python/tests/functional/api/test_full_mirror.py +0 -159
  54. pulp-python-3.11.2/pulp_python/tests/functional/api/test_pypi_apis.py +0 -334
  55. pulp-python-3.11.2/pulp_python/tests/functional/api/test_sync.py +0 -721
  56. pulp-python-3.11.2/pulp_python/tests/functional/conftest.py +0 -204
  57. pulp-python-3.11.2/pulp_python/tests/functional/utils.py +0 -385
  58. pulp-python-3.11.2/pulp_python/tests/upgrade/__init__.py +0 -0
  59. pulp-python-3.11.2/pulp_python/tests/upgrade/post/__init__.py +0 -0
  60. pulp-python-3.11.2/pulp_python/tests/upgrade/post/test_publish.py +0 -131
  61. pulp-python-3.11.2/pulp_python/tests/upgrade/pre/__init__.py +0 -0
  62. pulp-python-3.11.2/pulp_python/tests/upgrade/pre/test_publish.py +0 -128
  63. {pulp-python-3.11.2 → pulp-python-3.12.1}/COMMITMENT +0 -0
  64. {pulp-python-3.11.2 → pulp-python-3.12.1}/COPYRIGHT +0 -0
  65. {pulp-python-3.11.2 → pulp-python-3.12.1}/LICENSE +0 -0
  66. {pulp-python-3.11.2 → pulp-python-3.12.1}/MANIFEST.in +0 -0
  67. {pulp-python-3.11.2 → pulp-python-3.12.1}/README.md +0 -0
  68. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/__init__.py +0 -0
  69. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0001_initial.py +0 -0
  70. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0002_pythonpackagecontent_python_version.py +0 -0
  71. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0003_new_sync_filters.py +0 -0
  72. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0004_DATA_swap_distribution_model.py +0 -0
  73. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0005_pythonpackagecontent_sha256.py +0 -0
  74. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0006_pythonrepository_autopublish.py +0 -0
  75. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0007_pythonpackagecontent_mv-2-1.py +0 -0
  76. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0008_pythonpackagecontent_unique_sha256.py +0 -0
  77. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0009_pythondistribution_allow_uploads.py +0 -0
  78. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0010_update_json_field.py +0 -0
  79. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/0011_alter_pythondistribution_distribution_ptr_and_more.py +0 -0
  80. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/migrations/__init__.py +0 -0
  81. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/pypi/__init__.py +0 -0
  82. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/tasks/__init__.py +0 -0
  83. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/tasks/sync.py +0 -0
  84. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/webserver_snippets/__init__.py +0 -0
  85. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/webserver_snippets/apache.conf +0 -0
  86. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/app/webserver_snippets/nginx.conf +0 -0
  87. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/tests/__init__.py +0 -0
  88. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/tests/functional/__init__.py +0 -0
  89. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/tests/functional/api/__init__.py +0 -0
  90. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/tests/unit/__init__.py +0 -0
  91. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python/tests/unit/test_models.py +0 -0
  92. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python.egg-info/dependency_links.txt +0 -0
  93. {pulp-python-3.11.2 → pulp-python-3.12.1}/pulp_python.egg-info/top_level.txt +0 -0
  94. {pulp-python-3.11.2 → pulp-python-3.12.1}/setup.cfg +0 -0
  95. {pulp-python-3.11.2 → pulp-python-3.12.1}/unittest_requirements.txt +0 -0
@@ -8,16 +8,44 @@
8
8
 
9
9
  [//]: # (towncrier release notes start)
10
10
 
11
- ## 3.11.2 (2024-06-27) {: #3.11.2 }
11
+ ## 3.12.1 (2024-06-27) {: #3.12.1 }
12
12
 
13
13
 
14
- #### Bugfixes {: #3.11.2-bugfix }
14
+ #### Bugfixes {: #3.12.1-bugfix }
15
15
 
16
16
  - Fixed the `package_types` filter breaking other remote filters.
17
17
  [#691](https://github.com/pulp/pulp_python/issues/691)
18
18
 
19
19
  ---
20
20
 
21
+ ## 3.12.0 (2024-06-25) {: #3.12.0 }
22
+
23
+
24
+ #### Features {: #3.12.0-feature }
25
+
26
+ - Added RBAC support.
27
+ [#399](https://github.com/pulp/pulp_python/issues/399)
28
+ - Added Pulp replication support for Python distributions.
29
+ [#648](https://github.com/pulp/pulp_python/issues/648)
30
+ - Added Domain support.
31
+ [#668](https://github.com/pulp/pulp_python/issues/668)
32
+
33
+ #### Bugfixes {: #3.12.0-bugfix }
34
+
35
+ - Fixed tls_validation not being disabled when set to false on the remote.
36
+ [#653](https://github.com/pulp/pulp_python/issues/653)
37
+
38
+ #### Deprecations and Removals {: #3.12.0-removal }
39
+
40
+ - Raised the minimum `pulpcore` bound to `>=3.49` and dropped support for `python 3.8`.
41
+ [#pulpcore](https://github.com/pulp/pulp_python/issues/pulpcore)
42
+
43
+ #### Misc {: #3.12.0-misc }
44
+
45
+ -
46
+
47
+ ---
48
+
21
49
  ## 3.11.1 (2024-04-11) {: #3.11.1 }
22
50
 
23
51
  ### Bugfixes
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: pulp-python
3
- Version: 3.11.2
3
+ Version: 3.12.1
4
4
  Summary: pulp-python plugin for the Pulp Project
5
5
  Home-page: https://www.pulpproject.org
6
6
  Author: Pulp Project Developers
@@ -12,9 +12,8 @@ Classifier: Development Status :: 5 - Production/Stable
12
12
  Classifier: Framework :: Django
13
13
  Classifier: Programming Language :: Python
14
14
  Classifier: Programming Language :: Python :: 3
15
- Classifier: Programming Language :: Python :: 3.8
16
15
  Classifier: Programming Language :: Python :: 3.9
17
- Requires-Python: >=3.8
16
+ Requires-Python: >=3.9
18
17
  Description-Content-Type: text/markdown
19
18
  License-File: LICENSE
20
19
 
@@ -0,0 +1,8 @@
1
+ pytest<8
2
+ lxml
3
+ twine
4
+ pypi-simple
5
+ pytest-custom_exit_code
6
+ pytest-xdist
7
+ proxy.py~=2.4.4
8
+ trustme~=1.1.0
@@ -0,0 +1,66 @@
1
+ from django.db.models.signals import post_migrate
2
+ from pulpcore.plugin import PulpPluginAppConfig
3
+ from gettext import gettext as _
4
+
5
+
6
+ class PulpPythonPluginAppConfig(PulpPluginAppConfig):
7
+ """
8
+ Entry point for pulp_python plugin.
9
+ """
10
+
11
+ name = "pulp_python.app"
12
+ label = "python"
13
+ version = "3.12.1"
14
+ python_package_name = "pulp-python"
15
+ domain_compatible = True
16
+
17
+ def ready(self):
18
+ """Register PyPI access policy hook."""
19
+ super().ready()
20
+ post_migrate.connect(
21
+ _populate_pypi_access_policies,
22
+ sender=self,
23
+ dispatch_uid="populate_pypi_access_policies_identifier",
24
+ )
25
+
26
+
27
+ # TODO: Remove this when https://github.com/pulp/pulpcore/issues/5500 is resolved
28
+ def _populate_pypi_access_policies(sender, apps, verbosity, **kwargs):
29
+ from pulp_python.app.pypi.views import PyPIView, SimpleView, UploadView, MetadataView
30
+
31
+ try:
32
+ AccessPolicy = apps.get_model("core", "AccessPolicy")
33
+ except LookupError:
34
+ if verbosity >= 1:
35
+ print(_("AccessPolicy model does not exist. Skipping initialization."))
36
+ return
37
+
38
+ for viewset in (PyPIView, SimpleView, UploadView, MetadataView):
39
+ access_policy = getattr(viewset, "DEFAULT_ACCESS_POLICY", None)
40
+ if access_policy is not None:
41
+ viewset_name = viewset.urlpattern()
42
+ db_access_policy, created = AccessPolicy.objects.get_or_create(
43
+ viewset_name=viewset_name, defaults=access_policy
44
+ )
45
+ if created:
46
+ if verbosity >= 1:
47
+ print(
48
+ "Access policy for {viewset_name} created.".format(
49
+ viewset_name=viewset_name
50
+ )
51
+ )
52
+ elif not db_access_policy.customized:
53
+ dirty = False
54
+ for key in ["statements", "creation_hooks", "queryset_scoping"]:
55
+ value = access_policy.get(key)
56
+ if getattr(db_access_policy, key, None) != value:
57
+ setattr(db_access_policy, key, value)
58
+ dirty = True
59
+ if dirty:
60
+ db_access_policy.save()
61
+ if verbosity >= 1:
62
+ print(
63
+ "Access policy for {viewset_name} updated.".format(
64
+ viewset_name=viewset_name
65
+ )
66
+ )
@@ -0,0 +1,30 @@
1
+ from django.conf import settings
2
+
3
+
4
+ # Access Condition methods that can be used with PyPI access policies
5
+
6
+
7
+ def index_has_perm(request, view, action, perm="python.view_pythondistribution"):
8
+ """Access Policy condition that checks if the user has the perm on the index(distro)."""
9
+ if request.user.has_perm(perm):
10
+ return True
11
+ if settings.DOMAIN_ENABLED:
12
+ if request.user.has_perm(perm, obj=request.pulp_domain):
13
+ return True
14
+ return request.user.has_perm(perm, obj=view.distribution)
15
+
16
+
17
+ def index_has_repo_perm(request, view, action, perm="python.view_pythonrepository"):
18
+ """
19
+ Access Policy condition that checks if the user has the perm on the index's repository.
20
+
21
+ If index doesn't have a repository, then default return True.
22
+ """
23
+ if request.user.has_perm(perm):
24
+ return True
25
+ if settings.DOMAIN_ENABLED:
26
+ if request.user.has_perm(perm, obj=request.pulp_domain):
27
+ return True
28
+ if repo := view.distribution.repository:
29
+ return request.user.has_perm(perm, obj=repo.cast())
30
+ return True
@@ -0,0 +1,37 @@
1
+ # Generated by Django 4.2.10 on 2024-05-30 17:53
2
+
3
+ from django.db import migrations, models
4
+ import django.db.models.deletion
5
+ import pulpcore.app.util
6
+
7
+
8
+ class Migration(migrations.Migration):
9
+
10
+ dependencies = [
11
+ ("python", "0011_alter_pythondistribution_distribution_ptr_and_more"),
12
+ ]
13
+
14
+ operations = [
15
+ migrations.AlterUniqueTogether(
16
+ name="pythonpackagecontent",
17
+ unique_together=set(),
18
+ ),
19
+ migrations.AddField(
20
+ model_name="pythonpackagecontent",
21
+ name="_pulp_domain",
22
+ field=models.ForeignKey(
23
+ default=pulpcore.app.util.get_domain_pk,
24
+ on_delete=django.db.models.deletion.PROTECT,
25
+ to="core.domain",
26
+ ),
27
+ ),
28
+ migrations.AlterField(
29
+ model_name="pythonpackagecontent",
30
+ name="sha256",
31
+ field=models.CharField(db_index=True, max_length=64),
32
+ ),
33
+ migrations.AlterUniqueTogether(
34
+ name="pythonpackagecontent",
35
+ unique_together={("sha256", "_pulp_domain")},
36
+ ),
37
+ ]
@@ -0,0 +1,29 @@
1
+ # Generated by Django 4.2.10 on 2024-06-14 01:25
2
+
3
+ from django.db import migrations
4
+
5
+
6
+ class Migration(migrations.Migration):
7
+
8
+ dependencies = [
9
+ ('python', '0012_add_domain'),
10
+ ]
11
+
12
+ operations = [
13
+ migrations.AlterModelOptions(
14
+ name='pythondistribution',
15
+ options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('manage_roles_pythondistribution', 'Can manage roles on python distributions')]},
16
+ ),
17
+ migrations.AlterModelOptions(
18
+ name='pythonpublication',
19
+ options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('manage_roles_pythonpublication', 'Can manage roles on python publications')]},
20
+ ),
21
+ migrations.AlterModelOptions(
22
+ name='pythonremote',
23
+ options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('manage_roles_pythonremote', 'Can manage roles on python remotes')]},
24
+ ),
25
+ migrations.AlterModelOptions(
26
+ name='pythonrepository',
27
+ options={'default_related_name': '%(app_label)s_%(model_name)s', 'permissions': [('sync_pythonrepository', 'Can start a sync task'), ('modify_pythonrepository', 'Can modify content of the repository'), ('manage_roles_pythonrepository', 'Can manage roles on python repositories'), ('repair_pythonrepository', 'Can repair repository versions')]},
28
+ ),
29
+ ]
@@ -1,5 +1,6 @@
1
1
  from pulpcore.plugin.importexport import BaseContentResource
2
2
  from pulpcore.plugin.modelresources import RepositoryResource
3
+ from pulpcore.plugin.util import get_domain
3
4
  from pulp_python.app.models import (
4
5
  PythonPackageContent,
5
6
  PythonRepository,
@@ -15,7 +16,9 @@ class PythonPackageContentResource(BaseContentResource):
15
16
  """
16
17
  :return: PythonPackageContent specific to a specified repo-version.
17
18
  """
18
- return PythonPackageContent.objects.filter(pk__in=self.repo_version.content)
19
+ return PythonPackageContent.objects.filter(
20
+ pk__in=self.repo_version.content, _pulp_domain=get_domain()
21
+ )
19
22
 
20
23
  class Meta:
21
24
  model = PythonPackageContent
@@ -6,6 +6,7 @@ from django.core.exceptions import ObjectDoesNotExist
6
6
  from django.db import models
7
7
  from django.conf import settings
8
8
  from pulpcore.plugin.models import (
9
+ AutoAddObjPermsMixin,
9
10
  Content,
10
11
  Publication,
11
12
  Distribution,
@@ -23,6 +24,7 @@ from .utils import (
23
24
  PYPI_SERIAL_CONSTANT,
24
25
  )
25
26
  from pulpcore.plugin.repo_version_utils import remove_duplicates, validate_repo_version
27
+ from pulpcore.plugin.util import get_domain_pk, get_domain
26
28
 
27
29
  log = getLogger(__name__)
28
30
 
@@ -46,7 +48,7 @@ PLATFORMS = (
46
48
  )
47
49
 
48
50
 
49
- class PythonDistribution(Distribution):
51
+ class PythonDistribution(Distribution, AutoAddObjPermsMixin):
50
52
  """
51
53
  Distribution for 'Python' Content.
52
54
  """
@@ -68,6 +70,7 @@ class PythonDistribution(Distribution):
68
70
  path = PurePath(path)
69
71
  name = None
70
72
  version = None
73
+ domain = get_domain()
71
74
  if path.match("pypi/*/*/json"):
72
75
  version = path.parts[2]
73
76
  name = path.parts[1]
@@ -76,7 +79,7 @@ class PythonDistribution(Distribution):
76
79
  elif len(path.parts) and path.parts[0] == "simple":
77
80
  # Temporary fix for PublishedMetadata not being properly served from remote storage
78
81
  # https://github.com/pulp/pulp_python/issues/413
79
- if settings.DEFAULT_FILE_STORAGE != "pulpcore.app.models.storage.FileSystem":
82
+ if domain.storage_class != "pulpcore.app.models.storage.FileSystem":
80
83
  if self.publication or self.repository:
81
84
  try:
82
85
  publication = self.publication or Publication.objects.filter(
@@ -105,7 +108,11 @@ class PythonDistribution(Distribution):
105
108
  )
106
109
  # TODO Change this value to the Repo's serial value when implemented
107
110
  headers = {PYPI_LAST_SERIAL: str(PYPI_SERIAL_CONSTANT)}
108
- json_body = python_content_to_json(self.base_path, package_content, version=version)
111
+ if not settings.DOMAIN_ENABLED:
112
+ domain = None
113
+ json_body = python_content_to_json(
114
+ self.base_path, package_content, version=version, domain=domain
115
+ )
109
116
  if json_body:
110
117
  return json_response(json_body, headers=headers)
111
118
 
@@ -113,6 +120,9 @@ class PythonDistribution(Distribution):
113
120
 
114
121
  class Meta:
115
122
  default_related_name = "%(app_label)s_%(model_name)s"
123
+ permissions = [
124
+ ("manage_roles_pythondistribution", "Can manage roles on python distributions"),
125
+ ]
116
126
 
117
127
 
118
128
  class NormalizeName(models.Transform):
@@ -143,7 +153,7 @@ class PythonPackageContent(Content):
143
153
  name = models.TextField()
144
154
  name.register_lookup(NormalizeName)
145
155
  version = models.TextField()
146
- sha256 = models.CharField(unique=True, db_index=True, max_length=64)
156
+ sha256 = models.CharField(db_index=True, max_length=64)
147
157
  # Optional metadata
148
158
  python_version = models.TextField()
149
159
  metadata_version = models.TextField()
@@ -168,6 +178,8 @@ class PythonPackageContent(Content):
168
178
  classifiers = models.JSONField(default=list)
169
179
  project_urls = models.JSONField(default=dict)
170
180
  description_content_type = models.TextField()
181
+ # Pulp Domains
182
+ _pulp_domain = models.ForeignKey("core.Domain", default=get_domain_pk, on_delete=models.PROTECT)
171
183
 
172
184
  @staticmethod
173
185
  def init_from_artifact_and_relative_path(artifact, relative_path):
@@ -179,6 +191,8 @@ class PythonPackageContent(Content):
179
191
  data["version"] = metadata.version
180
192
  data["filename"] = path.name
181
193
  data["sha256"] = artifact.sha256
194
+ data["pulp_domain_id"] = artifact.pulp_domain_id
195
+ data["_pulp_domain_id"] = artifact.pulp_domain_id
182
196
  return PythonPackageContent(**data)
183
197
 
184
198
  def __str__(self):
@@ -200,10 +214,10 @@ class PythonPackageContent(Content):
200
214
 
201
215
  class Meta:
202
216
  default_related_name = "%(app_label)s_%(model_name)s"
203
- unique_together = ("sha256",)
217
+ unique_together = ("sha256", "_pulp_domain")
204
218
 
205
219
 
206
- class PythonPublication(Publication):
220
+ class PythonPublication(Publication, AutoAddObjPermsMixin):
207
221
  """
208
222
  A Publication for PythonContent.
209
223
  """
@@ -212,9 +226,12 @@ class PythonPublication(Publication):
212
226
 
213
227
  class Meta:
214
228
  default_related_name = "%(app_label)s_%(model_name)s"
229
+ permissions = [
230
+ ("manage_roles_pythonpublication", "Can manage roles on python publications"),
231
+ ]
215
232
 
216
233
 
217
- class PythonRemote(Remote):
234
+ class PythonRemote(Remote, AutoAddObjPermsMixin):
218
235
  """
219
236
  A Remote for Python Content.
220
237
 
@@ -249,9 +266,12 @@ class PythonRemote(Remote):
249
266
 
250
267
  class Meta:
251
268
  default_related_name = "%(app_label)s_%(model_name)s"
269
+ permissions = [
270
+ ("manage_roles_pythonremote", "Can manage roles on python remotes"),
271
+ ]
252
272
 
253
273
 
254
- class PythonRepository(Repository):
274
+ class PythonRepository(Repository, AutoAddObjPermsMixin):
255
275
  """
256
276
  Repository for "python" content.
257
277
  """
@@ -264,6 +284,12 @@ class PythonRepository(Repository):
264
284
 
265
285
  class Meta:
266
286
  default_related_name = "%(app_label)s_%(model_name)s"
287
+ permissions = [
288
+ ("sync_pythonrepository", "Can start a sync task"),
289
+ ("modify_pythonrepository", "Can modify content of the repository"),
290
+ ("manage_roles_pythonrepository", "Can manage roles on python repositories"),
291
+ ("repair_pythonrepository", "Can repair repository versions"),
292
+ ]
267
293
 
268
294
  def on_new_version(self, version):
269
295
  """
@@ -4,6 +4,7 @@ from gettext import gettext as _
4
4
  from rest_framework import serializers
5
5
  from pulp_python.app.utils import DIST_EXTENSIONS
6
6
  from pulpcore.plugin.models import Artifact
7
+ from pulpcore.plugin.util import get_domain
7
8
  from django.db.utils import IntegrityError
8
9
 
9
10
  log = logging.getLogger(__name__)
@@ -76,7 +77,7 @@ class PackageUploadSerializer(serializers.Serializer):
76
77
  try:
77
78
  artifact.save()
78
79
  except IntegrityError:
79
- artifact = Artifact.objects.get(sha256=artifact.sha256)
80
+ artifact = Artifact.objects.get(sha256=artifact.sha256, pulp_domain=get_domain())
80
81
  artifact.touch()
81
82
  log.info(f"Artifact for {file.name} already existed in database")
82
83
  data["content"] = (artifact, file.name)
@@ -88,6 +89,6 @@ class PackageUploadTaskSerializer(serializers.Serializer):
88
89
  A Serializer for responding to a package upload task.
89
90
  """
90
91
 
91
- session = serializers.CharField()
92
+ session = serializers.CharField(allow_null=True)
92
93
  task = serializers.CharField()
93
- task_start_time = serializers.DateTimeField()
94
+ task_start_time = serializers.DateTimeField(allow_null=True)