eeb5e7541fa58966bbf5e7c3148fe4a87089aed0
1 # -*- coding: utf-8 -*-
3 # Copyright 2018 Whitestack, LLC
4 # *************************************************************
6 # This file is part of OSM Monitoring module
7 # All Rights Reserved to Whitestack, LLC
9 # Licensed under the Apache License, Version 2.0 (the "License"); you may
10 # not use this file except in compliance with the License. You may obtain
11 # a copy of the License at
13 # http://www.apache.org/licenses/LICENSE-2.0
15 # Unless required by applicable law or agreed to in writing, software
16 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
17 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
18 # License for the specific language governing permissions and limitations
20 # For those usages not covered by the Apache License, Version 2.0 please
21 # contact: glavado@whitestack.com or fbravo@whitestack.com
27 from osm_mon
.core
.config
import Config
29 log
= logging
.getLogger(__name__
)
33 def __init__(self
, config
: Config
):
35 self
.url
= config
.get('grafana', 'url')
36 grafana_user
= config
.get("grafana", "user")
37 grafana_password
= config
.get("grafana", "password")
39 'content-type': "application/json",
40 'authorization': "Basic %s" % base64
.b64encode(
41 (grafana_user
+ ":" + grafana_password
).encode("utf-8")).decode()
44 def get_all_dashboard_uids(self
):
45 # Gets only dashboards that were automated by OSM (with tag 'osm_automated')
46 response
= requests
.request("GET", self
.url
+ "/api/search?tag=osm_automated", headers
=self
.headers
)
47 dashboards
= response
.json()
49 for dashboard
in dashboards
:
50 dashboard_uids
.append(dashboard
['uid'])
51 log
.debug("Searching for all dashboard uids: %s", dashboard_uids
)
54 def get_dashboard_status(self
, uid
):
55 response
= requests
.request("GET", self
.url
+ "/api/dashboards/uid/" + uid
, headers
=self
.headers
)
56 log
.debug("Searching for dashboard result: %s", response
.text
)
59 def create_dashboard(self
, uid
, name
, json_file
, project_name
=None):
61 with
open(json_file
) as f
:
62 dashboard_data
= f
.read()
64 dashboard_data
= dashboard_data
.replace('OSM_ID', uid
).replace('OSM_NAME', name
)
65 dashboard_json_data
= json
.loads(dashboard_data
)
68 folder_name
= project_name
71 response_folder_id
= requests
.request(
72 "GET", self
.url
+ "/api/folders/{}".format(folder_name
), headers
=self
.headers
)
73 if response_folder_id
.status_code
== 200:
74 folder_id
= json
.loads(response_folder_id
.text
)["id"]
75 dashboard_json_data
["folderId"] = folder_id
76 dashboard_json_data
["overwrite"] = False
78 response
= requests
.request(
79 "POST", self
.url
+ "/api/dashboards/db/", data
=json
.dumps(dashboard_json_data
), headers
=self
.headers
)
81 # Don't create the dashboard if already exists.
82 if json
.loads(response
.text
).get("status") == "name-exists":
86 if project_name
is not None:
88 response_team
= requests
.request(
89 "GET", self
.url
+ "/api/teams/search?name={}".format(name
), headers
=self
.headers
)
91 # Remove default permissions of admin user's dashboard so that it is not visible to non-admin users
92 if len(json
.loads(response_team
.text
)["teams"]) == 0:
93 # As team information is not available so it is admin user
94 dahboard_id
= json
.loads(response
.text
)["id"]
96 "POST", self
.url
+ "/api/dashboards/id/{}/permissions".format(dahboard_id
),
99 log
.info("Dashboard %s is created in Grafana", name
)
102 log
.exception("Exception processing message: ")
104 def delete_dashboard(self
, uid
):
105 response
= requests
.request("DELETE", self
.url
+ "/api/dashboards/uid/" + uid
, headers
=self
.headers
)
106 log
.debug("Dashboard %s deleted from Grafana", uid
)
109 def create_grafana_users(self
, user
):
110 email
= "{}@osm.etsi.org".format(user
)
117 response_users
= requests
.request("POST", self
.url
+ "/api/admin/users/", json
=user_payload
,
118 headers
=self
.headers
)
119 json_data
= json
.loads(response_users
.text
)
120 url
= "/api/org/users/{}/".format(json_data
["id"])
121 permission_payload
= {"role": "Editor", }
122 requests
.request("PATCH", self
.url
+ url
, json
=permission_payload
, headers
=self
.headers
)
123 log
.info("New user %s created in Grafana", user
)
124 return response_users
126 # Create Grafana team with member
127 def create_grafana_teams_members(self
, project_name
, user_name
, is_admin
, proj_list
):
128 # Check if user exist in Grafana
129 user_response
= requests
.request("GET", self
.url
+ "/api/users/lookup?loginOrEmail={}".format(user_name
),
130 headers
=self
.headers
)
131 user_obj
= json
.loads(user_response
.text
)
132 if user_response
.status_code
!= 200:
133 user_response
= self
.create_grafana_users(user_name
)
134 user_obj
= json
.loads(user_response
.text
)
136 user_id
= user_obj
["id"]
139 team_objs
= requests
.request("GET", self
.url
+ "/api/users/{}/teams".format(user_id
), headers
=self
.headers
)
140 team_obj
= json
.loads(team_objs
.text
)
143 for team
in team_obj
:
144 team_list
.append(team
["name"])
146 proj_unlink
= set(team_list
) - set(proj_list
)
147 for prj
in proj_unlink
:
148 response_team
= requests
.request("GET", self
.url
+ "/api/teams/search?name={}".format(prj
),
149 headers
=self
.headers
)
150 team_id
= json
.loads(response_team
.text
)["teams"][0]["id"]
151 requests
.request("DELETE", self
.url
+ "/api/teams/{}/members/{}".format(team_id
, user_id
),
152 headers
=self
.headers
)
153 if project_name
!= "admin":
155 response_team
= requests
.request("GET", self
.url
+ "/api/teams/search?name={}".format(project_name
),
156 headers
=self
.headers
)
158 # Search if team in Grafana corresponding to the project already exists
159 if not json
.loads(response_team
.text
)["teams"]:
160 self
.create_grafana_teams(project_name
)
161 response_team
= requests
.request("GET", self
.url
+ "/api/teams/search?name={}".format(project_name
),
162 headers
=self
.headers
)
163 team_id
= json
.loads(response_team
.text
)["teams"][0]["id"]
164 if project_name
not in team_list
:
165 # Create a team in Grafana corresponding to the project as it doesn't exist
169 requests
.request("POST", self
.url
+ "/api/teams/{}/members".format(team_id
), json
=member_payload
,
170 headers
=self
.headers
)
171 # Check if user role or project name is admin
172 if is_admin
or project_name
== 'admin':
173 # Give admin righsts to user
174 url
= "/api/org/users/{}/".format(user_id
)
175 permission_payload
= {"role": "Admin", }
176 requests
.request("PATCH", self
.url
+ url
, json
=permission_payload
, headers
=self
.headers
)
177 log
.info("User %s is assigned Admin permission", user_name
)
179 # Give editor rights to user
180 url
= "/api/org/users/{}/".format(user_id
)
181 permission_payload
= {"role": "Editor", }
182 requests
.request("PATCH", self
.url
+ url
, json
=permission_payload
, headers
=self
.headers
)
183 log
.info("User %s is assigned Editor permission", user_name
)
185 # Create team in Grafana
186 def create_grafana_teams(self
, team_name
):
187 team_payload
= {"name": team_name
, }
188 requests
.request("POST", self
.url
+ "/api/teams", json
=team_payload
, headers
=self
.headers
)
189 log
.info("New team %s created in Grafana", team_name
)
191 # Create folder in Grafana
192 def create_grafana_folders(self
, folder_name
):
193 folder_payload
= {"uid": folder_name
, "title": folder_name
}
194 requests
.request("POST", self
.url
+ "/api/folders", json
=folder_payload
, headers
=self
.headers
)
195 log
.info("Dashboard folder %s created", folder_name
)
197 response_team
= requests
.request("GET", self
.url
+ "/api/teams/search?name={}".format(folder_name
),
198 headers
=self
.headers
)
199 # Create team if it doesn't already exists
200 if len(json
.loads(response_team
.text
)["teams"]) == 0:
201 self
.create_grafana_teams(folder_name
)
202 response_team
= requests
.request("GET", self
.url
+ "/api/teams/search?name={}".format(folder_name
),
203 headers
=self
.headers
)
204 # Assign required permission to the team's folder
205 team_id
= json
.loads(response_team
.text
)["teams"][0]["id"]
206 permission_data
= {"items": [{"teamId": team_id
, "permission": 2}, ]}
207 requests
.request("POST", self
.url
+ "/api/folders/{}/permissions".format(folder_name
),
208 json
=permission_data
, headers
=self
.headers
)
210 def delete_grafana_users(self
, user_name
):
212 response_id
= requests
.request("GET", self
.url
+ "/api/users/lookup?loginOrEmail={}".format(user_name
),
213 headers
=self
.headers
)
215 user_id
= json
.loads(response_id
.text
)["id"]
217 log
.exception("Exception processing message: ")
219 response
= requests
.request("DELETE", self
.url
+ "/api/admin/users/{}".format(user_id
), headers
=self
.headers
)
220 log
.info("User %s deleted in Grafana", user_name
)
223 def delete_grafana_team(self
, project_name
):
224 # Delete Grafana folder
225 requests
.request("DELETE", self
.url
+ "/api/folders/{}".format(project_name
),
226 headers
=self
.headers
)
227 # Delete Grafana team
228 team_obj
= requests
.request("GET", self
.url
+ "/api/teams/search?name={}".format(project_name
),
229 headers
=self
.headers
)
230 team_id
= json
.loads(team_obj
.text
)["teams"][0]["id"]
231 response
= requests
.request("DELETE", self
.url
+ "/api/teams/{}".format(team_id
), headers
=self
.headers
)
232 log
.info("Team %s deleted in Grafana", project_name
)
235 def update_grafana_teams(self
, project_new_name
, project_old_name
):
236 team_obj
= requests
.request("GET", self
.url
+ "/api/teams/search?name={}".format(project_old_name
),
237 headers
=self
.headers
)
238 team_id
= json
.loads(team_obj
.text
)["teams"][0]["id"]
239 data
= {"name": project_new_name
, }
240 response
= requests
.request("PUT", self
.url
+ "/api/teams/{}".format(team_id
), json
=data
, headers
=self
.headers
)
241 log
.info("Grafana team updated %s", response
.text
)