Skip to content

fix(k8scontainer): use audit timeline creation time inventory instead of querying builder state - #1086

Open
kyasbal wants to merge 3 commits into
GoogleCloudPlatform:mainfrom
kyasbal:push-nplzwoputmxz
Open

kyasbal wants to merge 3 commits into
GoogleCloudPlatform:mainfrom
kyasbal:push-nplzwoputmxz

Conversation

@kyasbal

@kyasbal kyasbal commented Oct 1, 2026 •

Copy link
Copy Markdown
Member

Background & Problem

containerLogPodPhaseTimelineMapper synthesizes fallback Pod, Binding, and PodPhase revisions from container log labels when a Pod's creation revision is not already recorded by audit logs. Previously, this mapper had three issues:

  1. Unreliable Builder State Queries Across Flush Boundaries: The mapper checked whether audit logs had written revisions by calling builder.TimelineAccumulator.HasRevision(...). However, TimelineBuilder.HasRevision() only inspected in-memory slice length (len(b.revisions) > 0). Whenever TimelineAccumulator flushed pending items to disk (FlushPendingItems), b.revisions was cleared to nil, causing HasRevision() to return false even for timelines already populated by k8saudit. Furthermore, parser/mapper tasks should not read back mutated state from TimelineBuilder or TimelineAccumulator.
  2. Incorrect Timestamp on Subsequent Container Log Revisions: When container labels or scheduled node names changed on subsequent container logs (state != nil), containerLogPodPhaseTimelineMapper still hardcoded ChangedTime: time.Unix(0, 0) instead of using l.Timestamp. This caused subsequent revisions to be placed at 1970-01-01T00:00:00Z and appear before earlier audit log revisions.
  3. Creation-Time Semantics vs. Raw Path Existence: What determines whether a fallback time.Unix(0, 0) revision from container logs will corrupt an existing timeline is whether the target timeline path already has resolved creationTimes (from metadata.creationTimestamp or VerbCreate audit logs). Moreover, a single timeline path can observe multiple creationTimes when a resource with the same name is deleted and recreated during the inspection window.

Solution Approach

  1. Remove HasRevision and HasEvent from TimelineBuilder and TimelineAccumulator:
    • Removed HasRevision() and HasEvent() from TimelineBuilder and TimelineAccumulator, along with the test-only AddTestRevision() helper, enforcing a write-only accumulator contract for timeline mappers.
  2. Introduce TimelineCreationTimeInventoryTask with Dedicated Resource and PodPhase Discovery Tasks:
    • Added ResourceTimelineCreationTimeDiscoveryTask and PodPhaseTimelineCreationTimeDiscoveryTask in pkg/task/inspection/common/k8saudit to collect observed creation timestamps (map[*khifilev6.TimelinePath][]time.Time, deduplicated and sorted chronologically) for resource/subresource timelines and PodPhase timelines discovered from non-dry-run audit logs that have a resolved creation time (metadata.creationTimestamp or VerbCreate log timestamp).
    • Both discovery tasks provide TagTimelineCreationTimeDiscovery and are aggregated by TimelineCreationTimeInventoryTask.
    • Updated containerLogPodPhaseTimelineMapper to depend on TimelineCreationTimeInventoryTaskID instead of ResourceRevisionLogToTimelineMapperTaskID, PodPhaseLogToTimelineMapperTaskID, and TimelineAccumulator.HasRevision.
  3. Use l.Timestamp for Subsequent Container Log Revisions:
    • Updated containerLogPodPhaseTimelineMapper to use time.Unix(0, 0) only for the initial synthesized revision (state == nil) and l.Timestamp for subsequent revisions (state != nil).

Task Graph Changes

flowchart LR
    manifest_gen["k8saudit: ManifestGeneratorTask"]
    extractor["k8saudit: K8sAuditLogExtractor"]
    res_discovery["k8saudit: ResourceTimelineCreationTimeDiscoveryTask"]
    pod_phase_discovery["k8saudit: PodPhaseTimelineCreationTimeDiscoveryTask"]
    inventory["k8saudit: TimelineCreationTimeInventoryTask"]
    container_mapper["k8scontainer: PodPhaseTimelineMapperTask"]

    manifest_gen --> res_discovery
    extractor --> res_discovery
    manifest_gen --> pod_phase_discovery
    extractor --> pod_phase_discovery
    res_discovery -.->|"TagTimelineCreationTimeDiscovery"| inventory
    pod_phase_discovery -.->|"TagTimelineCreationTimeDiscovery"| inventory
    inventory --> container_mapper
Loading

Remaining Issues & Future Work

None.

@kyasbal kyasbal added type:bug Something isn't working as expected area:backend-parser Log parsers and log timeline mapper tasks area:khifile .khi file format, serialization, and schema labels Oct 1, 2026

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new task framework to discover and aggregate timeline paths written by Kubernetes audit logs, replacing the previous reliance on checking the state of the timeline accumulator directly. Specifically, it adds TimelinePathInventoryTask and TimelinePathDiscoveryTask under pkg/task/inspection/common/k8saudit, registers them, and refactors containerLogPodPhaseTimelineMapper to depend on the new inventory task. Unused methods such as HasRevision and HasEvent have been removed from TimelineAccumulator and TimelineBuilder. Additionally, tests have been updated to align with these changes, including mocking the new inventory task results and asserting correct timestamps. No review comments were provided, so there is no further feedback to address.

@kyasbal kyasbal changed the title fix(k8scontainer): use audit timeline path inventory instead of querying builder state fix(k8scontainer): use audit timeline creation time inventory instead of querying builder state Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area:backend-parser Log parsers and log timeline mapper tasks area:khifile .khi file format, serialization, and schema type:bug Something isn't working as expected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant