manager icon indicating copy to clipboard operation
manager copied to clipboard

Nebula Manager Device Group GET APIs has issue !!!

Open joshibhu opened this issue 4 years ago • 1 comments

Expected/Wanted Behavior

In case of app/cron-job deletion, the API "/api/v2/device_groups/" gives incorrect response. It shows the deleted apps/cron-jobs in the response. However the API "/api/v2/device_groups//info" gives the correct one even if it returns cached response.

Actual Behavior

The actual behavior of "/api/v2/device_groups/" API should be like that it should return real time response directly from database.

Steps to Reproduce the Problem

  1. Delete an app/cronjob which is already mapped with a device-group
  2. Trigger GET:: /api/v2/device_groups/ API
  3. You will see the deleted app/cronjob in the list Example ######################### THE APIs are executed in the sequence -

$ curl -X GET http://localhost:80/api/v2/cron_jobs -H 'Authorization: Basic bmVidWxhOm5lYnVsYQ==' -H 'Content-Type: application/json' -H 'cache-control: no-cache' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 87 100 87 0 0 1380 0 --:--:-- --:--:-- --:--:-- 1380{"cron_jobs":["bhuwan-cron1","crj-1","deviceinfo","jsms_device_app_orig","testApp11"]}

$ curl -X GET http://localhost:80/api/v2/device_groups/10000000b22e4609/info -H 'Authorization: Basic bmVidWxhOm5lYnVsYQ==' -H 'Content-Type: application/json' -H 'cache-control: no-cache' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 466 100 466 0 0 14562 0 --:--:-- --:--:-- --:--:-- 14562{"apps": [], "apps_list": [], "prune_id": 1, "cron_jobs": [{"cron_job_id": 5, "cron_job_name": "jsms_device_app_orig", "schedule": "*/1 * * * *", "env_vars": {"APP_URL": "http://192.168.1.9:3000"}, "docker_image": "192.168.255.30/jsms_device_app:0.0.1", "running": true, "networks": ["nebula", "bridge"], "volumes": ["/var/run/docker.sock:/var/run/docker.sock"], "devices": [], "privileged": false}], "cron_jobs_list": ["jsms_device_app_orig"], "device_group_id": 1}

$ curl -X DELETE http://localhost:80//api/v2/cron_jobs/jsms_device_app_orig -H 'Authorization: Basic bmVidWxhOm5lYnVsYQ==' -H 'Content-Type: application/json' -H 'cache-control: no-cache' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 2 100 2 0 0 64 0 --:--:-- --:--:-- --:--:-- 64{}

$ curl -X GET http://localhost:80/api/v2/cron_jobs -H 'Authorization: Basic bmVidWxhOm5lYnVsYQ==' -H 'Content-Type: application/json' -H 'cache-control: no-cache' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 64 100 64 0 0 2000 0 --:--:-- --:--:-- --:--:-- 2000{"cron_jobs":["bhuwan-cron1","crj-1","deviceinfo","testApp11"]}

$ curl -X GET http://localhost:80/api/v2/device_groups/10000000b22e4609/info -H 'Authorization: Basic bmVidWxhOm5lYnVsYQ==' -H 'Content-Type: application/json' -H 'cache-control: no-cache' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 105 100 105 0 0 6562 0 --:--:-- --:--:-- --:--:-- 6562{"apps": [], "apps_list": [], "prune_id": 1, "cron_jobs": [], "cron_jobs_list": [], "device_group_id": 1}

$ curl -X GET http://localhost:80/api/v2/device_groups/10000000b22e4609 -H 'Authorization: Basic bmVidWxhOm5lYnVsYQ==' -H 'Content-Type: application/json' -H 'cache-control: no-cache' % Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed 100 124 100 124 0 0 1319 0 --:--:-- --:--:-- --:--:-- 1319{"device_group_id": 1, "device_group": "10000000b22e4609", "apps": [], "prune_id": 1, "cron_jobs": ["jsms_device_app_orig"]}

Specifications

I noticed the issue is in the API implementation -

  1. In manager.py/get_device_group_info() method, post fetching device-group info from db the check is applied if the mapped app/cron-job exist or not and based on that device_group_config is being prepared
  2. However in manager.py/get_device_group() method, the exact device_group info is being returned from database.

The above scenario arises a question whether why the device-group and app/cron-job mapping is not actually getting deleted from db itself during app/cron-job deletion ? Will it not be inconsistent behavior.

joshibhu avatar Dec 23 '20 07:12 joshibhu

Thanks for opening the ticket, I managed to reproduce the issue and further confirmed it exists for apps as well as cron_jobs, the reason for this bug is that /device_groups/device_group_name doesn't show the real data but rather it shows pointers, meaning the pointer for the app/cron_job still exists even if the app/cron_job was deleted while /device_groups/device_group_name/info has internal logic that goes over and confirms the app/cron_job actually exists as well as being pointed on.

In order to fix this it may be needed to have delete operations also query the DB to get a list of all device_groups with pointers to the deleted app/cron_job and then run an update operation on each device_group which removes said pointer.

Meanwhile it won't cause any issue with devices in said device_group as they get their data from the /info endpoint which is also why a lot more effort was put into said endpoint correctness then the others

naorlivne avatar Dec 23 '20 09:12 naorlivne