Coverage for src/chuck_data/databricks/permission_validator.py: 0%

63 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-06-05 22:56 -0700

1""" 

2Module for validating Databricks API token permissions. 

3Provides functions to check access levels for different Databricks resources. 

4""" 

5 

6import logging 

7from typing import Dict, Any 

8 

9 

10def validate_all_permissions(client) -> Dict[str, Dict[str, Any]]: 

11 """ 

12 Run all permission checks and return detailed results. 

13 

14 Args: 

15 client: API client instance with token 

16 

17 Returns: 

18 Dict of permission check results by resource area 

19 """ 

20 results = { 

21 "basic_connectivity": check_basic_connectivity(client), 

22 "unity_catalog": check_unity_catalog(client), 

23 "sql_warehouse": check_sql_warehouse(client), 

24 "jobs": check_jobs(client), 

25 "models": check_models(client), 

26 "volumes": check_volumes(client), 

27 } 

28 

29 return results 

30 

31 

32def check_basic_connectivity(client): 

33 """ 

34 Check basic API connectivity using identity API. 

35 """ 

36 try: 

37 response = client.get("/api/2.0/preview/scim/v2/Me") 

38 username = response.get("userName", "unknown") 

39 return { 

40 "authorized": True, 

41 "details": f"Connected as {username}", 

42 "api_path": "/api/2.0/preview/scim/v2/Me", 

43 } 

44 except Exception as e: 

45 logging.debug(f"Basic connectivity check failed: {e}") 

46 return { 

47 "authorized": False, 

48 "error": str(e), 

49 "api_path": "/api/2.0/preview/scim/v2/Me", 

50 } 

51 

52 

53def check_unity_catalog(client): 

54 """ 

55 Check Unity Catalog access permission. 

56 """ 

57 try: 

58 # Try listing catalogs with minimal results 

59 response = client.get("/api/2.1/unity-catalog/catalogs?max_results=1") 

60 catalog_count = len(response.get("catalogs", [])) 

61 return { 

62 "authorized": True, 

63 "details": f"Unity Catalog access granted ({catalog_count} catalogs visible)", 

64 "api_path": "/api/2.1/unity-catalog/catalogs", 

65 } 

66 except Exception as e: 

67 logging.debug(f"Unity Catalog check failed: {e}") 

68 return { 

69 "authorized": False, 

70 "error": str(e), 

71 "api_path": "/api/2.1/unity-catalog/catalogs", 

72 } 

73 

74 

75def check_sql_warehouse(client): 

76 """ 

77 Check SQL warehouse access permission. 

78 """ 

79 try: 

80 response = client.get("/api/2.0/sql/warehouses?page_size=1") 

81 warehouse_count = len(response.get("warehouses", [])) 

82 return { 

83 "authorized": True, 

84 "details": f"SQL Warehouse access granted ({warehouse_count} warehouses visible)", 

85 "api_path": "/api/2.0/sql/warehouses", 

86 } 

87 except Exception as e: 

88 logging.debug(f"SQL Warehouse check failed: {e}") 

89 return { 

90 "authorized": False, 

91 "error": str(e), 

92 "api_path": "/api/2.0/sql/warehouses", 

93 } 

94 

95 

96def check_jobs(client): 

97 """ 

98 Check Jobs access permission. 

99 """ 

100 try: 

101 response = client.get("/api/2.1/jobs/list?limit=1") 

102 job_count = len(response.get("jobs", [])) 

103 return { 

104 "authorized": True, 

105 "details": f"Jobs access granted ({job_count} jobs visible)", 

106 "api_path": "/api/2.1/jobs/list", 

107 } 

108 except Exception as e: 

109 logging.debug(f"Jobs check failed: {e}") 

110 return {"authorized": False, "error": str(e), "api_path": "/api/2.1/jobs/list"} 

111 

112 

113def check_models(client): 

114 """ 

115 Check ML models access permission. 

116 """ 

117 try: 

118 response = client.get("/api/2.0/mlflow/registered-models/list?max_results=1") 

119 model_count = len(response.get("registered_models", [])) 

120 return { 

121 "authorized": True, 

122 "details": f"ML Models access granted ({model_count} models visible)", 

123 "api_path": "/api/2.0/mlflow/registered-models/list", 

124 } 

125 except Exception as e: 

126 logging.debug(f"Models check failed: {e}") 

127 return { 

128 "authorized": False, 

129 "error": str(e), 

130 "api_path": "/api/2.0/mlflow/registered-models/list", 

131 } 

132 

133 

134def check_volumes(client): 

135 """ 

136 Check Volumes access permission in Unity Catalog. 

137 """ 

138 # For volumes, we need a catalog and schema 

139 try: 

140 # First get a catalog 

141 catalog_response = client.get("/api/2.1/unity-catalog/catalogs?max_results=1") 

142 catalogs = catalog_response.get("catalogs", []) 

143 

144 if not catalogs: 

145 return { 

146 "authorized": False, 

147 "error": "No catalogs available to check volumes access", 

148 "api_path": "/api/2.1/unity-catalog/volumes", 

149 } 

150 

151 catalog_name = catalogs[0].get("name") 

152 

153 # Then get a schema 

154 schema_response = client.get( 

155 f"/api/2.1/unity-catalog/schemas?catalog_name={catalog_name}&max_results=1" 

156 ) 

157 schemas = schema_response.get("schemas", []) 

158 

159 if not schemas: 

160 return { 

161 "authorized": False, 

162 "error": f"No schemas available in catalog '{catalog_name}' to check volumes access", 

163 "api_path": "/api/2.1/unity-catalog/volumes", 

164 } 

165 

166 schema_name = schemas[0].get("name") 

167 

168 # Now check volumes 

169 volume_response = client.get( 

170 f"/api/2.1/unity-catalog/volumes?catalog_name={catalog_name}&schema_name={schema_name}" 

171 ) 

172 volume_count = len(volume_response.get("volumes", [])) 

173 

174 return { 

175 "authorized": True, 

176 "details": f"Volumes access granted in {catalog_name}.{schema_name} ({volume_count} volumes visible)", 

177 "api_path": "/api/2.1/unity-catalog/volumes", 

178 } 

179 except Exception as e: 

180 logging.debug(f"Volumes check failed: {e}") 

181 return { 

182 "authorized": False, 

183 "error": str(e), 

184 "api_path": "/api/2.1/unity-catalog/volumes", 

185 }