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 }  ,
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 }  ,
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 }  ,
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 }  ,
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