Skip to content

NETOBSERV-2609 show tls usage in topology view#1451

Open
jpinsonneau wants to merge 4 commits into
netobserv:mainfrom
jpinsonneau:2609
Open

NETOBSERV-2609 show tls usage in topology view#1451
jpinsonneau wants to merge 4 commits into
netobserv:mainfrom
jpinsonneau:2609

Conversation

@jpinsonneau
Copy link
Copy Markdown
Member

@jpinsonneau jpinsonneau commented Apr 22, 2026

Description

Display TLS versions and message types in topology side panel
Also display a lock with a green / yellow / red color showing if the TLS version involved is valid
Add an option to show an open lock when no TLS is involved

image image image image

Dependencies

Based on #1478 / #1530

Checklist

  • Does the changes in PR need specific configuration or environment set up for testing?
    • if so please describe it in PR description.
  • I have added thorough unit tests for the change.
  • QE requirements (check 1 from the list):
    • Standard QE validation, with pre-merge tests unless stated otherwise.
    • Regression tests only (e.g. refactoring with no user-facing change).
    • No QE (e.g. trivial change with high reviewer's confidence, or per agreement with the QE team).

Summary by CodeRabbit

  • New Features

    • TLS tracking everywhere: per-edge TLS lock/cleartext icons, severity coloring (including PQC), TLS versions/groups display, and quick-filter buttons
    • Topology: TLS-aware metric enrichment, optional cleartext-edge hint toggle, and topology display options for cleartext
    • UI: new TLS lock icons and localized copy for TLS states and cleartext guidance
  • Tests

    • Added unit/integration tests for TLS parsing, merging, severity classification, metrics merging, and UI rendering

Review Change Stack

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Apr 22, 2026

Skipping CI for Draft Pull Request.
If you want CI signal for your change, please convert it to an actual PR.
You can still manually trigger a test run with /test all

@openshift-ci
Copy link
Copy Markdown

openshift-ci Bot commented Apr 22, 2026

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by:
Once this PR has been reviewed and has the lgtm label, please assign mffiedler for approval. For more information see the Code Review Process.

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 22, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9bd9474a-b1d3-4420-aa5e-e8cf518bf665

📥 Commits

Reviewing files that changed from the base of the PR and between 60dfeb9 and 3ab6360.

📒 Files selected for processing (9)
  • web/locales/en/plugin__netobserv-plugin.json
  • web/src/api/ipfix.ts
  • web/src/api/loki.ts
  • web/src/components/drawer/element/__tests__/element-panel.spec.tsx
  • web/src/components/drawer/element/element-panel-content.tsx
  • web/src/components/tabs/netflow-topology/2d/topology-content.tsx
  • web/src/model/topology.ts
  • web/src/utils/__tests__/metrics.spec.ts
  • web/src/utils/metrics.ts
💤 Files with no reviewable changes (2)
  • web/src/components/tabs/netflow-topology/2d/topology-content.tsx
  • web/locales/en/plugin__netobserv-plugin.json

📝 Walkthrough

Walkthrough

Adds TLS-version and group visibility end-to-end: backend aggregate keys and Loki test, metric parsing and merging with optional tls metadata, topology model and edge/tag state, SVG lock icons and styles, element-drawer TLS details with quick-filters, display options for cleartext hints, filter encoder updates, tests, and English locale strings.

Changes

TLS Visibility Feature

Layer / File(s) Summary
Backend aggregate keys & API types
pkg/config/config.go, pkg/loki/topology_query_test.go, web/src/api/ipfix.ts, web/src/api/loki.ts, web/src/model/flow-query.ts, web/src/model/netflow-context.ts
Adds __TLSVersion aggregate key per scope and Loki test; extends Flow and metric types to carry TLS metadata; exports TLS aggregate suffix and helper; retypes FetchCallbacks.setMetrics to React setter.
TLS severity & classification
web/src/utils/tls-lock-severity.ts, web/src/utils/__tests__/tls-lock-severity.spec.ts
Introduce pqc severity and PQC group set; normalize version strings, map versions to severities, detect PQC when TLS 1.3 + PQC group, aggregate worst severity including pqc. Tests cover classifiers and aggregation.
Metrics TLS parsing & merge helpers
web/src/utils/metrics.ts, web/src/utils/__tests__/metrics.spec.ts
Normalize TLSTypes/TLSVersion/TLSGroup encodings into arrays, attach optional tls fields, implement mergeTlsIntoTopologyMetrics and mergeTlsVersionUsageMetrics with datapoint alignment and stats recompute; add step-from-values helper and tests.
Topology model & quick-filters
web/src/model/topology.ts
Add EdgeTlsPanelData, isTLSTracking and showCleartextEdgeLock options, helpers to build/merge TLS panel data, and toggleQuickFilterValue for per-label quick filters.
Edge generation & merging
web/src/model/topology.ts
generateEdge/addEdge accept per-row TLS data and cleartext hint, merge TLS state across rows, compute/strip TLS decorations based on tracking/options/traffic presence.
NetflowTopology fetch & state updates
web/src/components/tabs/netflow-topology/netflow-topology.tsx
Adds isTLSTracking prop and effective flag, refactors fetch to async commitMainMetrics, optionally runs TLS follow-up query (aggregateByWithTlsVersion) and merges TLS into topology metrics, uses functional setMetrics updates.
TopologyConnectorTag & TLS icons
web/src/components/tabs/netflow-topology/2d/components/topology-connector-tag.tsx, web/src/components/icons/tls-lock-icons.tsx, web/src/components/icons/index.ts, web/src/components/tabs/netflow-topology/2d/topology-content.css
New SVG tag component positions text and optional lock icon (open/closed) with tooltip; TLS lock icon components map severity/version to fill colors and render Lock/LockOpen icons; CSS styles for lock states added; icons re-exported.
Edge component wiring & styles
web/src/components/tabs/netflow-topology/2d/components/edge.tsx, web/src/components/tabs/netflow-topology/2d/styles/styleEdge.tsx
Edge props add tagTlsSecure, tagTlsLockSeverity, tagTlsCleartext; tag visibility updated to include TLS indicators; uses TopologyConnectorTag; detail-level filtering strips TLS tag when not high detail.
Element panel TLS details and gating
web/src/components/drawer/element/element-panel-content.tsx, web/src/components/drawer/element/element-panel.tsx, web/src/components/drawer/element/element-panel.css, web/src/components/drawer/element/__tests__/element-panel.spec.tsx
Add edgeTlsInfo rendering encrypted-traffic message, TLS version/group breakdowns with per-label quick-filter buttons and fallback when no breakdown; ElementPanel uses capabilities to gate tabs and consolidates tab reset logic. CSS for TLS drawer tab added and tests verify TLS UI scenarios.
Topology display options & UI wiring
web/src/components/dropdowns/topology-display-options.tsx, web/src/components/dropdowns/topology-display-dropdown.tsx, web/src/components/toolbar/view-options-toolbar.tsx, web/src/components/drawer/netflow-traffic-drawer.tsx
Expose isTLSTracking into display options; conditionally render "Cleartext traffic" checkbox when tracking enabled; thread capability through dropdown, toolbar, and drawer.
Filter-definitions endpoint encoding
web/src/utils/filter-definitions.ts, web/src/utils/__tests__/filter-definitions.spec.ts
Encoder signature aligned; new helpers parse calculated src/dst pairs, fallback mappings, extract encoded label keys, and provide an either-side endpoint encoder used when field absent. Tests validate namespace encoder behavior.
Localization and tests
web/locales/en/plugin__netobserv-plugin.json, web/src/model/__tests__/flow-query.spec.ts, assorted tests
English locale strings for TLS UI and classification states added. Tests added/updated for flow-query helpers, metrics TLS parsing/merging, and TLS severity classification. TestCaps updated to include isTLSTracking.

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title directly describes the main change: displaying TLS usage (versions, groups, and security status) in the topology view.
Description check ✅ Passed The description includes a clear summary of changes, visual examples, dependency references, and QE requirements checklist. However, unit test coverage is not explicitly confirmed and environment setup details are minimal.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

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

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

Warning

Review ran into problems

🔥 Problems

Linked repositories: Your configuration references 2 linked repositories, but your current plan allows 1. Analyzed netobserv/netobserv-operator, skipped netobserv/flowlogs-pipeline.


Linked repositories: Couldn't analyze netobserv/netobserv-operator - clone failed: Clone operation failed: Cloning into '/home/jailuser/git'...
warning: templates not found in /usr/share/git-core/templates
fatal: unable to access 'https://github.com/netobserv/netobserv-operator.git/': Failed to connect to github.com port 443 after 135045 ms: Couldn't connect to server


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.

@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 22, 2026
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:fa4506a

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=fa4506a make set-plugin-image

@codecov
Copy link
Copy Markdown

codecov Bot commented Apr 22, 2026

Codecov Report

❌ Patch coverage is 52.91139% with 186 lines in your changes missing coverage. Please review.
✅ Project coverage is 52.45%. Comparing base (b9947b2) to head (3ab6360).
⚠️ Report is 8 commits behind head on main.

Files with missing lines Patch % Lines
...-topology/2d/components/topology-connector-tag.tsx 25.00% 45 Missing ⚠️
...ponents/tabs/netflow-topology/netflow-topology.tsx 6.52% 43 Missing ⚠️
web/src/model/topology.ts 10.81% 33 Missing ⚠️
web/src/utils/metrics.ts 67.00% 18 Missing and 15 partials ⚠️
...omponents/drawer/element/element-panel-content.tsx 78.78% 6 Missing and 1 partial ⚠️
web/src/utils/filter-definitions.ts 78.57% 4 Missing and 2 partials ⚠️
web/src/utils/tls-lock-severity.ts 85.00% 2 Missing and 4 partials ⚠️
web/src/components/icons/tls-lock-icons.tsx 76.19% 3 Missing and 2 partials ⚠️
...eb/src/components/drawer/element/element-panel.tsx 50.00% 0 Missing and 3 partials ⚠️
.../components/dropdowns/topology-display-options.tsx 0.00% 2 Missing ⚠️
... and 3 more
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1451      +/-   ##
==========================================
+ Coverage   52.23%   52.45%   +0.22%     
==========================================
  Files         233      236       +3     
  Lines       12552    12893     +341     
  Branches     1575     1659      +84     
==========================================
+ Hits         6556     6763     +207     
- Misses       5378     5489     +111     
- Partials      618      641      +23     
Flag Coverage Δ
uitests 56.35% <51.93%> (+0.08%) ⬆️
unittests 41.16% <100.00%> (+0.24%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
pkg/config/config.go 50.00% <100.00%> (+2.63%) ⬆️
web/src/api/ipfix.ts 100.00% <ø> (ø)
web/src/api/loki.ts 84.61% <ø> (ø)
...b/src/components/drawer/netflow-traffic-drawer.tsx 47.70% <ø> (ø)
...components/dropdowns/topology-display-dropdown.tsx 45.45% <ø> (ø)
web/src/components/icons/index.ts 100.00% <100.00%> (ø)
...eb/src/components/toolbar/view-options-toolbar.tsx 21.53% <ø> (ø)
web/src/model/filters.ts 75.34% <ø> (ø)
web/src/model/flow-query.ts 94.73% <100.00%> (+3.07%) ⬆️
web/src/model/netflow-context.ts 70.00% <ø> (ø)
... and 13 more

... and 2 files with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@jpinsonneau
Copy link
Copy Markdown
Member Author

@jotak can you please share how to generate deprecated TLS traffic ?

I tried some curl using TLS1.2 but the eBPF agents are not capturing it 😞

@github-actions github-actions Bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label Apr 22, 2026
@jpinsonneau jpinsonneau requested a review from jotak April 22, 2026 14:19
@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 11, 2026
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:7bdb498

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=7bdb498 make set-plugin-image

Comment thread web/src/api/ipfix.ts Outdated
Comment on lines +62 to +70
if (!metricType) {
return false;
}
return (
metricType === 'Bytes' ||
metricType === 'Packets' ||
metricType === 'PktDropBytes' ||
metricType === 'PktDropPackets'
);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

So, I think the way I'm changing the metrics here won't work that way. It would be a new query to run, with TlsFlows as the metric type

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Sure, let me adapt to the new approach

@jotak
Copy link
Copy Markdown
Member

jotak commented May 11, 2026

In terms of graphical design it looks nice to me!
But the implementation will conflict with other changes that I'm doing, the tldr; is that I changed the approach, instead of adding TLS info into existing metrics, it's now a separate metric to fetch, much like what we're doing with DNS

@github-actions github-actions Bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 11, 2026
@jpinsonneau
Copy link
Copy Markdown
Member Author

Refactored based on #1478

Will rebased when merged and cherry picked on PF6 branch

@jpinsonneau
Copy link
Copy Markdown
Member Author

Rebased without changes

@jpinsonneau jpinsonneau added ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. and removed do-not-merge/hold labels May 18, 2026
@jpinsonneau jpinsonneau marked this pull request as ready for review May 18, 2026 15:57
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:6c5cd8d

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=6c5cd8d make set-plugin-image

Copy link
Copy Markdown
Contributor

@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: 9

🧹 Nitpick comments (3)
web/src/utils/metrics.ts (1)

61-63: ⚡ Quick win

Index TLS rows by edge key before merge.

This nested filter does a full tlsRows scan for every volume row. Build a keyed map once (src.id@dst.id) and merge from O(1) lookups.

Proposed refactor
 export const mergeTlsIntoTopologyMetrics = (
   volume: TopologyMetrics[],
   tlsRows: TopologyMetrics[]
 ): TopologyMetrics[] => {
   const mergeTls = (a: GenericMetricTls | undefined, b: GenericMetricTls | undefined): GenericMetricTls | undefined => {
@@
     return {
       ...(types.length ? { types } : {}),
       ...(versions.length ? { versions } : {})
     };
   };

+  const tlsByEdge = new Map<string, GenericMetricTls | undefined>();
+  for (const t of tlsRows) {
+    const k = `${t.source.id}@${t.destination.id}`;
+    tlsByEdge.set(k, mergeTls(tlsByEdge.get(k), t.tls));
+  }
+
   return volume.map(m => {
-    const matches = tlsRows.filter(t => t.source.id === m.source.id && t.destination.id === m.destination.id);
-    if (!matches.length) {
-      return m;
-    }
-    let mergedTls = m.tls;
-    for (const t of matches) {
-      mergedTls = mergeTls(mergedTls, t.tls);
-    }
+    const mergedTls = mergeTls(m.tls, tlsByEdge.get(`${m.source.id}@${m.destination.id}`));
     if (!mergedTls) {
       return m;
     }
     return { ...m, tls: mergedTls };
   });
 };

As per coding guidelines, "Optimize frontend performance by avoiding unnecessary re-renders and optimizing query patterns".

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/utils/metrics.ts` around lines 61 - 63, The current volume.map
callback repeatedly scans tlsRows with tlsRows.filter inside volume.map, causing
O(N*M) work; precompute a lookup map keyed by `${source.id}@${destination.id}`
(build once from tlsRows) and then in the volume.map use that map.get(key) to
retrieve matching TLS row(s) in O(1). Change the logic around the existing
volume.map and the local variable matches (used in the map callback) to look up
via the new map instead of calling tlsRows.filter each iteration; ensure keys
use the same id fields (source.id and destination.id) as in the original
comparison.
web/src/utils/__tests__/metrics.spec.ts (1)

511-563: ⚡ Quick win

Add regression test for empty-first-row merge bucket.

Please add a case where the first TLSVersion row has values: [] and a later row has datapoints; merged output should keep later datapoints.

Suggested test
 describe('mergeTlsVersionUsageMetrics', () => {
+  it('keeps datapoints when first bucket row is empty', () => {
+    const empty: [number, number][] = [];
+    const values: [number, number][] = [[100, 7]];
+    const merged = mergeTlsVersionUsageMetrics([
+      { name: 'TLS 1.2', values: empty, stats: computeStats(empty), aggregateBy: 'TLSVersion' },
+      { name: 'TLS 1.2', values, stats: computeStats(values), aggregateBy: 'TLSVersion' }
+    ]);
+    expect(merged).toHaveLength(1);
+    expect(merged[0].metric.values).toEqual([[100, 7]]);
+  });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/utils/__tests__/metrics.spec.ts` around lines 511 - 563, Add a
regression test to metrics.spec.ts for mergeTlsVersionUsageMetrics that covers
the case where the first TLSVersion row has values: [] and a later row for the
same name contains datapoints; create two GenericMetric-like inputs (first with
empty values and stats for empty, second with non-empty values and computeStats
for them), call mergeTlsVersionUsageMetrics([first, second]) and assert the
merged output contains a single bucket with the later datapoints preserved
(e.g., merged[0].metric.values equals the non-empty datapoints) and appropriate
name/filterValue; place this new it block inside the existing
describe('mergeTlsVersionUsageMetrics', ...) alongside the other tests.
web/src/utils/__tests__/filter-definitions.spec.ts (1)

7-22: ⚡ Quick win

Add a negated endpoint regression case.

These assertions only cover =. The new encoder also changes != / !~, and that's where the src/dst join semantics can drift. A namespace != ns1 expectation here would lock the behavior down.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/utils/__tests__/filter-definitions.spec.ts` around lines 7 - 22, Add
a negated-case unit test mirroring the existing positive case to lock the
src/dst join semantics for negation: use findFilter (or
getFilterDefinitions+findFilter when testing columnsWithoutFilterLink) to get
the 'namespace' FilterDefinitionSample, call def.encoder([{ v: 'ns1' }],
FilterCompare.notEqual, false) and assert the encoded string equals
'SrcK8S_Namespace!=ns1|DstK8S_Namespace!=ns1' so the encoder's handling of !=/!~
for the namespace filter is validated.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/components/drawer/element/element-panel-content.tsx`:
- Around line 165-171: The icon-only Button (id={buttonId}, icon using
TimesIcon/FilterIcon and onclick toggleQuickFilterValue) lacks an accessible
label and E2E hook; add a localized aria-label using t(...) that reflects the
current state (e.g., t('filters.clear', { value }) when isFiltered true and
t('filters.apply', { value }) when false) and add a stable data-test attribute
(e.g., data-test={`quick-filter-${def}-${value}`}) to the Button component so
screen readers and tests can target it reliably.
- Around line 223-231: The fallback message branch incorrectly checks
tlsVersionLabels; update the conditional that decides whether to render the "No
TLS message type breakdown..." block to test tlsTypeLabels (i.e., render when
tagTlsSecure is true AND tlsTypeLabels is absent/empty) so secure edges with
versions but missing message-type labels show the explanatory Content; locate
the conditional around tagTlsSecure in element-panel-content (the ternary that
currently inspects tlsVersionLabels) and replace that check to use tlsTypeLabels
instead.

In `@web/src/components/drawer/element/element-panel.tsx`:
- Around line 107-119: The activeTab reset logic fails to account for noMetrics
hiding the Metrics tab: update the condition that currently checks (activeTab
=== 'metrics' && _.isEmpty(metrics)) to also consider noMetrics (e.g., treat the
Metrics tab as unavailable when noMetrics is true), so if noMetrics becomes true
while metrics still has data we call setActiveTab('details'); modify the
useEffect conditions (referencing activeTab, metrics, noMetrics, showDroppedTab,
showHealthTab, setActiveTab) accordingly and apply the same fix to the other
similar reset check that references these symbols.

In `@web/src/components/dropdowns/topology-display-options.tsx`:
- Around line 189-200: The new Checkbox control (id
"edges-cleartext-lock-switch") lacks a stable E2E selector; add a data-test
attribute (e.g. data-test="edges-cleartext-lock-switch" or data-test-id) to the
<Checkbox> component so tests can reliably find the TLS toggle, ensuring you
update the JSX props on the Checkbox where id="edges-cleartext-lock-switch" is
defined (preserve existing props like label, isDisabled, isChecked, onChange).

In `@web/src/components/tabs/netflow-topology/2d/topology-content.tsx`:
- Around line 79-80: The component is currently prop-drilling the isTLSTracking
flag; stop passing isTLSTracking through props and instead read it from the
shared NetflowContext at the consumer level. In topology-content.tsx (component
TopologyContent or its exported function), remove isTLSTracking from the
props/interface, import and use the NetflowContext or the provided hook from
web/src/model/netflow-context.ts (e.g., useNetflowContext()) to obtain
isTLSTracking, and update all internal uses to reference the context value; also
update any call sites that passed isTLSTracking (see the blocks around lines
299–305/304) to stop supplying that prop. Ensure type signatures and
tests/consumers no longer expect the prop.

In `@web/src/components/tabs/netflow-topology/netflow-topology.tsx`:
- Line 127: Create a single effective TLS flag (e.g. effectiveIsTLSTracking)
computed from caps.isTLSTracking and props.isTLSTracking, and use that value
everywhere instead of mixing the two flags: replace the fetch condition that
sets fetchTlsGeneric (currently using caps.isTLSTracking &&
showTLSHints(metricType)) to use effectiveIsTLSTracking &&
showTLSHints(metricType), pass effectiveIsTLSTracking into TopologyContent
rendering props, and update any useEffect/useCallback dependency arrays that
currently reference caps.isTLSTracking or props.isTLSTracking to depend on
effectiveIsTLSTracking instead so fetches, rendering, and callbacks remain
consistent.
- Around line 166-205: commitMainMetrics currently calls
setMetrics(currentMetrics) using a stale snapshot captured earlier, which can
clobber concurrent updates (e.g., droppedRate) — change each setMetrics(...)
inside commitMainMetrics to the functional form setMetrics(prev => ({ ...prev,
... })) so you merge updates against the latest state; for each branch
(Bytes/Packets, PktDropBytes/PktDropPackets, DnsLatencyMs, TimeFlowRttNs)
compute the new partial payload (rate/droppedRate/dnsLatency/rtt using
getRateMetricKey/getFunctionMetricKey and Result.success/Result.empty as before)
and then call setMetrics(prev => ({ ...prev, ...partialPayload })) to avoid lost
updates from concurrent requests.

In `@web/src/utils/filter-definitions.ts`:
- Around line 95-102: The endpointEitherSideEncoder currently always joins left
and right clauses with '|' which fails for negated compares; update
endpointEitherSideEncoder to pick the joiner based on the compare: call
simpleFiltersEncoder(srcField) and simpleFiltersEncoder(dstField) as before, but
if the incoming compare is a negated compare (e.g. FilterCompare '!=' /
isNegated), join the left and right strings with '&' so both sides are excluded,
otherwise use '|' for the non-negated case; reference endpointEitherSideEncoder,
srcField, dstField, simpleFiltersEncoder, and compare when making this change.

In `@web/src/utils/metrics.ts`:
- Around line 570-574: The merge currently seeds from group[0].values which
drops all rows when that first row is empty; update the logic in this merge
block to locate the first row in group whose .values is non-empty (e.g., find
index i where group[i].values.length>0), use
stepFromGenericValues(group[i].values) and set values = group[i].values as the
initial seed, then loop over the rest of group (skipping index i) and call
combineValues(values, group[j].values, step, (a,b)=>a+b) for each; if no
non-empty row exists, return/leave values as an empty array to avoid losing
data.

---

Nitpick comments:
In `@web/src/utils/__tests__/filter-definitions.spec.ts`:
- Around line 7-22: Add a negated-case unit test mirroring the existing positive
case to lock the src/dst join semantics for negation: use findFilter (or
getFilterDefinitions+findFilter when testing columnsWithoutFilterLink) to get
the 'namespace' FilterDefinitionSample, call def.encoder([{ v: 'ns1' }],
FilterCompare.notEqual, false) and assert the encoded string equals
'SrcK8S_Namespace!=ns1|DstK8S_Namespace!=ns1' so the encoder's handling of !=/!~
for the namespace filter is validated.

In `@web/src/utils/__tests__/metrics.spec.ts`:
- Around line 511-563: Add a regression test to metrics.spec.ts for
mergeTlsVersionUsageMetrics that covers the case where the first TLSVersion row
has values: [] and a later row for the same name contains datapoints; create two
GenericMetric-like inputs (first with empty values and stats for empty, second
with non-empty values and computeStats for them), call
mergeTlsVersionUsageMetrics([first, second]) and assert the merged output
contains a single bucket with the later datapoints preserved (e.g.,
merged[0].metric.values equals the non-empty datapoints) and appropriate
name/filterValue; place this new it block inside the existing
describe('mergeTlsVersionUsageMetrics', ...) alongside the other tests.

In `@web/src/utils/metrics.ts`:
- Around line 61-63: The current volume.map callback repeatedly scans tlsRows
with tlsRows.filter inside volume.map, causing O(N*M) work; precompute a lookup
map keyed by `${source.id}@${destination.id}` (build once from tlsRows) and then
in the volume.map use that map.get(key) to retrieve matching TLS row(s) in O(1).
Change the logic around the existing volume.map and the local variable matches
(used in the map callback) to look up via the new map instead of calling
tlsRows.filter each iteration; ensure keys use the same id fields (source.id and
destination.id) as in the original comparison.
🪄 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: 1bf00d96-3efb-4b92-a67d-db77c669e15e

📥 Commits

Reviewing files that changed from the base of the PR and between b9947b2 and 82096dc.

📒 Files selected for processing (35)
  • pkg/config/config.go
  • pkg/loki/flow_query.go
  • pkg/loki/topology_query.go
  • pkg/loki/topology_query_test.go
  • web/locales/en/plugin__netobserv-plugin.json
  • web/src/api/ipfix.ts
  • web/src/api/loki.ts
  • web/src/components/drawer/element/__tests__/element-panel.spec.tsx
  • web/src/components/drawer/element/element-panel-content.tsx
  • web/src/components/drawer/element/element-panel.css
  • web/src/components/drawer/element/element-panel.tsx
  • web/src/components/drawer/netflow-traffic-drawer.tsx
  • web/src/components/dropdowns/topology-display-dropdown.tsx
  • web/src/components/dropdowns/topology-display-options.tsx
  • web/src/components/icons/index.ts
  • web/src/components/icons/tls-lock-icons.tsx
  • web/src/components/tabs/netflow-topology/2d/components/edge.tsx
  • web/src/components/tabs/netflow-topology/2d/components/topology-connector-tag.tsx
  • web/src/components/tabs/netflow-topology/2d/styles/styleEdge.tsx
  • web/src/components/tabs/netflow-topology/2d/topology-content.css
  • web/src/components/tabs/netflow-topology/2d/topology-content.tsx
  • web/src/components/tabs/netflow-topology/netflow-topology.tsx
  • web/src/components/toolbar/filters/__tests__/filters-toolbar.spec.tsx
  • web/src/components/toolbar/view-options-toolbar.tsx
  • web/src/model/__tests__/flow-query.spec.ts
  • web/src/model/filters.ts
  • web/src/model/flow-query.ts
  • web/src/model/netflow-context.ts
  • web/src/model/topology.ts
  • web/src/utils/__tests__/filter-definitions.spec.ts
  • web/src/utils/__tests__/metrics.spec.ts
  • web/src/utils/__tests__/tls-lock-severity.spec.ts
  • web/src/utils/filter-definitions.ts
  • web/src/utils/metrics.ts
  • web/src/utils/tls-lock-severity.ts

Comment thread web/src/components/drawer/element/element-panel-content.tsx
Comment thread web/src/components/drawer/element/element-panel-content.tsx Outdated
Comment thread web/src/components/drawer/element/element-panel.tsx Outdated
Comment thread web/src/components/dropdowns/topology-display-options.tsx
Comment thread web/src/components/tabs/netflow-topology/2d/topology-content.tsx Outdated
const fq = caps.flowQuery;
const features = config.features;
const { getMetrics } = caps.fetchFunctions;
const fetchTlsGeneric = caps.isTLSTracking && showTLSHints(metricType);
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot May 18, 2026

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Find the file and check its size
wc -l web/src/components/tabs/netflow-topology/netflow-topology.tsx

Repository: netobserv/netobserv-web-console

Length of output: 141


🏁 Script executed:

#!/bin/bash
# Read the file to understand the TLS tracking usage
cat -n web/src/components/tabs/netflow-topology/netflow-topology.tsx | head -400

Repository: netobserv/netobserv-web-console

Length of output: 17611


Unify TLS-tracking flag between fetch and render.

The TLS query at line 127 only checks caps.isTLSTracking, ignoring the props.isTLSTracking override that affects TopologyContent rendering. This allows TLS UI to be hidden while TLS queries still run, or vice versa. Create one effectiveIsTLSTracking value and use it consistently in the fetch decision, render prop, and callback dependencies.

Suggested fix
+  const effectiveIsTLSTracking = props.isTLSTracking ?? caps.isTLSTracking;
...
-      const fetchTlsGeneric = caps.isTLSTracking && showTLSHints(metricType);
+      const fetchTlsGeneric = effectiveIsTLSTracking && showTLSHints(metricType);
...
-      caps.isTLSTracking,
+      effectiveIsTLSTracking,
...
-            isTLSTracking={props.isTLSTracking ?? caps.isTLSTracking}
+            isTLSTracking={effectiveIsTLSTracking}
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@web/src/components/tabs/netflow-topology/netflow-topology.tsx` at line 127,
Create a single effective TLS flag (e.g. effectiveIsTLSTracking) computed from
caps.isTLSTracking and props.isTLSTracking, and use that value everywhere
instead of mixing the two flags: replace the fetch condition that sets
fetchTlsGeneric (currently using caps.isTLSTracking && showTLSHints(metricType))
to use effectiveIsTLSTracking && showTLSHints(metricType), pass
effectiveIsTLSTracking into TopologyContent rendering props, and update any
useEffect/useCallback dependency arrays that currently reference
caps.isTLSTracking or props.isTLSTracking to depend on effectiveIsTLSTracking
instead so fetches, rendering, and callbacks remain consistent.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

sounds legit?

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.

@jotak Yes, it's valid. The fetch path uses caps.isTLSTracking directly while the render prop uses props.isTLSTracking ?? caps.isTLSTracking. If a parent ever passes isTLSTracking={false} explicitly (with caps.isTLSTracking still true), TLS queries would still fire even though the UI shows nothing — wasted network call and potential stale data.

The fix is one line at the top of the component body:

const effectiveIsTLSTracking = props.isTLSTracking ?? caps.isTLSTracking;

Then replace the three occurrences:

  • const fetchTlsGeneric = effectiveIsTLSTracking && showTLSHints(metricType);
  • isTLSTracking={effectiveIsTLSTracking} on TopologyContent
  • caps.isTLSTrackingeffectiveIsTLSTracking in the useCallback dependency array

Comment thread web/src/components/tabs/netflow-topology/netflow-topology.tsx
Comment thread web/src/utils/filter-definitions.ts
Comment thread web/src/utils/metrics.ts Outdated
@jpinsonneau jpinsonneau added the needs-review Tells that the PR needs a review label May 18, 2026
Comment thread pkg/loki/flow_query.go Outdated
Comment on lines +232 to +235
// appendTLSTypesArrayLabelFromLine adds a TLSTypes label from the raw log line.
// Loki's |json stage does not extract JSON array fields as labels, so sum by(TLSTypes,...) would
// otherwise drop the dimension even though flows include "TLSTypes":[...] in JSON.
func (q *FlowQueryBuilder) appendTLSTypesArrayLabelFromLine(sb *strings.Builder) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not sure to understand why not just using the appendTLSFilter defined above. Did I miss an edge case there?

Copy link
Copy Markdown
Member

@jotak jotak May 19, 2026

Choose a reason for hiding this comment

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

Ah, I guess I get it: it's because you're doing an aggregation per TLS type, right?
I think we can simplify and forget about TLS types here; not only because imho it's not a super important thing to show in aggregated data, but also because I omitted it intentionally in prom metrics (for cardinality)
I think if we omit TLS types in aggregations, that simplifies the whole things quite a bit?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Actually, TLSGroup is much more meaningful to have in aggregateed data. PQC compliance is based on TLSGroup.

Comment thread web/src/utils/filter-definitions.ts Outdated
};

/** When column config has no `filter` key (tests) or no `field`, map endpoint filter id → [src,dst] ipfix fields. */
const ENDPOINT_DUAL_FIELD_FALLBACK: Partial<Record<FilterId, [Field, Field]>> = {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

per conventions, rename to endpointDualFieldFallback

Comment thread web/src/utils/filter-definitions.ts Outdated
};
};

/** `[SrcFoo,DstFoo]` on columns that aggregate both endpoints (no single `field`). */
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

(I'm trying to understand what triggered the need for these changes). Is there some columns / filters that lacked some definition in the config file? If I understand correctly, it's some columns with no assigned field that didn't work as expected?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Yes I had issues with Namespace filter and took the opportunity to fix it here based on calculated field.

Comment thread web/src/model/flow-query.ts Outdated
export type AggregateBy = FlowScope | Field;

/** Suffix for aggregateBy keys that mirror a topology scope plus TLSVersion (see backend GetAggregateKeyLabels). */
export const TOPOLOGY_TLS_VERSION_AGGREGATE_SUFFIX = '__TLSVersion';
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

it should be low camel case per convention

*/
export type TlsLockSeverity = 'deprecated' | 'legacy' | 'modern' | 'unknown';

const SEVERITY_RANK: Record<TlsLockSeverity, number> = {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

can we add a "PQC" rank? based on version==1.3 + group being one of X25519MLKEM768, Secp256r1MLKEM768 or Secp384r1MLKEM1024

};

/** Classify a single TLSVersion label from Loki / flow JSON. */
export const classifyTlsVersionString = (raw: string): TlsLockSeverity | null => {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this is catching very large possibilities, like it's an open input, but since we control the source we could make it simpler and explicit? idk, just to keep it simpler .. of course this approach would be worse if one day we end up gathering it from more sources.

fwiw currently that's the possible values:

  • SSLv3
  • TLS 1.0
  • TLS 1.1
  • TLS 1.2
  • TLS 1.3
  • potentially prefixed with "~ "

It's up to you, if you prefer to keep as is

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

sure let's keep it simple

@github-actions github-actions Bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 19, 2026
@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 19, 2026
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:8ae20ac

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=8ae20ac make set-plugin-image

Copy link
Copy Markdown
Contributor

@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: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@web/src/components/tabs/netflow-topology/2d/topology-content.tsx`:
- Around line 474-482: The edge reset path calls e.setData({...e.getData(), tag:
undefined, tagTlsSecure: undefined, tagTlsLockSeverity: undefined,
tagTlsCleartext: undefined, tlsTypeLabels: undefined, tlsVersionLabels:
undefined}) but omits clearing tlsGroupLabels; update the reset to also set
tlsGroupLabels: undefined so stale TLS group labels are removed when resetting
edge data (locate the reset block using e.setData and e.getData in
topology-content.tsx and add tlsGroupLabels to the cleared fields).

In `@web/src/utils/metrics.ts`:
- Around line 557-569: In mergeTlsVersionUsageMetrics, preserve the original,
untrimmed TLS label for the bucket filterValue: keep using row.name.trim() for
displayName but set filterValue to the raw row.name (not trimmed) so the exact
Loki label contract on MergedTlsVersionMetricRow is honored; update the bucket
creation (the variable b and its filterValue) to assign filterValue = row.name
while leaving displayName = display and rows = [].

In `@web/src/utils/tls-lock-severity.ts`:
- Around line 10-16: SEVERITY_RANK currently assigns pqc the highest numeric
value so the "worst-wins" aggregation (the code that selects the max/worst
severity using SEVERITY_RANK) will prefer pqc over clearly insecure labels like
deprecated/legacy; update the SEVERITY_RANK mapping for TlsLockSeverity so that
deprecated and legacy have higher numeric ranks than pqc (i.e., ensure
deprecated > legacy > pqc > modern > unknown) so the existing aggregation logic
that compares SEVERITY_RANK values returns the actual worst/insecure protocol
observed.
🪄 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: eb9df904-6c19-4eef-aa57-d9ef4db65376

📥 Commits

Reviewing files that changed from the base of the PR and between 82096dc and 1ce9f11.

📒 Files selected for processing (23)
  • pkg/config/config.go
  • pkg/loki/topology_query_test.go
  • web/locales/en/plugin__netobserv-plugin.json
  • web/src/api/loki.ts
  • web/src/components/drawer/element/__tests__/element-panel.spec.tsx
  • web/src/components/drawer/element/element-panel-content.tsx
  • web/src/components/drawer/element/element-panel.tsx
  • web/src/components/dropdowns/topology-display-options.tsx
  • web/src/components/icons/tls-lock-icons.tsx
  • web/src/components/tabs/netflow-topology/2d/components/topology-connector-tag.tsx
  • web/src/components/tabs/netflow-topology/2d/topology-content.css
  • web/src/components/tabs/netflow-topology/2d/topology-content.tsx
  • web/src/components/tabs/netflow-topology/netflow-topology.tsx
  • web/src/model/__tests__/flow-query.spec.ts
  • web/src/model/filters.ts
  • web/src/model/flow-query.ts
  • web/src/model/topology.ts
  • web/src/utils/__tests__/filter-definitions.spec.ts
  • web/src/utils/__tests__/metrics.spec.ts
  • web/src/utils/__tests__/tls-lock-severity.spec.ts
  • web/src/utils/filter-definitions.ts
  • web/src/utils/metrics.ts
  • web/src/utils/tls-lock-severity.ts
🚧 Files skipped from review as they are similar to previous changes (15)
  • web/src/model/filters.ts
  • web/src/components/dropdowns/topology-display-options.tsx
  • web/src/utils/tests/filter-definitions.spec.ts
  • web/src/api/loki.ts
  • web/src/utils/tests/metrics.spec.ts
  • pkg/config/config.go
  • web/src/model/flow-query.ts
  • web/src/components/tabs/netflow-topology/2d/topology-content.css
  • web/src/utils/filter-definitions.ts
  • web/src/components/tabs/netflow-topology/2d/components/topology-connector-tag.tsx
  • web/locales/en/plugin__netobserv-plugin.json
  • web/src/components/drawer/element/element-panel-content.tsx
  • web/src/components/drawer/element/element-panel.tsx
  • web/src/components/tabs/netflow-topology/netflow-topology.tsx
  • web/src/model/topology.ts

Comment thread web/src/components/tabs/netflow-topology/2d/topology-content.tsx
Comment thread web/src/utils/metrics.ts
Comment thread web/src/utils/tls-lock-severity.ts
@github-actions github-actions Bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 19, 2026
@jpinsonneau jpinsonneau added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 19, 2026
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:5ebe411

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=5ebe411 make set-plugin-image

@jpinsonneau jpinsonneau requested a review from jotak May 19, 2026 15:16
Comment thread web/src/api/loki.ts Outdated
/** TLS breakdown from Loki matrix metric labels when present (topology TLS aggregate). */
export type GenericMetricTls = {
/** Present on flow records; omitted from topology aggregation (cardinality). */
types?: string[];
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

types can be removed I guess?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Removed in 3ab6360

I initially kept that in the UI just in case but it seems we are going to a direction where it will never be the case.
We can reintroduce it if needed in the future (maybe if we introduce a side panel for overview metrics ?)

@github-actions github-actions Bot removed the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 20, 2026
Copy link
Copy Markdown
Member

@jotak jotak left a comment

Choose a reason for hiding this comment

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

/lgtm
thanks!

@Amoghrd
Copy link
Copy Markdown
Member

Amoghrd commented May 20, 2026

/ok-to-test

@openshift-ci openshift-ci Bot added the ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. label May 20, 2026
@github-actions
Copy link
Copy Markdown

New image:

quay.io/netobserv/network-observability-console-plugin:43e0514

It will expire in two weeks.

To deploy this build, run from the operator repo, assuming the operator is running:

USER=netobserv VERSION=43e0514 make set-plugin-image

@Amoghrd
Copy link
Copy Markdown
Member

Amoghrd commented May 20, 2026

/label qe-approved

@openshift-ci openshift-ci Bot added the qe-approved QE has approved this pull request label May 20, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

lgtm needs-review Tells that the PR needs a review ok-to-test To set manually when a PR is safe to test. Triggers image build on PR. qe-approved QE has approved this pull request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants