Add Version Endpoints

* At root URL will list all versions with respect to these [1]
  guidelines.
* v1/ path will list it's own version information

[1] https://wiki.openstack.org/wiki/VersionDiscovery

Change-Id: I9162408ab0cea03ba1cbf3326d0af80188385501
This commit is contained in:
Amelia Cordwell 2017-08-24 11:40:25 +12:00 committed by Adrian Turjak
parent b0ce4a1167
commit ae5c1943c9
5 changed files with 88 additions and 1 deletions

View File

@ -37,6 +37,10 @@ The points that are modular, or will be made more modular in future, are the Tas
Creation and management of Tasks, Tokens, and Notifications is not modular and is the framework around the defined Actions and TaskViews that handles how they are executed. This helps keep the way Actions are executed consistent and simpler to maintain, but does also allow Actions to run almost any logic within those consistent steps.
#### Version Endpoints:
* ../ - GET
* JSON containing details of the currently available versions (just v1 for now)
#### Admin Endpoints:
Endpoints for the management of tasks, tokens, and notifications. Most of these are limited by roles, or are for admin use only.

View File

@ -18,11 +18,17 @@ from django.conf import settings
from rest_framework_swagger.views import get_swagger_view
urlpatterns = []
from adjutant.api import views
from adjutant.api.v1 import views as views_v1
urlpatterns = [
url(r'^$', views.VersionView.as_view()),
]
# NOTE(adriant): This may not be the best approach, but it does work. Will
# gladly accept a cleaner alternative if it presents itself.
if apps.is_installed('adjutant.api.v1'):
urlpatterns.append(url(r'^v1/?$', views_v1.V1VersionEndpoint.as_view()))
urlpatterns.append(url(r'^v1/', include('adjutant.api.v1.urls')))

View File

@ -1,6 +1,10 @@
from django.apps import AppConfig
from adjutant.api.views import build_version_details
class APIV1Config(AppConfig):
name = "adjutant.api.v1"
label = 'api_v1'
def ready(self):
build_version_details('1.0', 'CURRENT', relative_endpoint='v1/')

View File

@ -23,11 +23,16 @@ from rest_framework.response import Response
from rest_framework.views import APIView
from adjutant.api import utils
from adjutant.api.views import SingleVersionView
from adjutant.api.models import Notification, Task, Token
from adjutant.api.v1.utils import (
create_notification, create_token, parse_filters, send_stage_email)
class V1VersionEndpoint(SingleVersionView):
version = '1.0'
class APIViewWithLogger(APIView):
"""
APIView with a logger.

68
adjutant/api/views.py Normal file
View File

@ -0,0 +1,68 @@
from rest_framework.views import APIView
from rest_framework.response import Response
_VERSIONS = {}
def build_version_details(id, status, links=None, relative_endpoint=None):
"""
Build a standard version dictionary
"""
int_id = int(float(id))
if not relative_endpoint:
relative_endpoint = "v%s/" % int_id
mime_type = "application/vnd.openstack.adjutant-v%s+json" % int_id
version_details = {
'status': status,
'id': id,
'media-types': [
{
'base': 'application/json',
'type': mime_type
}
],
'links': []
}
if links:
version_details['links'] = links
version_details['relative_endpoint'] = relative_endpoint
_VERSIONS[id] = version_details
return version_details
class VersionView(APIView):
def get(self, request):
versions = []
for version in _VERSIONS.values():
version = version.copy()
rel_endpoint = version.pop('relative_endpoint')
url = request.build_absolute_uri() + rel_endpoint
version['links'] = version['links'] + [{'href': url,
'rel': 'self'}]
versions.append(version)
return Response({'versions': versions}, status=200)
class SingleVersionView(APIView):
"""
A view to be added to the root of each API version detailing it's
own version details. Should be subclassed and have a version set.
"""
def get(self, request):
version = _VERSIONS.get(self.version, {}).copy()
if not version:
return Response({'error': 'Not Found'}, status=404)
version.pop('relative_endpoint')
version['links'] = version['links'] + [
{'href': request.build_absolute_uri(),
'rel': 'self'}]
return Response({'version': version}, status=200)