-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathfolder.py
412 lines (321 loc) · 14.1 KB
/
folder.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
import logging
import json
import httpx
from .api import Api
from .model import APIModel, APIEndpoints, RequestsMethods
class Folder:
"""The class includes all necessary methods to access the Grafana folder API endpoints
Args:
grafana_api_model (APIModel): Inject a Grafana API model object that includes all necessary values and information
Attributes:
grafana_api_model (APIModel): This is where we store the grafana_api_model
"""
def __init__(self, grafana_api_model: APIModel):
self.grafana_api_model = grafana_api_model
def get_folders(self) -> list:
"""The method includes a functionality to extract all folders inside the organization
Required Permissions:
Action: folders:read
Scope: folders:*
Raises:
Exception: Unspecified error by executing the API call
Returns:
api_call (list): Returns all folders
"""
api_call: list = Api(self.grafana_api_model).call_the_api(
APIEndpoints.FOLDERS.value
)
if api_call == list() or api_call[0].get("id") is None:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
return api_call
def get_folder_by_uid(self, uid: str) -> dict:
"""The method includes a functionality to extract all folder information specified by the uid of the folder
Args:
uid (str): Specify the uid of the folder
Required Permissions:
Action: folders:read
Scope: folders:*
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
api_call (dict): Returns a folder
"""
if len(uid) != 0:
api_call: dict = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.FOLDERS.value}/{uid}"
)
if api_call == dict() or api_call.get("id") is None:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
return api_call
else:
logging.error("There is no dashboard uid defined.")
raise ValueError
def get_folder_by_id(self, id: int) -> dict:
"""The method includes a functionality to extract all folder information specified by the id of the folder
Args:
id (int): Specify the id of the folder
Required Permissions:
Action: folders:read
Scope: folders:*
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
api_call (dict): Returns a folder
"""
if id != 0:
api_call: dict = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.FOLDERS.value}/id/{id}",
)
if api_call == dict() or api_call.get("id") is None:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
return api_call
else:
logging.error("There is no folder id defined.")
raise ValueError
def create_folder(
self, title: str, uid: str = None, parent_uid: str = None
) -> dict:
"""The method includes a functionality to create a new folder inside the organization specified by the defined title and the optional uid
Args:
title (str): Specify the title of the folder
uid (str): Specify the uid of the folder (default None)
parent_uid (str): Specify the parent_uid of the folder (default None)
Required Permissions:
Action: folders:create, folders:write
Scope: folders:*
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
api_call (dict): Returns a newly created folder
"""
if len(title) != 0:
folder_information: dict = dict()
folder_information.update({"title": title})
if uid is not None and len(uid) != 0:
folder_information.update({"uid": uid})
if parent_uid is not None and len(parent_uid) != 0:
folder_information.update({"parentUid": parent_uid})
api_call: dict = Api(self.grafana_api_model).call_the_api(
APIEndpoints.FOLDERS.value,
RequestsMethods.POST,
json.dumps(folder_information),
)
if api_call == dict() or api_call.get("id") is None:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
return api_call
else:
logging.error("There is no folder uid or title defined.")
raise ValueError
def update_folder(
self, title: str, uid: str, version: int = 0, overwrite: bool = False
) -> dict:
"""The method includes a functionality to update a folder information inside the organization specified by the uid, the title, the version of the folder or if folder information be overwritten
Args:
title (str): Specify the title of the folder
uid (str): Specify the uid of the folder
version (int): Specify the version of the folder (default 0)
overwrite (bool): Should the already existing folder information be overwritten (default False)
Required Permissions:
Action: folders:write
Scope: folders:*
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
api_call (dict): Returns an updated folder
"""
if overwrite is True:
version = None
if len(title) != 0 and version != 0 and len(uid) != 0:
folder_information: dict = dict()
folder_information.update({"title": title})
folder_information.update({"overwrite": overwrite})
folder_information.update({"uid": uid})
if version is not None:
folder_information.update({"version": version})
api_call: dict = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.FOLDERS.value}/{uid}",
RequestsMethods.PUT,
json.dumps(folder_information),
)
if api_call == dict() or api_call.get("id") is None:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
return api_call
else:
logging.error("There is no folder title, version or uid defined.")
raise ValueError
def move_folder(self, uid: str, parent_uid: str = None):
"""The method includes a functionality to move a folder inside the organization specified by the defined uid. This feature is only relevant if nested folders are enabled
Args:
uid (str): Specify the uid of the folder
parent_uid (str): Specify the parent_uid of the folder. If the value is None, then the folder is moved under the root (default None)
Required Permissions:
Action: folders:create, folders:write
Scope: folders:*, folders:uid:<destination folder UID>
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
api_call (dict): Returns the moved folder
"""
if len(uid) != 0:
folder_information: dict = dict()
if parent_uid is not None and len(parent_uid) != 0:
folder_information.update({"parentUid": parent_uid})
api_call = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.FOLDERS.value}/{uid}/move",
RequestsMethods.POST,
json.dumps(folder_information),
)
if api_call == dict() or api_call.get("id") is None:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
return api_call
else:
logging.error("There is no folder uid defined.")
raise ValueError
def delete_folder(self, uid: str):
"""The method includes a functionality to delete a folder inside the organization specified by the defined uid
Args:
uid (str): Specify the uid of the folder
Required Permissions:
Action: folders:delete
Scope: folders:*
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
None
"""
if len(uid) != 0:
api_call = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.FOLDERS.value}/{uid}",
RequestsMethods.DELETE,
)
if (
isinstance(api_call, dict)
and api_call.get("message") != "Folder deleted"
):
logging.error(f"Please, check the error: {api_call}.")
raise Exception
elif isinstance(api_call, httpx.Response) and api_call.status_code != 200:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
logging.info("You successfully destroyed the folder.")
else:
logging.error("There is no folder uid defined.")
raise ValueError
def get_folder_permissions(self, uid: str) -> list:
"""The method includes a functionality to extract the folder permissions inside the organization specified by the defined uid
Args:
uid (str): Specify the uid of the folder
Required Permissions:
Action: folders.permissions:read
Scope: folders:*
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
api_call (list): Returns a list of folder permissions
"""
if len(uid) != 0:
api_call: list = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.FOLDERS.value}/{uid}/permissions",
RequestsMethods.GET,
)
if api_call == list() or api_call[0].get("folderId") is None:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
return api_call
else:
logging.error("There is no folder uid defined.")
raise ValueError
def update_folder_permissions(self, uid: str, permission_json: dict):
"""The method includes a functionality to update the folder permissions based on the specified uid and the permission json document
Args:
uid (str): Specify the uid of the folder
permission_json (dict): Specify the inserted permissions as dict
Required Permissions:
Action: folders.permissions:write
Scope: folders:*
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
None
"""
if len(uid) != 0 and len(permission_json) != 0:
api_call: dict = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.FOLDERS.value}/{uid}/permissions",
RequestsMethods.POST,
json.dumps(permission_json),
)
if api_call.get("message") not in [
"Dashboard permissions updated",
"Folder permissions updated",
]:
logging.error(f"Please, check the error: {api_call}.")
raise Exception
else:
logging.info("You successfully modified the folder permissions.")
else:
logging.error("There is no folder uid or permission json defined.")
raise ValueError
def get_folder_id_by_dashboard_path(self, dashboard_path: str) -> int:
"""The method includes a functionality to extract the folder id specified inside model dashboard path
Args:
dashboard_path (str): Specify the dashboard path
Raises:
ValueError: Missed specifying a necessary value
Exception: Unspecified error by executing the API call
Returns:
folder_id (int): Returns the folder id
"""
if dashboard_path.lower() == "general":
return 0
if len(dashboard_path) != 0:
folders: list = self.get_all_folder_ids_and_names()
folder_id: int = 0
for f in folders:
if dashboard_path == f.get("title"):
folder_id = f.get("id")
if folder_id == 0:
logging.error(
f"There's no folder_id for the dashboard named {dashboard_path} available."
)
raise Exception
return folder_id
else:
logging.error("There is no dashboard_path defined.")
raise ValueError
def get_all_folder_ids_and_names(self) -> list:
"""The method extract all folder id and names inside the complete organisation
Returns:
folders (list): Returns a list of dicts with folder ids and the corresponding names
"""
folders_raw: list = Api(self.grafana_api_model).call_the_api(
f"{APIEndpoints.SEARCH.value}?folderIds=0"
)
folders_raw_len: int = len(folders_raw)
folders: list = list()
for i in range(0, folders_raw_len):
folders.append(
{"title": folders_raw[i].get("title"), "id": folders_raw[i].get("id")}
)
return folders