Skip to content
This repository has been archived by the owner on Dec 9, 2022. It is now read-only.

Commit

Permalink
Prevent deleted devices from being recreated
Browse files Browse the repository at this point in the history
This addresses issue:

 #3

In that it prevents a device to ever get re-created, as this is not
allowed by OTA Connect. This seems like a bug in OTA Connect, but
was easiest to fix here. Additionally, we think this addresses
a bug we had in production:

 advancedtelematic/ota-device-registry#89

Signed-off-by: Andy Doan <andy@foundries.io>
  • Loading branch information
doanac committed May 8, 2019
1 parent e6b1b5f commit af706e6
Show file tree
Hide file tree
Showing 3 changed files with 68 additions and 0 deletions.
3 changes: 3 additions & 0 deletions docker_run.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
# if FLASK_DEBUG is defined, we'll run via flask with dynamic reloading of
# code changes to disk. This is helpful for debugging something already in k8s

echo "Adding deleted hack DB table"
python3 -c "from ota_api.deleted_hack import migrate; migrate()"

if [ -z "$FLASK_DEBUG" ] ; then
exec /usr/bin/gunicorn -n ota-api -w4 -b 0.0.0.0:8000 $FLASK_APP:app
fi
Expand Down
60 changes: 60 additions & 0 deletions ota_api/deleted_hack.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# Copyright (C) 2019 Foundries.io
# Author: Andy Doan <andy@foundries.io>
import contextlib
import os

from pymysql import Connect

DB = os.environ.get('DEVICE_REGISTRY_DB', 'device_registry')
DBHOST = os.environ.get('DEVICE_REGISTRY_DBHOST', 'mysql')
DBUSER = os.environ.get('DEVICE_REGISTRY_DBUSER', 'device_registry')
DBPASS = os.environ.get('DEVICE_REGISTRY_DBPASS', 'device_registry')


@contextlib.contextmanager
def db_cursor(commit=False):
con = None
try:
con = Connect(host=DBHOST, user=DBUSER, password=DBPASS, db=DB)
with con.cursor() as cur:
yield cur
if commit:
con.commit()
finally:
if con:
con.close()


def migrate():
stmt = '''
CREATE TABLE IF NOT EXISTS OtaApiDeleted (
uuid CHAR(36) NOT NULL,
PRIMARY KEY (uuid)
);
'''
with db_cursor() as c:
c.execute(stmt)


def device_mark_deleted(device_uuid):
'''Mark a device as deleted so that it won't ever be allowed to be added
again.'''
stmt = 'INSERT INTO OtaApiDeleted (uuid) VALUES (%s)'
with db_cursor(commit=True) as c:
c.execute(stmt, device_uuid)


def device_is_deleted(device_uuid):
'''Check to see if this device was deleted. We can't allow it to be
re-added and OTA connect will. Letting a device through will cause
something like:
https://github.com/advancedtelematic/ota-device-registry/issues/89
'''
stmt = '''SELECT uuid
FROM OtaApiDeleted
WHERE uuid = %s
'''
with db_cursor() as c:
c.execute(stmt, device_uuid)
for r in c:
return True
5 changes: 5 additions & 0 deletions ota_api/ota_user.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from flask import abort, jsonify, make_response, request

from ota_api.deleted_hack import device_is_deleted, device_mark_deleted
from ota_api.ota_ce import OTACommunityEditionAPI

VALID_DEVICE_CHAR = set(string.ascii_letters + string.digits + '-' + '_' + '/')
Expand Down Expand Up @@ -99,8 +100,12 @@ def device_rename(self, name, new_name):
def device_delete(self, name):
api, d = self._get(name)
api.device_delete(d)
device_mark_deleted(d['uuid'])

def device_create(self, name, uuid, client_pem):
if device_is_deleted(uuid):
message = 'A device with this uuid has been deleted.'
abort(make_response(jsonify(message=message), 400))
api = OTACommunityEditionAPI('default')
api.device_create(name, uuid, client_pem)

Expand Down

0 comments on commit af706e6

Please sign in to comment.