Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
250 changes: 149 additions & 101 deletions config/sample-config.yaml

Large diffs are not rendered by default.

24 changes: 12 additions & 12 deletions mocks/loki/flow_records.json

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions pkg/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ type Frontend struct {
Deduper Deduper `yaml:"deduper" json:"deduper"`
Fields []FieldConfig `yaml:"fields" json:"fields"`
DataSources []string `yaml:"dataSources" json:"dataSources"`
LokiMocks bool `yaml:"lokiMocks,omitempty" json:"lokiMocks,omitempty"`
PromLabels []string `yaml:"promLabels" json:"promLabels"`
MaxChunkAgeMs int `yaml:"maxChunkAgeMs,omitempty" json:"maxChunkAgeMs,omitempty"` // populated at query time
}
Expand Down Expand Up @@ -216,6 +217,7 @@ func ReadFile(version, date, filename string) (*Config, error) {

if cfg.IsLokiEnabled() {
cfg.Frontend.DataSources = append(cfg.Frontend.DataSources, string(constants.DataSourceLoki))
cfg.Frontend.LokiMocks = cfg.Loki.UseMocks
}

if cfg.IsPromEnabled() {
Expand Down
59 changes: 59 additions & 0 deletions web/cypress/e2e/table/fields.spec.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/// <reference types="cypress" />
import r from './../../../../mocks/loki/flow_records.json';

describe('netflow-table', () => {
beforeEach(() => {
// this test bench only work with mocks
cy.intercept('GET', '/api/loki/flow/records?*', {
statusCode: 200,
body: r.data,
});
cy.openNetflowTrafficPage(true);

//move to table view
cy.get('.tableTabButton').click();
//clear default app filters
cy.get('#clear-all-filters-button').click();
});

it('display content correctly', () => {
// select first row
cy.get('#netflow-table-row-0').click()
// check for side panel content

// Dates
//cy.checkRecordField('StartTime', 'Start Time', ['Feb 15, 2024', '4:44:27.121 PM']);
//cy.checkRecordField('EndTime', 'End Time', ['Feb 15, 2024', '4:44:27.121 PM']);

// Source accordion
cy.get('[data-test-id="group-2"]').contains("Source");
cy.checkRecordField('SrcK8S_Name', 'Name', ['N', 'ip-10-0-1-7.ec2.internal']);
cy.checkRecordField('SrcK8S_Type', 'Kind', ['Node']);
cy.checkRecordField('SrcAddr', 'IP', ['10.0.1.7']);
cy.checkRecordField('SrcPort', 'Port', ['50104']);
cy.checkRecordField('SrcMac', 'MAC', ['02:27:A1:A8:84:B9']);

// Destination accordion
cy.get('[data-test-id="group-3"]').contains("Destination");
cy.checkRecordField('DstAddr', 'IP', ['10.0.1.140']);
cy.checkRecordField('DstPort', 'Port', ['https', '443']);
cy.checkRecordField('DstMac', 'MAC', ['02:7B:32:68:BE:65']);

// others
cy.checkRecordField('K8S_FlowLayer', 'Flow layer', ['infra']);

cy.get('[data-test-id="group-5"]').contains("L3 Layer");
cy.checkRecordField('Proto', 'Protocol', ['ICMP']);
cy.checkRecordField('Dscp', 'DSCP', ['Standard']);

cy.get('[data-test-id="group-6"]').contains("ICMP");
cy.checkRecordField('IcmpType', 'Type', ['ICMP_DEST_UNREACH']);
cy.checkRecordField('IcmpCode', 'Code', ['ICMP_NET_UNREACH']);

cy.checkRecordField('FlowDirection', 'Node Direction', ['Egress']);
cy.checkRecordField('FlowDirInts', 'Interfaces and Directions', ['br-ex', 'test', 'Egress', 'Ingress']);

cy.checkRecordField('Bytes', 'Bytes', ['66 bytes sent']);
cy.checkRecordField('Packets', 'Packets', ['1 packets sent']);
});
})
10 changes: 10 additions & 0 deletions web/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,15 @@ Cypress.Commands.add('changeMetricType', (name) => {
cy.get('[data-layer-id="default"]').children().its('length').should('be.gte', 5);
});

Cypress.Commands.add('checkRecordField', (field, name, values) => {
cy.get(`[data-test-id="drawer-field-${field}"]`).contains(name);
values.forEach(v => {
cy.get(`[data-test-id="drawer-field-${field}"]`)
.children('.record-field-content,.record-field-flex-container')
.should('contain', v);
});
});

declare global {
namespace Cypress {
interface Chainable {
Expand All @@ -202,6 +211,7 @@ declare global {
changeTimeRange(name: string, topology?: boolean): Chainable<Element>
changeMetricFunction(name: string): Chainable<Element>
changeMetricType(name: string): Chainable<Element>
checkRecordField(field: string, name: string, values: string[])
}
}
}
4 changes: 2 additions & 2 deletions web/cypress/support/const.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ export const availablePanelsCount = 4;
export const defaultPanelsCount = 2;

// table specific config
export const availableColumnGroupCount = 29;
export const availableColumnCount = 55;
export const availableColumnGroupCount = 30;
export const availableColumnCount = 56;
export const defaultColumnGroupCount = 6;
export const defaultColumnCount = 11;
3 changes: 3 additions & 0 deletions web/src/components/tabs/netflow-table/netflow-table-row.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Size } from '../../dropdowns/table-display-dropdown';
import './netflow-table-row.css';

export interface NetflowTableRowProps {
rowNumber?: number;
allowPktDrops: boolean;
lastRender?: string;
flow: Record;
Expand All @@ -23,6 +24,7 @@ export interface NetflowTableRowProps {
}

export const NetflowTableRow: React.FC<NetflowTableRowProps> = ({
rowNumber,
allowPktDrops,
lastRender,
flow,
Expand All @@ -43,6 +45,7 @@ export const NetflowTableRow: React.FC<NetflowTableRowProps> = ({
return (
<CSSTransition in={highlight} appear={highlight} timeout={100} classNames="newflow">
<Tr
id={`netflow-table-row-${rowNumber || 0}`}
data-last-render={lastRender || ''}
data-test={`tr-${flow.key}`}
isRowSelected={flow.key === selectedRecord?.key}
Expand Down
1 change: 1 addition & 0 deletions web/src/components/tabs/netflow-table/netflow-table.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,7 @@ export const NetflowTable: React.FC<NetflowTableProps> = React.forwardRef(

return getSortedFlows().map((f, i) => (
<NetflowTableRow
rowNumber={i}
key={f.key}
allowPktDrops={props.allowPktDrops}
flow={f}
Expand Down
2 changes: 2 additions & 0 deletions web/src/model/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ export type Config = {
deduper: Deduper;
fields: FieldConfig[];
dataSources: string[];
lokiMocks: boolean;
promLabels: string[];
maxChunkAgeMs?: number;
};
Expand All @@ -57,6 +58,7 @@ export const defaultConfig: Config = {
},
fields: [],
dataSources: ['loki', 'prom'],
lokiMocks: false,
promLabels: [],
maxChunkAgeMs: undefined
};
2 changes: 1 addition & 1 deletion web/src/utils/icmp.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export const getICMPType = (p: number, v: icmpAllTypesValues): ReadOnlyValue | u
};

export const getICMPCode = (p: number, t?: icmpAllTypesValues, c?: icmpAllCodesValues): ReadOnlyValue | undefined => {
if (!isValidICMPProto(p) || !t || !c) {
if (!isValidICMPProto(p) || t === undefined || c === undefined) {
return undefined;
}

Expand Down
Loading