Skip to content
This repository has been archived by the owner on Nov 28, 2024. It is now read-only.

Commit

Permalink
Search by CIDR address with ipv4 and ipv6
Browse files Browse the repository at this point in the history
  • Loading branch information
upalatucci committed Oct 24, 2023
1 parent b2e2d6d commit fbd0a24
Show file tree
Hide file tree
Showing 3 changed files with 63 additions and 11 deletions.
7 changes: 2 additions & 5 deletions src/views/states/list/components/utils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { InterfaceType, NodeNetworkConfigurationInterface } from '@types';
import { getIPV4Address, getIPV6Address } from '@utils/interfaces/getters';

import { FILTER_TYPES } from '../constants';
import { searchInterfaceByIP } from '../utilts';

export const interfaceFilters: Record<
string,
Expand All @@ -21,11 +21,8 @@ export const interfaceFilters: Record<
},
[FILTER_TYPES.IP_ADDRESS]: (selectedInput, obj) => {
const searchIPAddress = selectedInput?.[0];
if (!searchIPAddress) return true;

const addresses = [getIPV4Address(obj), getIPV6Address(obj)].filter(Boolean);

return addresses?.some((address) => address?.toLowerCase().includes(searchIPAddress));
return searchInterfaceByIP(searchIPAddress, obj);
},
} as const;

Expand Down
8 changes: 2 additions & 6 deletions src/views/states/list/hooks/useStateFilters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ import { useNMStateTranslation } from 'src/utils/hooks/useNMStateTranslation';

import { RowFilter } from '@openshift-console/dynamic-plugin-sdk';
import { InterfaceType, NodeNetworkConfigurationInterface, V1beta1NodeNetworkState } from '@types';
import { getIPV4Address, getIPV6Address } from '@utils/interfaces/getters';

import { FILTER_TYPES } from '../constants';
import { searchInterfaceByIP } from '../utilts';

const useStateFilters = (): RowFilter<V1beta1NodeNetworkState>[] => {
const { t } = useNMStateTranslation();
Expand All @@ -19,11 +19,7 @@ const useStateFilters = (): RowFilter<V1beta1NodeNetworkState>[] => {
const interfaces = obj?.status?.currentState
?.interfaces as NodeNetworkConfigurationInterface[];

const addresses = interfaces
?.reduce((acc, iface) => [...acc, getIPV4Address(iface), getIPV6Address(iface)], [])
.filter(Boolean);

return addresses?.some((address) => address?.toLowerCase().includes(searchIPAddress));
return interfaces?.some((iface) => searchInterfaceByIP(searchIPAddress, iface));
},
isMatch: () => true,
filterGroupName: t('Search IP address'),
Expand Down
59 changes: 59 additions & 0 deletions src/views/states/list/utilts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import { NodeNetworkConfigurationInterface } from '@types';
import { getIPV4Address, getIPV6Address } from '@utils/interfaces/getters';

const decimalToBinary = (decimalNumber: number) => (decimalNumber >>> 0).toString(2);

const ipv4StringToBinary = (ip: string) =>
ip
.split('.')
.map((classes) => decimalToBinary(parseInt(classes)).padStart(8, '0'))
.join('');

const convertIPv6ToBinary = (ip: string) => {
const ipBinary = ip
.toLowerCase()
.replaceAll('::', ':0000:')
.split(':')
.map((ip) => parseInt(ip, 16).toString(2).padStart(16, '0'));
return ipBinary.join('');
};

export const compareCIDR = (ipSearch: string, ip: string, isIPv4 = true) => {
const [baseIp, range] = ipSearch.split('/');

const baseIpBinary = isIPv4 ? ipv4StringToBinary(baseIp) : convertIPv6ToBinary(baseIp);

const ipBinary = isIPv4 ? ipv4StringToBinary(ip) : convertIPv6ToBinary(baseIp);

const rangeNumber = parseInt(range);

const baseIpBinarySlice = baseIpBinary.slice(0, rangeNumber);
const ipBinarySlice = ipBinary.slice(0, rangeNumber);

return baseIpBinarySlice === ipBinarySlice;
};

export const searchInterfaceByIP = (
searchIPAddress: string,
iface: NodeNetworkConfigurationInterface,
) => {
if (!searchIPAddress) return true;

const isSearchByIpv4 = searchIPAddress.includes('.');

if (searchIPAddress.includes('/')) {
const ipv4Address = getIPV4Address(iface);
const ipv6Address = getIPV6Address(iface);

if (ipv4Address && isSearchByIpv4 && compareCIDR(searchIPAddress, ipv4Address)) {
return true;
}
if (ipv6Address && !isSearchByIpv4 && compareCIDR(searchIPAddress, ipv6Address, false)) {
return true;
}
}

const addresses = [getIPV4Address(iface), getIPV6Address(iface)].filter(Boolean);

return addresses?.some((address) => address?.toLowerCase().includes(searchIPAddress));
};

0 comments on commit fbd0a24

Please sign in to comment.