Skip to content

feat: add Event.list() for listing existing events#2686

Open
threcc wants to merge 1 commit intoRedHatQE:mainfrom
threcc:feat/event-list
Open

feat: add Event.list() for listing existing events#2686
threcc wants to merge 1 commit intoRedHatQE:mainfrom
threcc:feat/event-list

Conversation

@threcc
Copy link
Copy Markdown

@threcc threcc commented Apr 3, 2026

Short description:

Add Event.list() classmethod that performs a standard K8s API list call instead of using watch() like Event.get().
This returns existing events immediately without blocking.

More details:
  • _parse_timestamp() helper handles lastTimestampcreationTimestamp fallback with error handling for malformed timestamps
  • since_seconds parameter (default: 300 = 5 minutes) filters events by time window
  • Results sorted by most recent first
What this PR does / why we need it:
  • Event.get() uses watch() internally that is a streaming API that only yields events occurring after the watch starts, and completes when timeout expires.
    Past events are not returned.

  • Event.list() performs a standard K8s list API call that returns immediately with events from the specified time window (default: last 5 minutes).
    Suitable for diagnostic scenarios like collecting warning events after a resource timeout.

n/a

Special notes for reviewer:

n/a

Bug:

n/a

Summary by CodeRabbit

  • New Features
    • Added event listing capability with support for filtering by namespace, field selectors, and label selectors to refine results.
    • Events are automatically filtered to show only those within a configurable time window, defaulting to the last 5 minutes.
    • Results are sorted by timestamp in descending order, displaying the most recent events first for better visibility.

Signed-off-by: threcc <trecchiu@redhat.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai bot commented Apr 3, 2026

Walkthrough

Added timestamp parsing and filtering to Event class. Introduced _parse_timestamp() static method to extract and parse event timestamps with fallback to creation timestamp. Added list() class method performing Kubernetes list calls with client-side time-window filtering and descending timestamp sort.

Changes

Cohort / File(s) Summary
Event timestamp and filtering
ocp_resources/event.py
Added datetime-related imports; introduced _parse_timestamp() static method to extract and parse lastTimestamp (with fallback to metadata.creationTimestamp) with debug logging on parsing failure; added list() class method that performs Kubernetes list operations with optional namespace, field_selector, and label_selector parameters, filters results by configurable since_seconds time window, and sorts by timestamp descending.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The title accurately describes the main change: adding an Event.list() method for listing existing events with non-blocking immediate return.
Description check ✅ Passed The description follows the template with all required sections completed, clearly explaining the feature, its rationale, and implementation details.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@redhat-qe-bot
Copy link
Copy Markdown
Contributor

Report bugs in Issues

Welcome! 🎉

This pull request will be automatically processed with the following features:

🔄 Automatic Actions

  • Reviewer Assignment: Reviewers are automatically assigned based on the OWNERS file in the repository root
  • Size Labeling: PR size labels (XS, S, M, L, XL, XXL) are automatically applied based on changes
  • Issue Creation: Disabled for this repository
  • Branch Labeling: Branch-specific labels are applied to track the target branch
  • Auto-verification: Auto-verified users have their PRs automatically marked as verified
  • Labels: All label categories are enabled (default configuration)

📋 Available Commands

PR Status Management

  • /wip - Mark PR as work in progress (adds WIP: prefix to title)
  • /wip cancel - Remove work in progress status
  • /hold - Block PR merging (approvers only)
  • /hold cancel - Unblock PR merging
  • /verified - Mark PR as verified
  • /verified cancel - Remove verification status
  • /reprocess - Trigger complete PR workflow reprocessing (useful if webhook failed or configuration changed)
  • /regenerate-welcome - Regenerate this welcome message

Review & Approval

  • /lgtm - Approve changes (looks good to me)
  • /approve - Approve PR (approvers only)
  • /automerge - Enable automatic merging when all requirements are met (maintainers and approvers only)
  • /assign-reviewers - Assign reviewers based on OWNERS file
  • /assign-reviewer @username - Assign specific reviewer
  • /check-can-merge - Check if PR meets merge requirements

Testing & Validation

  • /retest tox - Run Python test suite with tox
  • /retest python-module-install - Test Python package installation
  • /retest conventional-title - Validate commit message format
  • /retest all - Run all available tests

Cherry-pick Operations

  • /cherry-pick <branch> - Schedule cherry-pick to target branch when PR is merged
    • Multiple branches: /cherry-pick branch1 branch2 branch3

Label Management

  • /<label-name> - Add a label to the PR
  • /<label-name> cancel - Remove a label from the PR

✅ Merge Requirements

This PR will be automatically approved when the following conditions are met:

  1. Approval: /approve from at least one approver
  2. Status Checks: All required status checks must pass
  3. No Blockers: No wip, hold, has-conflicts labels and PR must be mergeable (no conflicts)
  4. Verified: PR must be marked as verified

📊 Review Process

Approvers and Reviewers

Approvers:

  • myakove
  • rnetser

Reviewers:

  • myakove
  • rnetser
Available Labels
  • hold
  • verified
  • wip
  • lgtm
  • approve
  • automerge
AI Features
  • Conventional Title: Mode: fix (claude/claude-opus-4-6[1m])
  • Cherry-Pick Conflict Resolution: Enabled (claude/claude-opus-4-6[1m])

💡 Tips

  • WIP Status: Use /wip when your PR is not ready for review
  • Verification: The verified label is removed on new commits unless the push is detected as a clean rebase
  • Cherry-picking: Cherry-pick labels are processed when the PR is merged
  • Permission Levels: Some commands require approver permissions
  • Auto-verified Users: Certain users have automatic verification and merge privileges

For more information, please refer to the project documentation or contact the maintainers.

Copy link
Copy Markdown

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@ocp_resources/event.py`:
- Line 113: Add a guard to validate the since_seconds parameter (the argument
declared as "since_seconds: int = 300") to ensure it is non‑negative: if
since_seconds < 0, raise a clear ValueError (or similar) with a descriptive
message so the call fails fast; apply this same validation to the other
occurrence of since_seconds in the file (the second declaration referenced in
the review).
- Around line 100-103: The parsed timestamp can be offset-naive and later
compared to the timezone-aware cutoff in list(), causing a TypeError; after
calling datetime.fromisoformat(...) (and after replacing "Z" with "+00:00"),
ensure the resulting datetime is timezone-aware by setting tzinfo to UTC when
dt.tzinfo is None (use datetime.timezone.utc or equivalent) before returning it
from the parsing helper; this guarantees safe comparisons against the
timezone-aware cutoff used in list().
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 1d2563f8-02a3-4e54-a961-89d475c4509c

📥 Commits

Reviewing files that changed from the base of the PR and between 512728d and 2eaad7c.

📒 Files selected for processing (1)
  • ocp_resources/event.py

Comment on lines +100 to +103
try:
return datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
except (ValueError, TypeError):
LOGGER.debug(f"Failed to parse event timestamp: {timestamp}")
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Verifies Python datetime behavior that can trigger the runtime error path.
python - <<'PY'
from datetime import datetime, timezone
samples = ["2026-04-03T12:00:00", "2026-04-03T12:00:00Z"]
cutoff = datetime.now(timezone.utc)
for ts in samples:
    parsed = datetime.fromisoformat(ts.replace("Z", "+00:00"))
    print(f"{ts} -> tzinfo={parsed.tzinfo}")
    try:
        print("comparison_ok:", parsed >= cutoff)
    except Exception as exc:
        print("comparison_error:", type(exc).__name__, str(exc))
PY

Repository: RedHatQE/openshift-python-wrapper

Length of output: 249


🏁 Script executed:

# Locate and examine the event.py file
git ls-files | grep -E "event\.py$"

Repository: RedHatQE/openshift-python-wrapper

Length of output: 99


🏁 Script executed:

# Read the file to understand the full context of _parse_timestamp and list methods
cat -n ocp_resources/event.py | head -220

Repository: RedHatQE/openshift-python-wrapper

Length of output: 10161


🏁 Script executed:

# Check for generated-code markers per coding guidelines
grep -n "Generated using\|End of generated code" ocp_resources/event.py

Repository: RedHatQE/openshift-python-wrapper

Length of output: 59


Normalize parsed timestamps to timezone-aware UTC to prevent comparison error at runtime.

When a timestamp lacks a timezone indicator (e.g., "2026-04-03T12:00:00"), datetime.fromisoformat() returns a naive datetime. Comparing this naive datetime to the timezone-aware cutoff at line 163 raises TypeError: can't compare offset-naive and offset-aware datetimes, silently bypassing the try-except block at line 102 and crashing the list() method.

Proposed fix
     try:
-            return datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
+            parsed = datetime.fromisoformat(timestamp.replace("Z", "+00:00"))
+            if parsed.tzinfo is None:
+                parsed = parsed.replace(tzinfo=timezone.utc)
+            return parsed.astimezone(timezone.utc)
     except (ValueError, TypeError):
             LOGGER.debug(f"Failed to parse event timestamp: {timestamp}")
             return None

Also applies to: line 163

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ocp_resources/event.py` around lines 100 - 103, The parsed timestamp can be
offset-naive and later compared to the timezone-aware cutoff in list(), causing
a TypeError; after calling datetime.fromisoformat(...) (and after replacing "Z"
with "+00:00"), ensure the resulting datetime is timezone-aware by setting
tzinfo to UTC when dt.tzinfo is None (use datetime.timezone.utc or equivalent)
before returning it from the parsing helper; this guarantees safe comparisons
against the timezone-aware cutoff used in list().

namespace: str | None = None,
field_selector: str | None = None,
label_selector: str | None = None,
since_seconds: int = 300,
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Validate since_seconds lower bound.

Negative values currently produce a future cutoff and unintuitive filtering. Add a guard to fail fast.

💡 Proposed fix
     def list(
         cls,
         client: DynamicClient,
         namespace: str | None = None,
         field_selector: str | None = None,
         label_selector: str | None = None,
         since_seconds: int = 300,
     ) -> list[Any]:
+        if since_seconds < 0:
+            raise ValueError("since_seconds must be >= 0")

Also applies to: 159-159

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@ocp_resources/event.py` at line 113, Add a guard to validate the
since_seconds parameter (the argument declared as "since_seconds: int = 300") to
ensure it is non‑negative: if since_seconds < 0, raise a clear ValueError (or
similar) with a descriptive message so the call fails fast; apply this same
validation to the other occurrence of since_seconds in the file (the second
declaration referenced in the review).

@myakove
Copy link
Copy Markdown
Collaborator

myakove commented Apr 5, 2026

@threcc Please address coderabiitai comments.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants