Skip to content

Commit

Permalink
[Backport 4.5] Fix IPV6 visualizations (#4920)
Browse files Browse the repository at this point in the history
Fix IPV6 visualizations (#4909)

* create compression function

* Implement IPv6 compressor

* Fix visualization in agent view

* Create unit tests for ipv6-services

* Update changelog

* Add data type verification

* Migrate to ts

* Migrate to ts

* Update to match the styleguide

Co-authored-by: Álex <alejandro.ruiz.becerra@wazuh.com>
(cherry picked from commit a83bc15)

Co-authored-by: Nico Guevara <42900763+Tostti@users.noreply.github.com>
  • Loading branch information
github-actions[bot] and Tostti authored Nov 23, 2022
1 parent 63637c4 commit 7989a7e
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 22 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ All notable changes to the Wazuh app project will be documented in this file.

### Fixed

- Fixed an issue that caused incorrect visualization of IPv6 addresses ([#4909](https://github.com/wazuh/wazuh-kibana-app/pull/4909)).
- Fixed several typos in the code, by @jctello [#4911](https://github.com/wazuh/wazuh-kibana-app/pull/4911)
- Fixed references to Elasticsearch in Wazuh-stack plugin [4894](https://github.com/wazuh/wazuh-kibana-app/pull/4894)

Expand Down
15 changes: 8 additions & 7 deletions public/components/common/welcome/agents-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import WzTextWithTooltipIfTruncated from '../wz-text-with-tooltip-if-truncated';
import { WzStat } from '../../wz-stat';
import { GroupTruncate } from '../util/agent-group-truncate'
import { AgentStatus } from '../../agents/agent_status';
import { compressIPv6 } from '../../../services/ipv6-services';

export class AgentInfo extends Component {
constructor(props) {
Expand All @@ -33,7 +34,7 @@ export class AgentInfo extends Component {
this.state = {};
}


async componentDidMount() {
const managerVersion = await WzRequest.apiReq('GET', '/', {});
this.setState({
Expand Down Expand Up @@ -73,7 +74,7 @@ export class AgentInfo extends Component {
const osName = os_name === '- -' ? '-' : os_name;

return (
<WzTextWithTooltipIfTruncated position='bottom' tooltipProps={{ anchorClassName: 'wz-width-100'}} elementStyle={{ maxWidth: style.maxWidth, fontSize: 12 }}>
<WzTextWithTooltipIfTruncated position='bottom' tooltipProps={{ anchorClassName: 'wz-width-100' }} elementStyle={{ maxWidth: style.maxWidth, fontSize: 12 }}>
{this.getPlatformIcon(this.props.agent)}
{' '}{osName}
</WzTextWithTooltipIfTruncated>
Expand All @@ -99,13 +100,13 @@ export class AgentInfo extends Component {
)
}

buildStats(items) {
buildStats(items) {
const checkField = field => {
return field !== undefined || field ? field : '-';
};
const stats = items.map(item => {
// We add tooltipProps, so that the ClusterNode and Operating System fields occupy their space and do not exceed this, overlapping with the one on the right
const tooltipProps = item.description === 'Cluster node' ? { anchorClassName: 'wz-width-100'} : {};
const tooltipProps = item.description === 'Cluster node' ? { anchorClassName: 'wz-width-100' } : {};
return (
<EuiFlexItem key={item.description} style={item.style || null}>
<WzStat
Expand All @@ -122,7 +123,7 @@ export class AgentInfo extends Component {
) : item.description === 'Operating system' ? (
this.addTextPlatformRender(this.props.agent, item.style)
) : item.description === 'Status' ? (
<AgentStatus status={this.props.agent.status} style={{...item.style, fontSize: '12px'}} />
<AgentStatus status={this.props.agent.status} style={{ ...item.style, fontSize: '12px' }} />
) : (
<WzTextWithTooltipIfTruncated position='bottom' tooltipProps={tooltipProps} elementStyle={{ maxWidth: item.style.maxWidth, fontSize: 12 }}>
{checkField(item.title)}
Expand Down Expand Up @@ -157,7 +158,7 @@ export class AgentInfo extends Component {
arrayStats = [
{ title: agent.id, description: 'ID', style: { minWidth: 30 } },
{ title: agent.status, description: 'Status', style: { minWidth: 130 } },
{ title: agent.ip, description: 'IP', style: { minWidth: 80 } },
{ title: compressIPv6(agent.ip), description: 'IP', style: {} },
{ title: agent.version, description: 'Version', style: { minWidth: 100 } },
{ title: agent.group, description: 'Groups', style: { minWidth: 150 } },
{ title: agent.name, description: 'Operating system', style: { minWidth: 150 } },
Expand All @@ -173,7 +174,7 @@ export class AgentInfo extends Component {

return (
<Fragment>
<EuiFlexGroup wrap style={{responsive: true }} className="wz-welcome-page-agent-info-details">
<EuiFlexGroup wrap style={{ responsive: true }} className="wz-welcome-page-agent-info-details">
{stats}
</EuiFlexGroup>
</Fragment>
Expand Down
30 changes: 15 additions & 15 deletions public/controllers/agent/components/agents-table.js
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ import { UI_ERROR_SEVERITIES } from '../../../react-services/error-orchestrator/
import { getErrorOrchestrator } from '../../../react-services/common-services';
import { AgentStatus } from '../../../components/agents/agent_status';
import { AgentSynced } from '../../../components/agents/agent-synced';
import { compressIPv6 } from '../../../services/ipv6-services';

export const AgentsTable = withErrorBoundary(
class AgentsTable extends Component {
Expand Down Expand Up @@ -284,11 +285,10 @@ export const AgentsTable = withErrorBoundary(
};
const agentVersion = agent.version !== undefined ? agent.version.split(' ')[1] : '-';
const node_name = agent.node_name && agent.node_name !== 'unknown' ? agent.node_name : '-';

return {
id: agent.id,
name: agent.name,
ip: agent.ip,
ip: compressIPv6(agent.ip),
status: agent.status,
group_config_status: agent.group_config_status,
group: checkField(agent.group),
Expand Down Expand Up @@ -465,7 +465,7 @@ export const AgentsTable = withErrorBoundary(
field: 'id',
name: 'ID',
sortable: true,
width: '6%',
width: '4%',
},
{
field: 'name',
Expand All @@ -477,14 +477,14 @@ export const AgentsTable = withErrorBoundary(
{
field: 'ip',
name: 'IP',
width: '8%',
width: '14%',
truncateText: true,
sortable: true,
},
{
field: 'group',
name: 'Group(s)',
width: '14%',
width: '12%',
truncateText: true,
sortable: true,
render: (groups) => (groups !== '-' ? this.renderGroups(groups) : '-'),
Expand Down Expand Up @@ -530,7 +530,7 @@ export const AgentsTable = withErrorBoundary(
name: 'Status',
truncateText: true,
sortable: true,
width: '10%',
width: '8%',
render: (status) => <AgentStatus status={status} labelProps={{ className: 'hide-agent-status' }} />,
},
{
Expand All @@ -539,7 +539,7 @@ export const AgentsTable = withErrorBoundary(
truncateText: true,
sortable: true,
width: '10%',
render: (synced) => <AgentSynced synced={synced}/>,
render: (synced) => <AgentSynced synced={synced} />,
},
{
align: 'right',
Expand Down Expand Up @@ -671,7 +671,7 @@ export const AgentsTable = withErrorBoundary(
return {
'data-test-subj': `row-${id}`,
className: 'customRowClass',
onClick: () => {},
onClick: () => { },
};
};

Expand Down Expand Up @@ -700,11 +700,11 @@ export const AgentsTable = withErrorBoundary(
const pagination =
totalItems > 15
? {
pageIndex: pageIndex,
pageSize: pageSize,
totalItemCount: totalItems,
pageSizeOptions: [15, 25, 50, 100],
}
pageIndex: pageIndex,
pageSize: pageSize,
totalItemCount: totalItems,
pageSizeOptions: [15, 25, 50, 100],
}
: false;
const sorting = {
sort: {
Expand Down Expand Up @@ -739,8 +739,8 @@ export const AgentsTable = withErrorBoundary(
if (filters.length > 0) {
!auxFilters.includes(group)
? this.setState({
filters: [...filters, { field: 'q', value: `group=${group}` }],
})
filters: [...filters, { field: 'q', value: `group=${group}` }],
})
: false;
} else {
this.setState({
Expand Down
21 changes: 21 additions & 0 deletions public/services/ipv6-services.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import { compressIPv6 } from "./ipv6-services";

describe('[settings] Input validation', () => {
it.each`
value | expectedValidation
${'192.168.100.1'} | ${'192.168.100.1'}
${'FE80:1234:2223:A000:2202:B3FF:FE1E:8329'} | ${'FE80:1234:2223:A000:2202:B3FF:FE1E:8329'}
${'FE80:0034:0223:A000:0002:B3FF:0000:8329'} | ${'FE80:34:223:A000:2:B3FF:0:8329'}
${'FE80:1234:2223:0000:0000:B3FF:FE1E:8329'} | ${'FE80:1234:2223::B3FF:FE1E:8329'}
${'FE80:0000:0000:A000:0000:0000:0000:8329'} | ${'FE80:0:0:A000::8329'}
${'FE80:0000:0000:0000:2202:00FF:0E1E:8329'} | ${'FE80::2202:FF:E1E:8329'}
${'0000:0000:0000:0000:2202:00FF:0E1E:8329'} | ${'::2202:FF:E1E:8329'}
${'2202:00FF:0E1E:8329:2202:0000:0000:0000'} | ${'2202:FF:E1E:8329:2202::'}
${'0000:0000:0000:0000:0000:0000:0000:0000'} | ${'::'}
${undefined} | ${undefined}
${234} | ${234}
`('$value | $expectedValidation', ({ value, expectedValidation }) => {
expect(
compressIPv6(value)).toBe(expectedValidation);
});
});
21 changes: 21 additions & 0 deletions public/services/ipv6-services.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
export function compressIPv6 (ip: string) {
if (typeof (ip) !== 'string') {
return ip;
}
if (ip?.split(':').length !== 8) {
return ip;
}

let output = ip.split(':').map(terms => terms.replace(/\b0+/g, '') || '0').join(':');
const zeros = Array.from(output.matchAll(/\b:?(?:0+:?){2,}/g));
if (zeros.length > 0) {
let max = '';
zeros.forEach(item => {
if (item[0].replace(/:/g, '').length > max.replace(/:/g, '').length) {
max = item[0];
}
});
output = output.replace(max, '::');
}
return output;
}

0 comments on commit 7989a7e

Please sign in to comment.