Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
B
brian-dashboard-manager
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Wiki
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Container Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
geant-swd
brian
brian-dashboard-manager
Commits
88751ac8
Commit
88751ac8
authored
3 years ago
by
Bjarke Madsen
Browse files
Options
Downloads
Patches
Plain Diff
Delete stale dashboards after provisioning.
parent
66608ca0
No related branches found
Branches containing commit
No related tags found
Tags containing commit
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
brian_dashboard_manager/grafana/dashboard.py
+20
-5
20 additions, 5 deletions
brian_dashboard_manager/grafana/dashboard.py
brian_dashboard_manager/grafana/provision.py
+64
-18
64 additions, 18 deletions
brian_dashboard_manager/grafana/provision.py
test/test_update.py
+25
-1
25 additions, 1 deletion
test/test_update.py
with
109 additions
and
24 deletions
brian_dashboard_manager/grafana/dashboard.py
+
20
−
5
View file @
88751ac8
...
@@ -74,12 +74,27 @@ def delete_dashboards(request: TokenRequest):
...
@@ -74,12 +74,27 @@ def delete_dashboards(request: TokenRequest):
# Searches for a dashboard with given title
# Searches for a dashboard with given title
def
find_dashboard
(
request
:
TokenRequest
,
title
):
def
find_dashboard
(
request
:
TokenRequest
,
title
=
None
):
r
=
request
.
get
(
'
api/search
'
,
params
=
{
param
=
{
'
query
'
:
title
**
({
'
query
'
:
title
}
if
title
else
{}),
})
'
type
'
:
'
dash-db
'
,
'
limit
'
:
5000
,
'
page
'
:
1
}
r
=
request
.
get
(
'
api/search
'
,
params
=
param
)
if
r
and
len
(
r
)
>
0
:
if
r
and
len
(
r
)
>
0
:
return
r
[
0
]
if
title
:
return
r
[
0
]
else
:
while
True
:
param
[
'
page
'
]
+=
1
page
=
request
.
get
(
'
api/search
'
,
params
=
param
)
if
len
(
page
)
>
0
:
r
.
extend
(
page
)
else
:
break
return
r
return
None
return
None
...
...
This diff is collapsed.
Click to expand it.
brian_dashboard_manager/grafana/provision.py
+
64
−
18
View file @
88751ac8
...
@@ -7,6 +7,7 @@ import logging
...
@@ -7,6 +7,7 @@ import logging
import
time
import
time
import
json
import
json
import
datetime
import
datetime
from
functools
import
reduce
from
concurrent.futures
import
ProcessPoolExecutor
,
ThreadPoolExecutor
from
concurrent.futures
import
ProcessPoolExecutor
,
ThreadPoolExecutor
from
brian_dashboard_manager.config
import
DEFAULT_ORGANIZATIONS
,
STATE_PATH
from
brian_dashboard_manager.config
import
DEFAULT_ORGANIZATIONS
,
STATE_PATH
from
brian_dashboard_manager.grafana.utils.request
import
\
from
brian_dashboard_manager.grafana.utils.request
import
\
...
@@ -15,7 +16,7 @@ from brian_dashboard_manager.grafana.utils.request import \
...
@@ -15,7 +16,7 @@ from brian_dashboard_manager.grafana.utils.request import \
from
brian_dashboard_manager.grafana.organization
import
\
from
brian_dashboard_manager.grafana.organization
import
\
get_organizations
,
create_organization
,
create_api_token
,
\
get_organizations
,
create_organization
,
create_api_token
,
\
delete_api_token
,
delete_expired_api_tokens
,
set_home_dashboard
delete_api_token
,
delete_expired_api_tokens
,
set_home_dashboard
from
brian_dashboard_manager.grafana.dashboard
import
\
from
brian_dashboard_manager.grafana.dashboard
import
find_dashboard
,
\
get_dashboard_definitions
,
create_dashboard
,
delete_dashboard
get_dashboard_definitions
,
create_dashboard
,
delete_dashboard
from
brian_dashboard_manager.grafana.datasource
import
\
from
brian_dashboard_manager.grafana.datasource
import
\
check_provisioned
,
create_datasource
check_provisioned
,
create_datasource
...
@@ -39,10 +40,13 @@ logger = logging.getLogger(__name__)
...
@@ -39,10 +40,13 @@ logger = logging.getLogger(__name__)
def
generate_all_nrens
(
token_request
,
nrens
,
folder_id
,
datasource_name
):
def
generate_all_nrens
(
token_request
,
nrens
,
folder_id
,
datasource_name
):
provisioned
=
[]
with
ThreadPoolExecutor
(
max_workers
=
8
)
as
executor
:
with
ThreadPoolExecutor
(
max_workers
=
8
)
as
executor
:
for
dashboard
in
generate_nrens
(
nrens
,
datasource_name
):
for
dashboard
in
generate_nrens
(
nrens
,
datasource_name
):
executor
.
submit
(
create_dashboard
,
token_request
,
res
=
executor
.
submit
(
create_dashboard
,
token_request
,
dashboard
,
folder_id
)
dashboard
,
folder_id
)
provisioned
.
append
(
res
)
return
[
r
.
result
()
for
r
in
provisioned
]
def
provision_folder
(
token_request
,
folder_name
,
def
provision_folder
(
token_request
,
folder_name
,
...
@@ -70,6 +74,8 @@ def provision_folder(token_request, folder_name,
...
@@ -70,6 +74,8 @@ def provision_folder(token_request, folder_name,
excluded_dashboards
=
list
(
excluded_dashboards
=
list
(
map
(
lambda
s
:
s
.
lower
(),
excluded_dashboards
))
map
(
lambda
s
:
s
.
lower
(),
excluded_dashboards
))
provisioned
=
[]
with
ThreadPoolExecutor
(
max_workers
=
4
)
as
executor
:
with
ThreadPoolExecutor
(
max_workers
=
4
)
as
executor
:
for
dashboard
in
dash_data
:
for
dashboard
in
dash_data
:
rendered
=
render_dashboard
(
dashboard
)
rendered
=
render_dashboard
(
dashboard
)
...
@@ -77,8 +83,9 @@ def provision_folder(token_request, folder_name,
...
@@ -77,8 +83,9 @@ def provision_folder(token_request, folder_name,
executor
.
submit
(
delete_dashboard
,
token_request
,
executor
.
submit
(
delete_dashboard
,
token_request
,
rendered
,
folder
[
'
id
'
])
rendered
,
folder
[
'
id
'
])
continue
continue
executor
.
submit
(
create_dashboard
,
token_request
,
provisioned
.
append
(
executor
.
submit
(
create_dashboard
,
token_request
,
rendered
,
folder
[
'
id
'
])
rendered
,
folder
[
'
id
'
]))
return
[
r
.
result
()
for
r
in
provisioned
]
def
provision_aggregate
(
token_request
,
agg_type
,
aggregate_folder
,
def
provision_aggregate
(
token_request
,
agg_type
,
aggregate_folder
,
...
@@ -93,7 +100,7 @@ def provision_aggregate(token_request, agg_type, aggregate_folder,
...
@@ -93,7 +100,7 @@ def provision_aggregate(token_request, agg_type, aggregate_folder,
f
'
Aggregate -
{
agg_type
}
'
,
data
,
datasource_name
,
tag
)
f
'
Aggregate -
{
agg_type
}
'
,
data
,
datasource_name
,
tag
)
rendered
=
render_dashboard
(
dashboard
)
rendered
=
render_dashboard
(
dashboard
)
create_dashboard
(
token_request
,
rendered
,
aggregate_folder
[
'
id
'
])
return
create_dashboard
(
token_request
,
rendered
,
aggregate_folder
[
'
id
'
])
def
provision_maybe
(
config
):
def
provision_maybe
(
config
):
...
@@ -247,7 +254,17 @@ def provision(config):
...
@@ -247,7 +254,17 @@ def provision(config):
datasource_name
=
datasource
.
get
(
'
name
'
,
'
PollerInfluxDB
'
)
datasource_name
=
datasource
.
get
(
'
name
'
,
'
PollerInfluxDB
'
)
excluded_folders
=
org_config
.
get
(
'
excluded_folders
'
,
{})
excluded_folders
=
org_config
.
get
(
'
excluded_folders
'
,
{})
def
get_uid
(
prev
,
curr
):
prev
[
curr
.
get
(
'
uid
'
)]
=
False
return
prev
# Map of dashboard UID -> whether it has been updated.
# This is used to remove stale dashboards at the end.
dash_list
=
find_dashboard
(
token_request
)
or
[]
dash_list
=
reduce
(
get_uid
,
dash_list
,
{})
with
ProcessPoolExecutor
(
max_workers
=
4
)
as
executor
:
with
ProcessPoolExecutor
(
max_workers
=
4
)
as
executor
:
provisioned
=
[]
for
folder_name
,
dash
in
dashboards
.
items
():
for
folder_name
,
dash
in
dashboards
.
items
():
exclude
=
excluded_folders
.
get
(
folder_name
)
exclude
=
excluded_folders
.
get
(
folder_name
)
if
exclude
:
if
exclude
:
...
@@ -260,10 +277,19 @@ def provision(config):
...
@@ -260,10 +277,19 @@ def provision(config):
logger
.
info
(
logger
.
info
(
f
'
Provisioning
{
org
[
"
name
"
]
}
/
{
folder_name
}
dashboards
'
)
f
'
Provisioning
{
org
[
"
name
"
]
}
/
{
folder_name
}
dashboards
'
)
executor
.
submit
(
provision_folder
,
token_request
,
res
=
executor
.
submit
(
provision_folder
,
token_request
,
folder_name
,
dash
,
folder_name
,
dash
,
excluded_interfaces
,
datasource_name
,
excluded_interfaces
,
datasource_name
,
exclude
)
exclude
)
provisioned
.
append
(
res
)
for
result
in
provisioned
:
folder
=
result
.
result
()
if
folder
is
None
:
continue
for
dashboard
in
folder
:
if
dashboard
is
None
:
continue
dash_list
[
dashboard
.
get
(
'
uid
'
)]
=
True
aggregate_dashboards
=
{
aggregate_dashboards
=
{
'
CLS PEERS
'
:
{
'
CLS PEERS
'
:
{
...
@@ -296,6 +322,7 @@ def provision(config):
...
@@ -296,6 +322,7 @@ def provision(config):
pass
pass
else
:
else
:
with
ProcessPoolExecutor
(
max_workers
=
4
)
as
executor
:
with
ProcessPoolExecutor
(
max_workers
=
4
)
as
executor
:
provisioned
=
[]
agg_folder
=
find_folder
(
token_request
,
'
Aggregates
'
)
agg_folder
=
find_folder
(
token_request
,
'
Aggregates
'
)
for
agg_type
,
dash
in
aggregate_dashboards
.
items
():
for
agg_type
,
dash
in
aggregate_dashboards
.
items
():
if
agg_type
in
exclude_agg
:
if
agg_type
in
exclude_agg
:
...
@@ -306,28 +333,40 @@ def provision(config):
...
@@ -306,28 +333,40 @@ def provision(config):
continue
continue
logger
.
info
(
f
'
Provisioning
{
org
[
"
name
"
]
}
'
+
logger
.
info
(
f
'
Provisioning
{
org
[
"
name
"
]
}
'
+
f
'
/Aggregate
{
agg_type
}
dashboards
'
)
f
'
/Aggregate
{
agg_type
}
dashboards
'
)
executor
.
submit
(
provision_aggregate
,
token_request
,
res
=
executor
.
submit
(
provision_aggregate
,
token_request
,
agg_type
,
agg_folder
,
dash
,
agg_type
,
agg_folder
,
dash
,
excluded_interfaces
,
datasource_name
)
excluded_interfaces
,
datasource_name
)
provisioned
.
append
(
res
)
for
result
in
provisioned
:
dashboard
=
result
.
result
()
if
dashboard
is
None
:
continue
dash_list
[
dashboard
.
get
(
'
uid
'
)]
=
True
# NREN Access dashboards
# NREN Access dashboards
# uses a different template than the above.
# uses a different template than the above.
logger
.
info
(
'
Provisioning NREN Access dashboards
'
)
logger
.
info
(
'
Provisioning NREN Access dashboards
'
)
# always recreate NREN folder
delete_folder
(
token_request
,
'
NREN Access
'
)
folder
=
find_folder
(
token_request
,
'
NREN Access
'
)
folder
=
find_folder
(
token_request
,
'
NREN Access
'
)
nrens
=
filter
(
is_nren
,
excluded_interfaces
)
nrens
=
filter
(
is_nren
,
excluded_interfaces
)
generate_all_nrens
(
token_request
,
provisioned
=
generate_all_nrens
(
nrens
,
folder
[
'
id
'
],
datasource_name
)
token_request
,
nrens
,
folder
[
'
id
'
],
datasource_name
)
for
dashboard
in
provisioned
:
if
dashboard
is
None
:
continue
dash_list
[
dashboard
.
get
(
'
uid
'
)]
=
True
# Non-generated dashboards
# Non-generated dashboards
excluded_dashboards
=
org_config
.
get
(
'
excluded_dashboards
'
,
[])
excluded_dashboards
=
org_config
.
get
(
'
excluded_dashboards
'
,
[])
logger
.
info
(
'
Provisioning static dashboards
'
)
logger
.
info
(
'
Provisioning static dashboards
'
)
for
dashboard
in
get_dashboard_definitions
():
for
dashboard
in
get_dashboard_definitions
():
if
dashboard
[
'
title
'
]
not
in
excluded_dashboards
:
if
dashboard
[
'
title
'
]
not
in
excluded_dashboards
:
create_dashboard
(
token_request
,
dashboard
)
res
=
create_dashboard
(
token_request
,
dashboard
)
if
res
:
dash_list
[
res
.
get
(
'
uid
'
)]
=
True
else
:
else
:
delete_dashboard
(
token_request
,
dashboard
)
delete_dashboard
(
token_request
,
dashboard
)
...
@@ -336,6 +375,13 @@ def provision(config):
...
@@ -336,6 +375,13 @@ def provision(config):
logger
.
info
(
'
Configuring Home dashboard
'
)
logger
.
info
(
'
Configuring Home dashboard
'
)
is_staff
=
org
[
'
name
'
]
==
'
GÉANT Staff
'
is_staff
=
org
[
'
name
'
]
==
'
GÉANT Staff
'
set_home_dashboard
(
token_request
,
is_staff
)
set_home_dashboard
(
token_request
,
is_staff
)
# just hardcode that we updated home dashboard
dash_list
[
'
home
'
]
=
True
for
dash
,
provisioned
in
dash_list
.
items
():
if
not
provisioned
:
logger
.
info
(
f
'
Deleting stale dashboard with UID
{
dash
}
'
)
delete_dashboard
(
token_request
,
{
'
uid
'
:
dash
})
logger
.
info
(
f
'
Time to complete:
{
time
.
time
()
-
start
}
'
)
logger
.
info
(
f
'
Time to complete:
{
time
.
time
()
-
start
}
'
)
for
org_id
,
token
in
tokens
:
for
org_id
,
token
in
tokens
:
...
...
This diff is collapsed.
Click to expand it.
test/test_update.py
+
25
−
1
View file @
88751ac8
import
responses
import
responses
import
json
import
json
import
re
import
re
from
brian_dashboard_manager.grafana.utils.request
import
TokenRequest
from
brian_dashboard_manager.templating.nren_access
import
get_nrens
from
brian_dashboard_manager.templating.nren_access
import
get_nrens
from
brian_dashboard_manager.grafana.provision
import
provision_folder
,
\
from
brian_dashboard_manager.grafana.provision
import
provision_folder
,
\
generate_all_nrens
,
provision
generate_all_nrens
,
provision
...
@@ -241,6 +242,7 @@ def test_provision_folder(data_config, mocker):
...
@@ -241,6 +242,7 @@ def test_provision_folder(data_config, mocker):
'
testdatasource
'
,
[
'
CLS TESTDASHBOARD
'
])
'
testdatasource
'
,
[
'
CLS TESTDASHBOARD
'
])
@responses.activate
def
test_provision_nrens
(
data_config
,
mocker
):
def
test_provision_nrens
(
data_config
,
mocker
):
NREN_INTERFACES
=
[
NREN_INTERFACES
=
[
# physical
# physical
...
@@ -299,12 +301,34 @@ def test_provision_nrens(data_config, mocker):
...
@@ -299,12 +301,34 @@ def test_provision_nrens(data_config, mocker):
}
}
]
]
UID
=
'
1337
'
def
get_callback
(
request
):
query
=
request
.
params
.
get
(
'
query
'
)
return
200
,
{},
json
.
dumps
({
'
uid
'
:
UID
,
'
title
'
:
query
})
responses
.
add_callback
(
method
=
responses
.
GET
,
url
=
re
.
compile
(
f
"
http://
{
data_config
[
'
hostname
'
]
}
/api/search
"
),
callback
=
get_callback
)
def
post_callback
(
request
):
dashboard
=
json
.
loads
(
request
.
body
).
get
(
'
dashboard
'
)
title
=
dashboard
.
get
(
'
title
'
)
return
200
,
{},
json
.
dumps
({
'
uid
'
:
UID
,
'
title
'
:
title
})
responses
.
add_callback
(
method
=
responses
.
POST
,
url
=
re
.
compile
(
f
"
http://
{
data_config
[
'
hostname
'
]
}
/api/dashboards/db
"
),
callback
=
post_callback
)
nrens
=
get_nrens
(
NREN_INTERFACES
)
nrens
=
get_nrens
(
NREN_INTERFACES
)
assert
len
(
nrens
)
==
1
and
nrens
.
get
(
'
HEANET
'
)
is
not
None
assert
len
(
nrens
)
==
1
and
nrens
.
get
(
'
HEANET
'
)
is
not
None
assert
len
(
nrens
.
get
(
'
HEANET
'
).
get
(
'
AGGREGATES
'
))
==
1
assert
len
(
nrens
.
get
(
'
HEANET
'
).
get
(
'
AGGREGATES
'
))
==
1
assert
len
(
nrens
.
get
(
'
HEANET
'
).
get
(
'
SERVICES
'
))
==
1
assert
len
(
nrens
.
get
(
'
HEANET
'
).
get
(
'
SERVICES
'
))
==
1
assert
len
(
nrens
.
get
(
'
HEANET
'
).
get
(
'
PHYSICAL
'
))
==
2
assert
len
(
nrens
.
get
(
'
HEANET
'
).
get
(
'
PHYSICAL
'
))
==
2
generate_all_nrens
(
None
,
NREN_INTERFACES
,
1
,
'
testdatasource
'
)
token_request
=
TokenRequest
(
token
=
'
testtoken
'
,
**
data_config
)
generate_all_nrens
(
token_request
,
NREN_INTERFACES
,
1
,
'
testdatasource
'
)
@responses.activate
@responses.activate
...
...
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment