1 # -*- coding: utf-8 -*-
3 # Copyright 2021 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
25 from osm_mon
.core
.common_db
import CommonDbClient
26 from osm_mon
.core
.config
import Config
27 from osm_mon
.core
.keystone
import KeystoneConnection
28 from osm_mon
.dashboarder
.backends
.grafana
import GrafanaBackend
29 from osm_mon
import __path__
as mon_path
30 from osm_mon
.core
.utils
import find_in_list
, create_filter_from_nsr
32 log
= logging
.getLogger(__name__
)
35 class DashboarderService
:
36 def __init__(self
, config
: Config
):
38 self
.common_db
= CommonDbClient(self
.conf
)
39 self
.grafana
= GrafanaBackend(self
.conf
)
41 if bool(self
.conf
.get('keystone', 'enabled')):
42 self
.keystone
= KeystoneConnection(self
.conf
)
46 def create_dashboards(self
):
47 # TODO lavado: migrate these methods to mongo change streams
48 # Lists all dashboards and OSM resources for later comparisons
49 dashboard_uids
= self
.grafana
.get_all_dashboard_uids()
50 osm_resource_uids
= []
53 # Check if keystone is the auth/projects backend and get projects from there
57 map(lambda project
: {'_id': project
.id, 'name': project
.name
}, self
.keystone
.getProjects())
60 log
.error('Cannot retrieve projects from keystone')
62 # Reads existing project list and creates a dashboard for each
63 projects
.extend(self
.common_db
.get_projects())
64 for project
in projects
:
65 project_id
= project
['_id']
66 # Collect Project IDs for periodical dashboard clean-up
67 osm_resource_uids
.append(project_id
)
68 dashboard_path
= '{}/dashboarder/templates/project_scoped.json'.format(mon_path
[0])
69 if project_id
not in dashboard_uids
:
70 project_name
= project
['name']
71 if project_name
!= "admin":
72 # Create project folder in Grafana only if user is not admin.
73 # Admin user's dashboard will be created in default folder
74 self
.grafana
.create_grafana_folders(project_name
)
75 self
.grafana
.create_dashboard(project_id
, project_name
,
77 log
.debug('Created dashboard for Project: %s', project_id
)
79 log
.debug('Dashboard already exists')
81 # Reads existing NS list and creates a dashboard for each
82 # TODO lavado: only create for ACTIVE NSRs
83 nsrs
= self
.common_db
.get_nsrs()
86 dashboard_path
= '{}/dashboarder/templates/ns_scoped.json'.format(mon_path
[0])
87 # Collect NS IDs for periodical dashboard clean-up
88 osm_resource_uids
.append(nsr_id
)
89 # Check if the NSR's VNFDs contain metrics
90 # Only one DF at the moment, support for this feature is comming in the future
91 vnfds_profiles
= nsr
['nsd']["df"][0]['vnf-profile']
92 for vnf_profile
in vnfds_profiles
:
94 vnfd
= self
.common_db
.get_vnfd_by_id(vnf_profile
['vnfd-id'], create_filter_from_nsr(nsr
))
95 # If there are metrics, create dashboard (if exists)
96 vdu_found
= find_in_list(vnfd
["vdu"], lambda a_vdu
: "monitoring-parameter" in a_vdu
)
98 if nsr_id
not in dashboard_uids
:
99 nsr_name
= nsr
['name']
100 project_id
= nsr
["_admin"]["projects_read"][0]
102 # Get project details from commondb
103 project_details
= self
.common_db
.get_project(project_id
)
104 project_name
= project_details
["name"]
105 except Exception as e
:
106 # Project not found in commondb
108 # Serach project in keystone
109 for project
in projects
:
110 if project_id
== project
['_id']:
111 project_name
= project
["name"]
113 log
.info('Project %s not found', project_id
)
114 log
.debug('Exception %s' % e
)
115 self
.grafana
.create_dashboard(nsr_id
, nsr_name
,
116 dashboard_path
, project_name
)
117 log
.debug('Created dashboard for NS: %s', nsr_id
)
119 log
.debug('Dashboard already exists')
122 log
.debug('NS does not has metrics')
124 log
.exception("VNFD is not valid or has been renamed")
127 # Delete obsolete dashboards
128 for dashboard_uid
in dashboard_uids
:
129 if dashboard_uid
not in osm_resource_uids
:
130 self
.grafana
.delete_dashboard(dashboard_uid
)
131 log
.debug('Deleted obsolete dashboard: %s', dashboard_uid
)
133 log
.debug('All dashboards in use')
135 def create_grafana_user(self
, user
):
136 self
.grafana
.create_grafana_users(user
)
138 def create_grafana_team_member(self
, project_data
, userid
):
140 # Get user details from commondb
141 user
= self
.common_db
.get_user_by_id(userid
)
142 user_name
= user
["username"]
143 except Exception as e
:
144 # User not found in commondb
146 # Serach user in keystone
147 user
= self
.keystone
.getUserById(userid
)
148 user_name
= user
.name
150 log
.info('User %s not found', userid
)
151 log
.debug('Exception %s' % e
)
153 for project
in project_data
:
154 proj_list
.append(project
["project"])
155 for proj
in project_data
:
156 role_obj
= self
.common_db
.get_role_by_name(proj
["role"])
157 is_admin
= role_obj
["permissions"].get("admin")
158 self
.grafana
.create_grafana_teams_members(proj
["project"], user_name
, is_admin
, proj_list
)
160 def create_grafana_team(self
, team_name
):
161 self
.grafana
.create_grafana_teams(team_name
)
163 def delete_grafana_user(self
, user_name
):
164 self
.grafana
.delete_grafana_users(user_name
)
166 def delete_grafana_team(self
, project_name
):
167 self
.grafana
.delete_grafana_team(project_name
)
169 def update_grafana_team(self
, project_new_name
, project_old_name
):
170 self
.grafana
.update_grafana_teams(project_new_name
, project_old_name
)