11import logging
2- import os
32import time
43import json
54import httpx
5+ from pathlib import Path
66from string import Template
77from psycopg import AsyncConnection
8+ from ..settings import settings
89
910logger = logging .getLogger (__name__ )
1011
1112DEFAULT_HEADERS = {"Content-Type" : "application/json" }
12- DRYCC_CONTROLLER_URL = os .environ .get ('DRYCC_CONTROLLER_URL' )
13- DRYCC_GRAFANA_REFRESH = os .environ .get ('DRYCC_GRAFANA_REFRESH' , '60s' )
14- DRYCC_GRAFANA_DASHBOARD = os .path .join (os .path .dirname (os .path .abspath (__file__ )), "../" )
13+ DRYCC_GRAFANA_DASHBOARD = Path (__file__ ).resolve ().parent .parent
1514
1615# Drycc Workspace role to Grafana role mapping
1716DRYCC_WORKSPACE_ROLE_MAPPING = {"admin" : "Editor" , "member" : "Editor" , "viewer" : "Viewer" }
@@ -107,15 +106,15 @@ async def sync_alerting(context: dict, token: dict, userinfo: dict):
107106 The alerts field only controls notification channels (handled in sync_default).
108107 """
109108 workspace_orgs = context .get ("workspace_orgs" , {})
110- alerting_path = os . path . join ( os . path . dirname ( __file__ ), ".." , "alerting" )
109+ alerting_path = Path ( __file__ ). resolve (). parent . parent / "alerting"
111110
112111 for ws_name , ws_info in workspace_orgs .items ():
113112 org_id = ws_info ["org_id" ]
114113 ctx = {** context , "org_id" : org_id }
115114
116115 async with httpx .AsyncClient () as client :
117- for filename in os . listdir ( alerting_path ):
118- with open (os . path . join ( alerting_path , filename ) ) as f :
116+ for filepath in alerting_path . glob ( "*.json" ):
117+ with filepath . open () as f :
119118 rule = json .load (f )
120119 # Use PUT for idempotent upsert (POST would create duplicates)
121120 resp = await client .put (
@@ -135,23 +134,20 @@ async def sync_alerting(context: dict, token: dict, userinfo: dict):
135134async def sync_datasources (context : dict , token : dict , userinfo : dict ):
136135 """Create datasources for each workspace org with workspace-specific URLs."""
137136 workspace_orgs = context .get ("workspace_orgs" , {})
138- datasources_path = os .path .join (os .path .dirname (__file__ ), ".." , "datasources" )
139- drycc_token = context .get ("drycc_token" )
137+ datasources_path = Path (__file__ ).resolve ().parent .parent / "datasources"
140138
141139 for ws_name , ws_info in workspace_orgs .items ():
142140 org_id = ws_info ["org_id" ]
143141 ctx = {** context , "org_id" : org_id }
144142 headers = _api_headers (ctx , userinfo )
145143
146144 async with httpx .AsyncClient () as client :
147- for filename in os . listdir ( datasources_path ):
148- with open (os . path . join ( datasources_path , filename ) ) as f :
145+ for filepath in datasources_path . glob ( "*.json" ):
146+ with filepath . open () as f :
149147 template = Template (f .read ())
150148 datasource = json .loads (template .substitute (
151- controller_url = DRYCC_CONTROLLER_URL ,
152- workspace = ws_name ,
153- time_interval = DRYCC_GRAFANA_REFRESH ,
154- token = drycc_token
149+ controller_url = settings .drycc_controller_url ,
150+ time_interval = settings .drycc_grafana_refresh
155151 ))
156152 resp = await client .get (
157153 _api_url (f"/api/datasources/name/{ datasource ['name' ]} " ), headers = headers )
@@ -174,17 +170,17 @@ async def sync_datasources(context: dict, token: dict, userinfo: dict):
174170async def sync_dashboards (context : dict , token : dict , userinfo : dict ):
175171 """Create dashboards for each workspace org."""
176172 workspace_orgs = context .get ("workspace_orgs" , {})
177- dashboards_path = os . path . join ( os . path . dirname ( __file__ ), ".." , "dashboards" )
173+ dashboards_path = Path ( __file__ ). resolve (). parent . parent / "dashboards"
178174
179175 for ws_name , ws_info in workspace_orgs .items ():
180176 org_id = ws_info ["org_id" ]
181177 ctx = {** context , "org_id" : org_id }
182178
183179 async with httpx .AsyncClient () as client :
184- for filename in os . listdir ( dashboards_path ):
185- with open (os . path . join ( dashboards_path , filename ) ) as f :
180+ for filepath in dashboards_path . glob ( "*.json" ):
181+ with filepath . open () as f :
186182 dashboard = json .load (f )
187- dashboard .update ({"id" : None , "refresh" : DRYCC_GRAFANA_REFRESH })
183+ dashboard .update ({"id" : None , "refresh" : settings . drycc_grafana_refresh })
188184 await client .post (
189185 _api_url ("/api/dashboards/db" ),
190186 headers = _api_headers (ctx , userinfo ),
@@ -202,12 +198,12 @@ async def sync_dashboards(context: dict, token: dict, userinfo: dict):
202198def _api_url (url_path , is_admin = False ):
203199 if is_admin :
204200 return "http://{}:{}@localhost:{}{}" .format (
205- os . environ . get ( 'GF_SECURITY_ADMIN_USER' ) ,
206- os . environ . get ( 'GF_SECURITY_ADMIN_PASSWORD' ) ,
207- os . environ . get ( 'GF_SERVER_HTTP_PORT' , 3000 ) ,
208- url_path ,
201+ settings . gf_security_admin_user ,
202+ settings . gf_security_admin_password ,
203+ settings . gf_server_http_port ,
204+ url_path
209205 )
210- return "http://localhost:{}{}" .format (os . environ . get ( 'GF_SERVER_HTTP_PORT' , 3000 ) , url_path )
206+ return "http://localhost:{}{}" .format (settings . gf_server_http_port , url_path )
211207
212208
213209def _api_headers (context : dict , userinfo ):
@@ -233,7 +229,7 @@ async def _get_workspaces(drycc_token: str) -> list:
233229 headers = {"Authorization" : f"Token { drycc_token } " }
234230 async with httpx .AsyncClient () as client :
235231 resp = await client .get (
236- f"{ DRYCC_CONTROLLER_URL } /v2/workspaces" , headers = headers )
232+ f"{ settings . drycc_controller_url } /v2/workspaces" , headers = headers )
237233 resp .raise_for_status ()
238234 return resp .json ().get ("results" , [])
239235
@@ -243,7 +239,7 @@ async def _get_workspace_members(workspace_name: str, drycc_token: str) -> list:
243239 headers = {"Authorization" : f"Token { drycc_token } " }
244240 async with httpx .AsyncClient () as client :
245241 resp = await client .get (
246- f"{ DRYCC_CONTROLLER_URL } /v2/workspaces/{ workspace_name } /members" ,
242+ f"{ settings . drycc_controller_url } /v2/workspaces/{ workspace_name } /members" ,
247243 headers = headers )
248244 resp .raise_for_status ()
249245 return resp .json ().get ("results" , [])
@@ -420,7 +416,7 @@ def _build_alertmanager_config(alert_addresses: str) -> str:
420416
421417async def _upsert_alert_configuration (org_id : int , config : str ):
422418 """Insert or update alert configuration for an org using parameterized query."""
423- async with await AsyncConnection .connect (os . environ . get ( "GF_DATABASE_URL" ) ) as conn :
419+ async with await AsyncConnection .connect (settings . gf_database_url ) as conn :
424420 async with conn .cursor () as cursor :
425421 await cursor .execute (
426422 """
@@ -438,37 +434,6 @@ async def _upsert_alert_configuration(org_id: int, config: str):
438434
439435
440436async def _get_or_create_drycc_token (username , token : dict ):
441- async def _check_or_create_drycc_token (drycc_token , token ):
442- async with httpx .AsyncClient () as client :
443- created = False if drycc_token else True
444- if drycc_token :
445- headers = {"Authorization" : f"Token { drycc_token } " }
446- resp = await client .get (
447- f"{ DRYCC_CONTROLLER_URL } /v2/auth/whoami" , headers = headers )
448- if resp .status_code in [401 , 403 ]:
449- created = True
450- if created :
451- headers = {"Authorization" : f"Bearer { token ['access_token' ]} " }
452- data = (await client .post (
453- f"{ DRYCC_CONTROLLER_URL } /v2/auth/token/?alias=grafana-datasource" ,
454- headers = headers , json = token )).json ()
455- drycc_token = data ["token" ]
456- return created , drycc_token
457-
458- async with await AsyncConnection .connect (os .environ .get ("GF_DATABASE_URL" )) as conn :
459- async with conn .cursor () as cursor :
460- await cursor .execute (
461- "SELECT o_auth_id_token FROM user_auth WHERE auth_module=%s AND auth_id=%s" ,
462- ("authproxy" , username )
463- )
464- row = await cursor .fetchone ()
465- drycc_token = row [0 ] if row else None
466- created , drycc_token = await _check_or_create_drycc_token (drycc_token , token )
467- if created :
468- async with conn .cursor () as cursor :
469- await cursor .execute (
470- "UPDATE user_auth SET o_auth_id_token=%s WHERE auth_module=%s AND auth_id=%s" ,
471- (drycc_token , "authproxy" , username )
472- )
473- await conn .commit ()
474- return created , drycc_token
437+ # Pass through the Passport access_token directly, no need for DRF token conversion
438+ drycc_token = token .get ("access_token" )
439+ return True , drycc_token
0 commit comments