Implement list and delete snapshot functionality in Python SDK#448
Implement list and delete snapshot functionality in Python SDK#448shrutiyam-glitch wants to merge 3 commits intokubernetes-sigs:mainfrom
Conversation
✅ Deploy Preview for agent-sandbox canceled.
|
|
[APPROVALNOTIFIER] This PR is NOT APPROVED This pull-request has been approved by: shrutiyam-glitch The full list of commands accepted by this bot can be found here. DetailsNeeds approval from an approver in each of these files:Approvers can indicate their approval by writing |
| """Result of a list snapshots operation.""" | ||
|
|
||
| success: bool | ||
| snapshots: list[dict[str, str]] |
There was a problem hiding this comment.
Instead of returning a list[dict[str, str]], wdyt about creating a dedicated dataclass (e.g., SnapshotInfo or SnapshotDetail) for the snapshot representation ?
|
|
||
| valid_snapshots.append( | ||
| { | ||
| "snapshot_id": metadata.get("name"), |
There was a problem hiding this comment.
We are mapping metadata.get("name") to snapshot_id here. However, down below in delete_snapshots, the parameter is named snapshot_uid. Please add a small docstring note or standardizing the terminology across the client to snapshot_name to prevent confusion.
| ) | ||
|
|
||
| # Sort snapshots by creation timestamp descending | ||
| valid_snapshots.sort(key=lambda x: x["creationTimestamp"], reverse=True) |
There was a problem hiding this comment.
If a snapshot object is missing creationTimestamp or it explicitly evaluates to None for any unforeseen reason, sorting might throw a TypeError. To be safe, you can use key=lambda x: x["creationTimestamp"] or "".
| - If snapshot_uid is provided, deletes that specific snapshot. | ||
| - If grouping_labels is provided, deletes all snapshots matching the grouping labels. | ||
| - If not provided, deletes ALL snapshots for this pod. | ||
| Returns a DeleteSnapshotResult containing the list of successfully deleted snapshots. |
There was a problem hiding this comment.
Just to confirm my understanding here. If a user passes both snapshot_uid and grouping_labels to this method, grouping_labels will be silently ignored, right ? It would be safer to either explicitly enforce mutual exclusivity by raising a ValueError, or at least log a warning that the labels are being ignored when a UID is specified or document this case...
| snapshots_to_delete.append(snapshot_uid) | ||
| else: | ||
| logger.info( | ||
| "No snapshot_uid provided. Deleting ALL snapshots for this pod." |
There was a problem hiding this comment.
This log message says "Deleting ALL snapshots for this pod." But, if grouping_labels is provided, it's actually filtering and only deleting a matching subset. Should we reword this to something like: "No snapshot_uid provided. Fetching snapshots to delete based on pod name and labels."
| error_code=SNAPSHOT_ERROR_CODE, | ||
| ) | ||
| if ( | ||
| snapshots_result |
There was a problem hiding this comment.
snapshots_result is a ListSnapshotResult dataclass instance, so shouldn't this always be "true" ? . Maybe you can simplify this condition to:
if snapshots_result.success and snapshots_result.snapshots:
| name=uid, | ||
| ) | ||
| logger.info(f"PodSnapshot '{uid}' deleted.") | ||
| deleted_snapshots.append(uid) |
There was a problem hiding this comment.
When deleting a list of snapshots (batch deletion), if one deletion throws an ApiException (other than 404), the function returns immediately. This leaves the remaining targeted snapshots undeleted. Let's accumulate the errors in a list and continuing the loop, then returning an aggregated failure response at the end so it attempts to delete as many as they were intended.
There was a problem hiding this comment.
If one deletion fails in the middle, there is another case where it returns success=False, but partial delete happened
| and snapshots_result.snapshots | ||
| ): | ||
| snapshots_to_delete = [ | ||
| s["snapshot_id"] for s in snapshots_result.snapshots |
There was a problem hiding this comment.
is it the snapshot name or uid here? not clear, if the name is needed Rename the parameter to snapshot_name, could be confusing
| ) | ||
| if ( | ||
| snapshots_result | ||
| and snapshots_result.success |
There was a problem hiding this comment.
You already checked not snapshots_result.success above
| @@ -19,11 +19,13 @@ | |||
| PodSnapshotSandboxClient, | |||
There was a problem hiding this comment.
Missing Tests
test for list_snapshots with ready_only=False
There is no unit test verifying that passing ready_only=False includes non-ready snapshots. This is a key feature path.
test for delete_snapshots with snapshot_uid and grouping_labels both provided
The docstring implies only snapshot_uid is used when both are provided — but there's no test asserting that grouping_labels is ignored in that case.
test for delete_snapshots with a generic Exception
delete_snapshots loop catches Exception in addition to ApiException, but there's no unit test for this code path.
|
|
||
| # Sort snapshots by creation timestamp descending | ||
| valid_snapshots.sort(key=lambda x: x["creationTimestamp"], reverse=True) | ||
| logger.info(f"Found {len(valid_snapshots)} ready snapshots.") |
There was a problem hiding this comment.
This will print also when ready_only=False, just change the wording
| ) | ||
| else: | ||
| print( | ||
| f"No ready snapshots found or failed: {list_result.error_reason if list_result else ''}" |
There was a problem hiding this comment.
Is this check complete?, it just check the object type, will not reach else
This PR implements the ability to list and delete Pod Snapshots within the
PodSnapshotSandboxClient.Core Logic Implementation:
*
list_snapshots(grouping_labels, ready_only):-- Fetches PodSnapshots using Kubernetes label selectors.
-- Returns a list of snapshots sorted by creation timestamp (newest first).
-- Supports filtering for snapshots in the Ready state.
*
delete_snapshots(grouping_labels, snapshot_uid):-- Allows deleting a specific snapshot by UID.
-- Supports bulk deletion based on grouping labels or deleting all snapshots associated with the pod.
Testing Done:
Integration Test: Added
test_podsnapshot_extension.pywhich verifies the full E2E flow:-- creating multiple snapshots, listing them, and performing a cleanup deletion
Unit tests are added
Output: