Coverage for netbox/plugins/views.py: 55%

43 statements  

« prev     ^ index     » next       coverage.py v7.15.2, created at 2026-10-10 18:35 +0000

1from collections import OrderedDict 

2 

3from django.apps import apps 

4from django.urls.exceptions import NoReverseMatch 

5from drf_spectacular.utils import extend_schema 

6from rest_framework.response import Response 

7from rest_framework.reverse import reverse 

8from rest_framework.views import APIView 

9 

10from netbox.registry import registry 

11from utilities.api import IsSuperuser 

12 

13 

14@extend_schema(exclude=True) 

15class InstalledPluginsAPIView(APIView): 

16 """ 

17 API view for listing all installed plugins 

18 """ 

19 permission_classes = [IsSuperuser] 

20 _ignore_model_permissions = True 

21 schema = None 

22 

23 def get_view_name(self): 

24 return "Installed Plugins" 

25 

26 @staticmethod 

27 def _get_plugin_data(plugin_app_config): 

28 return { 

29 'name': plugin_app_config.verbose_name, 

30 'package': plugin_app_config.name, 

31 'author': plugin_app_config.author, 

32 'author_email': plugin_app_config.author_email, 

33 'description': plugin_app_config.description, 

34 'version': plugin_app_config.version, 

35 'release_track': plugin_app_config.release_track, 

36 } 

37 

38 def get(self, request, format=None): 

39 return Response([ 

40 self._get_plugin_data(apps.get_app_config(plugin)) 

41 for plugin in registry['plugins']['installed'] 

42 ]) 

43 

44 

45@extend_schema(exclude=True) 

46class PluginsAPIRootView(APIView): 

47 _ignore_model_permissions = True 

48 schema = None 

49 

50 def get_view_name(self): 

51 return "Plugins" 

52 

53 @staticmethod 

54 def _get_plugin_entry(plugin, app_config, request, format): 

55 # Check if the plugin specifies any API URLs 

56 api_app_name = f'{app_config.name}-api' 

57 try: 

58 entry = (getattr(app_config, 'base_url', app_config.label), reverse( 

59 f"plugins-api:{api_app_name}:api-root", 

60 request=request, 

61 format=format 

62 )) 

63 except NoReverseMatch: 

64 # The plugin does not include an api-root url 

65 entry = None 

66 

67 return entry 

68 

69 def get(self, request, format=None): 

70 

71 entries = [] 

72 for plugin in registry['plugins']['installed']: 

73 app_config = apps.get_app_config(plugin) 

74 entry = self._get_plugin_entry(plugin, app_config, request, format) 

75 if entry is not None: 

76 entries.append(entry) 

77 

78 return Response(OrderedDict(( 

79 ('installed-plugins', reverse('plugins-api:plugins-list', request=request, format=format)), 

80 *entries 

81 )))