Skip to content

Commit

Permalink
docs(api): document the inventory endpoint
Browse files Browse the repository at this point in the history
!24 #55
  • Loading branch information
jon-nfc committed Jun 11, 2024
1 parent 36fa364 commit 2eb5031
Show file tree
Hide file tree
Showing 5 changed files with 166 additions and 55 deletions.
73 changes: 73 additions & 0 deletions app/api/serializers/itam/inventory.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
from django.urls import reverse

from itam.models.device import Device
from rest_framework import serializers




class InventorySerializer(serializers.Serializer):
""" Serializer for Inventory Upload """


class DetailsSerializer(serializers.Serializer):

name = serializers.CharField(
help_text = 'Host name',
required = True
)

serial_number = serializers.CharField(
help_text = 'Devices serial number',
required = True
)

uuid = serializers.CharField(
help_text = 'Device system UUID',
required = True
)


class OperatingSystemSerializer(serializers.Serializer):

name = serializers.CharField(
help_text='Name of the operating system installed on the device',
required = True,
)

version_major = serializers.IntegerField(
help_text='Major semver version number of the OS version',
required = True,
)

version = serializers.CharField(
help_text='semver version number of the OS',
required = True
)


class SoftwareSerializer(serializers.Serializer):

name = serializers.CharField(
help_text='Name of the software',
required = True
)

category = serializers.CharField(
help_text='Category of the software',
default = None,
required = False
)

version = serializers.CharField(
default = None,
help_text='semver version number of the software',
required = False
)


details = DetailsSerializer()

os = OperatingSystemSerializer()

software = SoftwareSerializer(many = True)
39 changes: 33 additions & 6 deletions app/api/views/itam/inventory.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,16 @@
from django.http import Http404, JsonResponse
from django.utils import timezone

from drf_spectacular.utils import extend_schema, OpenApiExample, OpenApiTypes, OpenApiResponse, OpenApiParameter

from rest_framework import generics, views
from rest_framework.response import Response

from access.mixin import OrganizationMixin
from access.models import Organization

from api.views.mixin import OrganizationPermissionAPI
from api.serializers.itam.inventory import InventorySerializer

from core.http.common import Http

Expand All @@ -38,20 +41,44 @@ def permission_check(self, request, view, obj=None) -> bool:

class Collect(OrganizationPermissionAPI, views.APIView):

# permission_classes = [
# InventoryPermissions
# ]

queryset = Device.objects.all()


@extend_schema(
summary = "Upload a device's inventory",
description = """After inventorying a device, it's inventory file, `.json` is uploaded to this endpoint.
If the device does not exist, it will be created. If the device does exist the existing
device will be updated with the information within the inventory.
matching for an existing device is by slug which is the hostname converted to lower case
letters. This conversion is automagic.
**NOTE:** _for device creation, the API user must have user setting 'Default Organization'. Without
this setting populated, no device will be created and the endpoint will return HTTP/403_
## Permissions
- `itam.add_device` Required to upload inventory
""",
methods=["POST"],
parameters = None,
tags = ['device', 'inventory',],
request = InventorySerializer,
responses = {
200: OpenApiResponse(description='Inventory updated an existing device'),
201: OpenApiResponse(description='Inventory created a new device'),
400: OpenApiResponse(description='Inventory is invalid'),
401: OpenApiResponse(description='User Not logged in'),
403: OpenApiResponse(description='User is missing permission or in different organization'),
500: OpenApiResponse(description='Exception occured. View server logs for the Stack Trace'),
}
)
def post(self, request, *args, **kwargs):


data = json.loads(request.body)

# data = self.request.data

device = None

self.default_organization = UserSettings.objects.get(user=request.user).default_organization
Expand Down
29 changes: 27 additions & 2 deletions app/app/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -223,8 +223,33 @@
}

SPECTACULAR_SETTINGS = {
'TITLE': 'Your Project API',
'DESCRIPTION': 'Your project description',
'TITLE': 'ITSM API',
'DESCRIPTION': """This UI is intended to serve as the API documentation.
## Authentication
Authentication with the api is via Token. The token is placed in header `Authorization` with a value of `Token <Your Token>`.
## Token Generation
To generate a token, run `python3 manage.py drf_create_token <username>` from the CLI.
## Examples
curl:
- Simple API Request: `curl -X GET <url>/api/ -H 'Authorization: Token <token>'`
- Post an Inventory File:
``` bash
curl --header "Content-Type: application/json" \\
--header "Authorization: Token <token>" \\
--request POST \\
--data @<path to inventory file>/<file name>.json \\
<url>/api/device/inventory
```
""",
'VERSION': '1.0.0',
'SERVE_INCLUDE_SCHEMA': False,

Expand Down
53 changes: 6 additions & 47 deletions docs/projects/django-template/api.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,65 +6,24 @@ template: project.html
about: https://gitlab.com/nofusscomputing/infrastructure/configuration-management/django_app
---

to access the api, it can be done with the following command:

``` bash

curl -X GET http://127.0.0.1:8000/api/ -H 'Authorization: Token <token>'

```
An api is available for this application and can be viewed at endpoint `/api/`. Documentation specific to each of the endpoints can be found within the swagger UI at endpoint `api/swagger/`.


## Features

- Inventory Report Collection
- Device Inventory upload

- Swagger UI


## Inventory Reports

- url `/api/device/inventory`

- method `POST`

- content `application/json`

- permission `itam.add_device`

Passing a valid inventory report to this endpoint will update the device within the app. If the device doesn't exist it will be created.

Report Format

``` json

{
"details": {
"name": "string",
"serial_number": "string",
"uuid": "string"
},
"os": {
"name": "name of os",
"version_major": "major version number",
"version": "as reported"
},
"software": [
{
"name": "string",
"category": "string",
"version": "string"
}
]
}

## Device Inventory

```
You can [inventory](itam/device.md#inventory) your devices and upload them to the inventory endpoint.


## User Token
## Swagger UI

To generate a user token to access the api, use command `python3 manage.py drf_create_token <username>`
The swagger UI is included within this application and can be found at endpoint `/api/swagger` on your server. This UI has been used to document the API.


## Organizations
Expand Down
27 changes: 27 additions & 0 deletions docs/projects/django-template/itam/device.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,30 @@ The report can contain the following information:

!!! info
When the software is added to the inventory, a regex search is done to return the [semver](https://semver.org/) of the software. if no semver is found, the version number provided is used.

Example Report

``` json

{
"details": {
"name": "string",
"serial_number": "string",
"uuid": "string"
},
"os": {
"name": "name of os",
"version_major": "major version number",
"version": "as reported"
},
"software": [
{
"name": "string",
"category": "string",
"version": "string"
}
]
}


```

0 comments on commit 2eb5031

Please sign in to comment.