3232 API_ROOT = settings .V3_DOMAIN_API_ROOT_NO_FRONT_SLASH
3333else :
3434 API_ROOT = settings .V3_API_ROOT_NO_FRONT_SLASH
35+
3536if settings .API_ROOT_REWRITE_HEADER :
3637 V3_API_ROOT = settings .V3_API_ROOT .replace ("/<path:api_root>/" , settings .API_ROOT )
38+ V4_API_ROOT = settings .V4_API_ROOT .replace ("/<path:api_root>/" , settings .API_ROOT )
3739else :
3840 V3_API_ROOT = settings .V3_API_ROOT
41+ V4_API_ROOT = settings .V4_API_ROOT
3942
4043
4144class ViewSetNode :
@@ -153,70 +156,83 @@ class PulpDefaultRouter(routers.DefaultRouter):
153156 vs_tree .add_decendent (ViewSetNode (viewset ))
154157
155158special_views = [
156- path ("login/" , LoginViewSet .as_view ()),
157- path ("repair/" , RepairView .as_view ()),
159+ path ("login/" , LoginViewSet .as_view (), name = "login" ),
160+ path ("repair/" , RepairView .as_view (), name = "repair" ),
158161 path (
159162 "orphans/cleanup/" ,
160163 OrphansCleanupViewset .as_view (actions = {"post" : "cleanup" }),
164+ name = "orphan-cleanup" ,
161165 ),
162- path ("orphans/" , OrphansView .as_view ()),
166+ path ("orphans/" , OrphansView .as_view (), name = "orphans" ),
163167 path (
164168 "repository_versions/" ,
165169 ListRepositoryVersionViewSet .as_view (actions = {"get" : "list" }),
170+ name = "repository-versions" ,
166171 ),
167172 path (
168173 "repositories/reclaim_space/" ,
169174 ReclaimSpaceViewSet .as_view (actions = {"post" : "reclaim" }),
175+ name = "reclaim" ,
170176 ),
171177 path (
172178 "importers/core/pulp/import-check/" ,
173179 PulpImporterImportCheckView .as_view (),
180+ name = "pulp-importer-import-check" ,
174181 ),
175182]
176183
177- docs_and_status = [
178- path ("livez/" , LivezView .as_view ()),
179- path ("status/" , StatusView .as_view ()),
180- path (
181- "docs/api.json" ,
182- SpectacularJSONAPIView .as_view (authentication_classes = [], permission_classes = []),
183- name = "schema" ,
184- ),
185- path (
186- "docs/api.yaml" ,
187- SpectacularYAMLAPIView .as_view (authentication_classes = [], permission_classes = []),
188- name = "schema-yaml" ,
189- ),
190- path (
191- "docs/" ,
192- SpectacularRedocView .as_view (
193- authentication_classes = [],
194- permission_classes = [],
195- url = f"{ V3_API_ROOT } docs/api.json?include_html=1&pk_path=1" ,
184+
185+ def _docs_and_status (_api_root ):
186+ paths = [
187+ path (
188+ "docs/api.json" ,
189+ SpectacularJSONAPIView .as_view (authentication_classes = [], permission_classes = []),
190+ name = "schema" ,
196191 ),
197- name = "schema-redoc" ,
198- ),
199- path (
200- "swagger/" ,
201- SpectacularSwaggerView .as_view (
202- authentication_classes = [],
203- permission_classes = [],
204- url = f"{ V3_API_ROOT } docs/api.json?include_html=1&pk_path=1" ,
192+ path (
193+ "docs/api.yaml" ,
194+ SpectacularYAMLAPIView .as_view (authentication_classes = [], permission_classes = []),
195+ name = "schema-yaml" ,
205196 ),
206- name = "schema-swagger" ,
207- ),
208- ]
197+ path (
198+ "docs/" ,
199+ SpectacularRedocView .as_view (
200+ authentication_classes = [],
201+ permission_classes = [],
202+ url = f"{ _api_root } docs/api.json?include_html=1&pk_path=1" ,
203+ ),
204+ name = "schema-redoc" ,
205+ ),
206+ path (
207+ "swagger/" ,
208+ SpectacularSwaggerView .as_view (
209+ authentication_classes = [],
210+ permission_classes = [],
211+ url = f"{ _api_root } docs/api.json?include_html=1&pk_path=1" ,
212+ ),
213+ name = "schema-swagger" ,
214+ ),
215+ path ("livez/" , LivezView .as_view (), name = "livez" ),
216+ path ("status/" , StatusView .as_view (), name = "status" ),
217+ ]
218+
219+ return paths
220+
221+
222+ v3_docs_and_status = _docs_and_status (V3_API_ROOT )
223+ v4_docs_and_status = _docs_and_status (V4_API_ROOT )
209224
210225urlpatterns = [
211- path (API_ROOT , include (special_views )),
212226 path ("auth/" , include ("rest_framework.urls" )),
213- path (settings .V3_API_ROOT_NO_FRONT_SLASH , include (docs_and_status )),
227+ path (API_ROOT , include (special_views )),
228+ path (settings .V3_API_ROOT_NO_FRONT_SLASH , include (v3_docs_and_status )),
214229]
215230
231+
216232if settings .DOMAIN_ENABLED :
217233 # Ensure Docs and Status endpoints are available within domains, but are not shown in API schema
218234 docs_and_status_no_schema = []
219- for p in docs_and_status :
235+ for p in v3_docs_and_status :
220236
221237 @extend_schema (exclude = True )
222238 class NoSchema (p .callback .cls ):
@@ -227,6 +243,34 @@ class NoSchema(p.callback.cls):
227243 docs_and_status_no_schema .append (path (str (p .pattern ), view , name = name ))
228244 urlpatterns .insert (- 1 , path (API_ROOT , include (docs_and_status_no_schema )))
229245
246+
247+ if settings .ENABLE_V4_API :
248+ urlpatterns .extend (
249+ [
250+ path (V4_API_ROOT , include ((special_views , "core" ), namespace = "v4" )),
251+ path (
252+ settings .V4_API_ROOT_NO_FRONT_SLASH ,
253+ include ((v4_docs_and_status , "core" ), namespace = "v4" ),
254+ ),
255+ ]
256+ )
257+
258+
259+ if settings .DOMAIN_ENABLED :
260+ # Ensure Docs and Status endpoints are available within domains, but are not shown in API schema
261+ docs_and_status_no_schema = []
262+ for p in v4_docs_and_status :
263+
264+ @extend_schema (exclude = True )
265+ class NoSchema (p .callback .cls ):
266+ pass
267+
268+ view = NoSchema .as_view (** p .callback .initkwargs )
269+ name = p .name + "-domains" if p .name else None
270+ docs_and_status_no_schema .append (path (str (p .pattern ), view , name = name ))
271+ urlpatterns .insert (- 1 , path (API_ROOT , include (docs_and_status_no_schema )))
272+
273+
230274if "social_django" in settings .INSTALLED_APPS :
231275 urlpatterns .append (
232276 path ("" , include ("social_django.urls" , namespace = settings .SOCIAL_AUTH_URL_NAMESPACE ))
@@ -239,6 +283,12 @@ class NoSchema(p.callback.cls):
239283for router in all_routers :
240284 urlpatterns .append (path (API_ROOT , include (router .urls )))
241285
286+ if settings .ENABLE_V4_API :
287+ for router in all_routers :
288+ urlpatterns .append (
289+ path (V4_API_ROOT .lstrip ("/" ), include ((router .urls , "core" ), namespace = "v4" ))
290+ )
291+
242292# If plugins define a urls.py, include them into the root namespace.
243293for plugin_pattern in plugin_patterns :
244294 urlpatterns .append (path ("" , include (plugin_pattern )))
0 commit comments