=============================
Django GCP IoT Device Manager
=============================


.. image:: https://img.shields.io/pypi/v/dj_gcp_iotdevice.svg
        :target: https://pypi.python.org/pypi/dj_gcp_iotdevice

.. image:: https://img.shields.io/gitlab/pipeline/pennatus/dj_gcp_iotdevice/master
        :alt: Gitlab pipeline status

.. image:: https://readthedocs.org/projects/dj_gcp_iotdevice/badge/?version=latest
        :target: https://dj_gcp_iotdevice.readthedocs.io/en/latest/?badge=latest
        :alt: Documentation Status


Provides a CRDL (Create, Retrieve, Destroy, List) interface to GCP IoT Core

* Free software: MIT license
* Documentation: https://dj_gcp_iotdevice.readthedocs.io.

Getting Started
---------------

If you are not familiar with GCP IoT Core then please first read the following:

* GCP IoT Core getting started link: https://cloud.google.com/iot/docs/how-tos/getting-started

First create an IoT device registry and then make sure that the service account assigned
to your service (VM, Cloud Run, App Engine) has enough GCP permissions to
create/read/delete/list from GCP IoT Core.

Installation
------------

Install ``dj_gcp_iotdevice`` from pip ::

    $ pip install dj_gcp_iotdevice

Add to your top level ``apps.py`` ::

    from dj_gcp_iotdevice.apps import GCPIoTDeviceConfig

    class MyProjectDeviceConfig(GCPIoTDeviceConfig):
        registry = 'my-iot-registry'
        location = 'us-central1'
        project = 'my-project-id'

Add the new app config to your installed apps ::

    INSTALLED_APPS = [
        ...
        'apps.MyProjectDeviceConfig',
    ]

Add the provided urls to your list of urls ::

    urlpatterns = [
        ...
        path('', include('dj_gcp_iotdevice.urls')),
    ]

API
---

The following endpoints will be accessible ::

    POST /devices/
    GET /devices/{id}
    DELETE /devices/{id}
    GET /devices/

To create a new device you will need to generate a private/public keypair using the following commands ::

    openssl genpkey -algorithm RSA -out rsa_private.pem -pkeyopt rsa_keygen_bits:2048
    openssl rsa -in rsa_private.pem -pubout -out rsa_public.pem

Take the contents of the ``rsa_public.pem`` and use that for the public_key in the API.  Make sure to use \\n characters for the line feeds.

The following snippet is the openapi spec for the new devices api ::

    /devices/:
        get:
            operationId: devices_list
            summary: Used to list all the devices in the registry.
            description: |-
                :raises PermissionDenied: Likely bad coordinates to registry or not enough permissions
                                        to list devices from registry.
            parameters: []
            responses:
                '200':
                description: ''
                schema:
                    type: array
                    items:
                    $ref: '#/definitions/Device'
            tags:
                - devices
        post:
            operationId: devices_create
            summary: Used to add a new IoT device to the registry.
            description: |-
                :raises ParseError: Bad data provided.  Likely a bad public key.
                :raises NotAcceptable: Could not add device.  Probably device Id already exists.
                :raises PermissionDenied: Likely wrong GCP coordinates or insufficient permissions
                                        on GCP to add devices to the registry.
            parameters:
                - name: data
                in: body
                required: true
                schema:
                    $ref: '#/definitions/Device'
            responses:
                '201':
                description: ''
                schema:
                    $ref: '#/definitions/Device'
            tags:
                - devices
            parameters: []
    /devices/{id}/:
        get:
            operationId: devices_read
            summary: Used to get one device from the registry.
            description: |-
                :raises PermissionDenied: Likely bad coordinates to registry or not enough
                                        permissions to read devices from registry.
                :raises NotFound: Device does not exist.
            parameters: []
            responses:
                '200':
                description: ''
                schema:
                    $ref: '#/definitions/Device'
            tags:
                - devices
        delete:
            operationId: devices_delete
            summary: Used to remove a device from the registry.
            description: |-
                :raises PermissionDenied: Likely bad coordinates to registry or not enough
                                        permissions to remove devices from the registry.
                :raises NotFound: Device does not exist.
            parameters: []
            responses:
                '204':
                description: ''
            tags:
                - devices
            parameters:
            - name: id
                in: path
                required: true
                type: string
