waldur-site-agent-cscs-dwdi 0.7.5__py3-none-any.whl → 0.7.6__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of waldur-site-agent-cscs-dwdi might be problematic. Click here for more details.

@@ -5,7 +5,9 @@ from datetime import datetime, timezone
5
5
  from typing import Any, Optional
6
6
 
7
7
  from waldur_api_client.models.resource import Resource as WaldurResource
8
+ from waldur_api_client.types import Unset
8
9
 
10
+ from waldur_site_agent.backend import structures
9
11
  from waldur_site_agent.backend.backends import BaseBackend
10
12
 
11
13
  from .client import CSCSDWDIClient
@@ -59,6 +61,21 @@ class CSCSDWDIComputeBackend(BaseBackend):
59
61
  if self.socks_proxy:
60
62
  logger.info("CSCS-DWDI Compute Backend: Using SOCKS proxy: %s", self.socks_proxy)
61
63
 
64
+ def pull_resource(
65
+ self, waldur_resource: WaldurResource
66
+ ) -> Optional[structures.BackendResourceInfo]:
67
+ """Pull resource from backend with cluster filtering support."""
68
+ try:
69
+ backend_id = waldur_resource.backend_id
70
+ backend_resource_info = self._pull_backend_resource(backend_id, waldur_resource)
71
+ if backend_resource_info is None:
72
+ return None
73
+ except Exception:
74
+ logger.exception("Error while pulling resource [%s]", backend_id)
75
+ return None
76
+ else:
77
+ return backend_resource_info
78
+
62
79
  def ping(self, raise_exception: bool = False) -> bool: # noqa: ARG002
63
80
  """Check if CSCS-DWDI API is accessible.
64
81
 
@@ -71,7 +88,7 @@ class CSCSDWDIComputeBackend(BaseBackend):
71
88
  return self.cscs_client.ping()
72
89
 
73
90
  def _get_usage_report(
74
- self, resource_backend_ids: list[str]
91
+ self, resource_backend_ids: list[str], clusters: Optional[list[str]] = None
75
92
  ) -> dict[str, dict[str, dict[str, float]]]:
76
93
  """Get usage report for specified resources.
77
94
 
@@ -80,6 +97,7 @@ class CSCSDWDIComputeBackend(BaseBackend):
80
97
 
81
98
  Args:
82
99
  resource_backend_ids: List of account identifiers to report on
100
+ clusters: Optional list of cluster names to filter by
83
101
 
84
102
  Returns:
85
103
  Dictionary mapping account names to usage data:
@@ -120,6 +138,7 @@ class CSCSDWDIComputeBackend(BaseBackend):
120
138
  accounts=resource_backend_ids,
121
139
  from_date=from_date,
122
140
  to_date=to_date,
141
+ clusters=clusters,
123
142
  )
124
143
 
125
144
  # Process the response
@@ -262,6 +281,69 @@ class CSCSDWDIComputeBackend(BaseBackend):
262
281
 
263
282
  return usage
264
283
 
284
+ def _pull_backend_resource(
285
+ self, resource_backend_id: str, waldur_resource: Optional[WaldurResource] = None
286
+ ) -> Optional[structures.BackendResourceInfo]:
287
+ """Pull resource data from the DWDI backend for usage reporting.
288
+
289
+ For DWDI, we treat the resource_backend_id as an account name
290
+ and fetch usage data for that account from the DWDI API.
291
+
292
+ Args:
293
+ resource_backend_id: Account name (e.g., 'g207')
294
+ waldur_resource: Optional Waldur resource object for filtering
295
+
296
+ Returns:
297
+ BackendResourceInfo with usage data or None if account not found
298
+ """
299
+ logger.info("Pulling resource %s", resource_backend_id)
300
+
301
+ # For DWDI, the resource_backend_id is the account name
302
+ account_name = resource_backend_id
303
+
304
+ # Extract cluster from offering_slug for filtering (always lowercase)
305
+ clusters = None
306
+ if (
307
+ waldur_resource
308
+ and hasattr(waldur_resource, "offering_slug")
309
+ and waldur_resource.offering_slug
310
+ and not isinstance(waldur_resource.offering_slug, Unset)
311
+ ):
312
+ # Use offering_slug as cluster name, converted to lowercase
313
+ cluster_name = waldur_resource.offering_slug.lower()
314
+ clusters = [cluster_name]
315
+ logger.info(
316
+ "Filtering DWDI query by cluster: %s (lowercase from offering_slug)",
317
+ cluster_name,
318
+ )
319
+
320
+ # Get usage data for this account
321
+ try:
322
+ usage_report = self._get_usage_report([account_name], clusters=clusters)
323
+
324
+ if account_name not in usage_report:
325
+ logger.warning("There is no account with ID %s in the DWDI backend", account_name)
326
+ return None
327
+
328
+ # Extract usage data for this account
329
+ account_usage = usage_report[account_name]
330
+
331
+ # Extract users (everyone except TOTAL_ACCOUNT_USAGE)
332
+ users = [username for username in account_usage if username != "TOTAL_ACCOUNT_USAGE"]
333
+
334
+ logger.info(
335
+ "Found usage data for account %s with %d users: %s", account_name, len(users), users
336
+ )
337
+
338
+ return structures.BackendResourceInfo(
339
+ users=users,
340
+ usage=account_usage,
341
+ )
342
+
343
+ except Exception:
344
+ logger.exception("Error while pulling account %s from DWDI", account_name)
345
+ return None
346
+
265
347
  # Methods not implemented for reporting-only backend
266
348
  def get_account(self, account_name: str) -> Optional[dict[str, Any]]:
267
349
  """Not implemented for reporting-only backend."""
@@ -126,7 +126,11 @@ class CSCSDWDIClient:
126
126
  return self._token
127
127
 
128
128
  def get_usage_for_month(
129
- self, accounts: list[str], from_date: date, to_date: date
129
+ self,
130
+ accounts: list[str],
131
+ from_date: date,
132
+ to_date: date,
133
+ clusters: Optional[list[str]] = None,
130
134
  ) -> dict[str, Any]:
131
135
  """Get usage data for multiple accounts for a month range.
132
136
 
@@ -134,6 +138,7 @@ class CSCSDWDIClient:
134
138
  accounts: List of account identifiers to query
135
139
  from_date: Start date (beginning of month)
136
140
  to_date: End date (end of month)
141
+ clusters: Optional list of cluster names to filter by
137
142
 
138
143
  Returns:
139
144
  API response with usage data grouped by account
@@ -156,9 +161,13 @@ class CSCSDWDIClient:
156
161
  if accounts:
157
162
  params["account"] = accounts
158
163
 
164
+ # Add cluster filters if provided
165
+ if clusters:
166
+ params["cluster"] = clusters
167
+
159
168
  headers = {"Authorization": f"Bearer {token}"}
160
169
 
161
- url = f"{self.api_url}/api/v1/compute/usage-month-multiaccount"
170
+ url = f"{self.api_url}/compute/usage-month/account"
162
171
 
163
172
  logger.debug(
164
173
  "Fetching usage for accounts %s from %s to %s",
@@ -179,7 +188,11 @@ class CSCSDWDIClient:
179
188
  return response.json()
180
189
 
181
190
  def get_usage_for_days(
182
- self, accounts: list[str], from_date: date, to_date: date
191
+ self,
192
+ accounts: list[str],
193
+ from_date: date,
194
+ to_date: date,
195
+ clusters: Optional[list[str]] = None,
183
196
  ) -> dict[str, Any]:
184
197
  """Get usage data for multiple accounts for a day range.
185
198
 
@@ -187,6 +200,7 @@ class CSCSDWDIClient:
187
200
  accounts: List of account identifiers to query
188
201
  from_date: Start date
189
202
  to_date: End date
203
+ clusters: Optional list of cluster names to filter by
190
204
 
191
205
  Returns:
192
206
  API response with usage data grouped by account
@@ -209,9 +223,13 @@ class CSCSDWDIClient:
209
223
  if accounts:
210
224
  params["account"] = accounts
211
225
 
226
+ # Add cluster filters if provided
227
+ if clusters:
228
+ params["cluster"] = clusters
229
+
212
230
  headers = {"Authorization": f"Bearer {token}"}
213
231
 
214
- url = f"{self.api_url}/api/v1/compute/usage-day-multiaccount"
232
+ url = f"{self.api_url}/compute/usage-day/account"
215
233
 
216
234
  logger.debug(
217
235
  "Fetching daily usage for accounts %s from %s to %s",
@@ -272,7 +290,7 @@ class CSCSDWDIClient:
272
290
 
273
291
  headers = {"Authorization": f"Bearer {token}"}
274
292
 
275
- url = f"{self.api_url}/api/v1/storage/usage-month/filesystem_name/data_type"
293
+ url = f"{self.api_url}/storage/usage-month/{filesystem}/{data_type}"
276
294
 
277
295
  logger.debug(
278
296
  "Fetching storage usage for paths %s for month %s",
@@ -332,7 +350,7 @@ class CSCSDWDIClient:
332
350
 
333
351
  headers = {"Authorization": f"Bearer {token}"}
334
352
 
335
- url = f"{self.api_url}/api/v1/storage/usage-day/filesystem_name/data_type"
353
+ url = f"{self.api_url}/storage/usage-day/{filesystem}/{data_type}"
336
354
 
337
355
  logger.debug(
338
356
  "Fetching storage usage for paths %s for date %s",
@@ -368,7 +386,7 @@ class CSCSDWDIClient:
368
386
  "to": today.strftime("%Y-%m-%d"),
369
387
  }
370
388
 
371
- url = f"{self.api_url}/api/v1/compute/usage-day-multiaccount"
389
+ url = f"{self.api_url}/compute/usage-day"
372
390
 
373
391
  # Configure httpx client with SOCKS proxy if specified
374
392
  client_args: dict[str, Any] = {"timeout": 10.0}
@@ -399,7 +417,10 @@ class CSCSDWDIClient:
399
417
  "exact-date": today.strftime("%Y-%m-%d"),
400
418
  }
401
419
 
402
- url = f"{self.api_url}/api/v1/storage/usage-day/filesystem_name/data_type"
420
+ # Use default values for ping test
421
+ filesystem = "lustre"
422
+ data_type = "projects"
423
+ url = f"{self.api_url}/storage/usage-day/{filesystem}/{data_type}"
403
424
 
404
425
  # Configure httpx client with SOCKS proxy if specified
405
426
  client_args: dict[str, Any] = {"timeout": 10.0}
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: waldur-site-agent-cscs-dwdi
3
- Version: 0.7.5
3
+ Version: 0.7.6
4
4
  Summary: CSCS-DWDI reporting plugin for Waldur Site Agent
5
5
  Author-email: OpenNode Team <info@opennodecloud.com>
6
6
  Requires-Python: <4,>=3.9
@@ -0,0 +1,7 @@
1
+ waldur_site_agent_cscs_dwdi/__init__.py,sha256=OHO1yF5NTGt0otI-GollR_ppPXP--aUZRCdaT5-8IWw,56
2
+ waldur_site_agent_cscs_dwdi/backend.py,sha256=AWZuuY24KDGB5RWZhonoPrbIKpnrPc6D5WwwE6E8F6Y,30155
3
+ waldur_site_agent_cscs_dwdi/client.py,sha256=6YrMky3pUfBJSAMYFAavBOz7-pooQIfqNjsBVk__K6g,14314
4
+ waldur_site_agent_cscs_dwdi-0.7.6.dist-info/METADATA,sha256=9MZUrv-3X3VmDqW2eA3wFCxwQFswQwaMeGRoghOmdLY,8131
5
+ waldur_site_agent_cscs_dwdi-0.7.6.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
+ waldur_site_agent_cscs_dwdi-0.7.6.dist-info/entry_points.txt,sha256=gbp1thULdYQN4leLZeM8TBoruPSGQEKQxlQ0fg8u3Ug,187
7
+ waldur_site_agent_cscs_dwdi-0.7.6.dist-info/RECORD,,
@@ -1,7 +0,0 @@
1
- waldur_site_agent_cscs_dwdi/__init__.py,sha256=OHO1yF5NTGt0otI-GollR_ppPXP--aUZRCdaT5-8IWw,56
2
- waldur_site_agent_cscs_dwdi/backend.py,sha256=2A53fAvjwnCaxsuA42bdqxHEp0DrwN1F4MYoB1ryCuQ,26846
3
- waldur_site_agent_cscs_dwdi/client.py,sha256=sqCBpioe5d6sJwp-iVGUL3AUIOxkXqTEA6u6mmd0F_Y,13782
4
- waldur_site_agent_cscs_dwdi-0.7.5.dist-info/METADATA,sha256=ncgQidSFZxvbh4jjAipUfQ7zhZrDm_qnCvcDzc_brag,8131
5
- waldur_site_agent_cscs_dwdi-0.7.5.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
6
- waldur_site_agent_cscs_dwdi-0.7.5.dist-info/entry_points.txt,sha256=gbp1thULdYQN4leLZeM8TBoruPSGQEKQxlQ0fg8u3Ug,187
7
- waldur_site_agent_cscs_dwdi-0.7.5.dist-info/RECORD,,