mirror of
https://github.com/ansible/awx.git
synced 2026-02-12 07:04:45 -03:30
120 lines
4.2 KiB
Python
120 lines
4.2 KiB
Python
import warnings
|
|
|
|
from rest_framework.permissions import IsAuthenticated
|
|
from drf_spectacular.openapi import AutoSchema
|
|
from drf_spectacular.views import (
|
|
SpectacularAPIView,
|
|
SpectacularSwaggerView,
|
|
SpectacularRedocView,
|
|
)
|
|
|
|
|
|
def filter_credential_type_schema(
|
|
result,
|
|
generator, # NOSONAR
|
|
request, # NOSONAR
|
|
public, # NOSONAR
|
|
):
|
|
"""
|
|
Postprocessing hook to filter CredentialType kind enum values.
|
|
|
|
For CredentialTypeRequest and PatchedCredentialTypeRequest schemas (POST/PUT/PATCH),
|
|
filter the 'kind' enum to only show 'cloud' and 'net' values.
|
|
|
|
This ensures the OpenAPI schema accurately reflects that only 'cloud' and 'net'
|
|
credential types can be created or modified via the API, matching the validation
|
|
in CredentialTypeSerializer.validate().
|
|
|
|
Args:
|
|
result: The OpenAPI schema dict to be modified
|
|
generator, request, public: Required by drf-spectacular interface (unused)
|
|
|
|
Returns:
|
|
The modified OpenAPI schema dict
|
|
"""
|
|
schemas = result.get('components', {}).get('schemas', {})
|
|
|
|
# Filter CredentialTypeRequest (POST/PUT) - field is required
|
|
if 'CredentialTypeRequest' in schemas:
|
|
kind_prop = schemas['CredentialTypeRequest'].get('properties', {}).get('kind', {})
|
|
if 'enum' in kind_prop:
|
|
# Filter to only cloud and net (no None - field is required)
|
|
kind_prop['enum'] = ['cloud', 'net']
|
|
kind_prop['description'] = "* `cloud` - Cloud\\n* `net` - Network"
|
|
|
|
# Filter PatchedCredentialTypeRequest (PATCH) - field is optional
|
|
if 'PatchedCredentialTypeRequest' in schemas:
|
|
kind_prop = schemas['PatchedCredentialTypeRequest'].get('properties', {}).get('kind', {})
|
|
if 'enum' in kind_prop:
|
|
# Filter to only cloud and net (None allowed - field can be omitted in PATCH)
|
|
kind_prop['enum'] = ['cloud', 'net', None]
|
|
kind_prop['description'] = "* `cloud` - Cloud\\n* `net` - Network"
|
|
|
|
return result
|
|
|
|
|
|
class CustomAutoSchema(AutoSchema):
|
|
"""Custom AutoSchema to add swagger_topic to tags and handle deprecated endpoints."""
|
|
|
|
def get_tags(self):
|
|
tags = []
|
|
try:
|
|
if hasattr(self.view, 'get_serializer'):
|
|
serializer = self.view.get_serializer()
|
|
else:
|
|
serializer = None
|
|
except Exception:
|
|
serializer = None
|
|
warnings.warn(
|
|
'{}.get_serializer() raised an exception during '
|
|
'schema generation. Serializer fields will not be '
|
|
'generated for this view.'.format(self.view.__class__.__name__)
|
|
)
|
|
|
|
if hasattr(self.view, 'swagger_topic'):
|
|
tags.append(str(self.view.swagger_topic).title())
|
|
elif serializer and hasattr(serializer, 'Meta') and hasattr(serializer.Meta, 'model'):
|
|
tags.append(str(serializer.Meta.model._meta.verbose_name_plural).title())
|
|
elif hasattr(self.view, 'model'):
|
|
tags.append(str(self.view.model._meta.verbose_name_plural).title())
|
|
else:
|
|
tags = super().get_tags() # Use default drf-spectacular behavior
|
|
|
|
if not tags:
|
|
warnings.warn(f'Could not determine tags for {self.view.__class__.__name__}')
|
|
tags = ['api'] # Fallback to default value
|
|
|
|
return tags
|
|
|
|
def is_deprecated(self):
|
|
"""Return `True` if this operation is to be marked as deprecated."""
|
|
return getattr(self.view, 'deprecated', False)
|
|
|
|
|
|
class AuthenticatedSpectacularAPIView(SpectacularAPIView):
|
|
"""SpectacularAPIView that requires authentication."""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
|
|
class AuthenticatedSpectacularSwaggerView(SpectacularSwaggerView):
|
|
"""SpectacularSwaggerView that requires authentication."""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
|
|
class AuthenticatedSpectacularRedocView(SpectacularRedocView):
|
|
"""SpectacularRedocView that requires authentication."""
|
|
|
|
permission_classes = [IsAuthenticated]
|
|
|
|
|
|
# Schema view (returns OpenAPI schema JSON/YAML)
|
|
schema_view = AuthenticatedSpectacularAPIView.as_view()
|
|
|
|
# Swagger UI view
|
|
swagger_ui_view = AuthenticatedSpectacularSwaggerView.as_view(url_name='api:schema-json')
|
|
|
|
# ReDoc UI view
|
|
redoc_view = AuthenticatedSpectacularRedocView.as_view(url_name='api:schema-json')
|