Skip to content

Commit 4ac9a47

Browse files
committed
CNV-52160: UDN with topology selector
1 parent 30ba9b2 commit 4ac9a47

File tree

5 files changed

+318
-41
lines changed

5 files changed

+318
-41
lines changed

Diff for: src/utils/resources/udns/types/types.ts

+8-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ export type UserDefinedNetworkSubnet = string | UserDefinedNetworkLayer3Subnet;
2929
export type UserDefinedNetworkLayer3 = {
3030
joinSubnets?: string[];
3131
mtu?: number;
32-
role: string;
32+
role: UserDefinedNetworkRole;
3333
subnets?: UserDefinedNetworkLayer3Subnet[];
3434
};
3535

@@ -41,6 +41,13 @@ export type ClusterUserDefinedNetworkSpec = {
4141
export type UserDefinedNetworkSpec = {
4242
layer2?: UserDefinedNetworkLayer2;
4343
layer3?: UserDefinedNetworkLayer3;
44+
localnet?: {
45+
cidr?: string;
46+
hostSubnet?: number;
47+
mtu?: number;
48+
role: UserDefinedNetworkRole;
49+
subnets?: UserDefinedNetworkSubnet[];
50+
};
4451
topology: string;
4552
};
4653

Diff for: src/views/udns/list/components/SubnetsInput.tsx

+62
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
import React, { FC } from 'react';
2+
import { FieldPath, useFormContext, useWatch } from 'react-hook-form';
3+
4+
import { FormGroup, TextInput } from '@patternfly/react-core';
5+
import SubnetCIRDHelperText from '@utils/components/SubnetCIRDHelperText/SubnetCIRDHelperText';
6+
import { useNetworkingTranslation } from '@utils/hooks/useNetworkingTranslation';
7+
import {
8+
UserDefinedNetworkLayer3Subnet,
9+
UserDefinedNetworkSpec,
10+
} from '@utils/resources/udns/types';
11+
12+
import { UDNForm } from './constants';
13+
import { getSubnetFields, getSubnetsFromNetworkSpec } from './utils';
14+
15+
type SubnetsInputProps = {
16+
isClusterUDN?: boolean;
17+
};
18+
19+
const SubnetsInput: FC<SubnetsInputProps> = ({ isClusterUDN }) => {
20+
const { t } = useNetworkingTranslation();
21+
22+
const { setValue } = useFormContext<UDNForm>();
23+
const networkSpecPath = isClusterUDN ? 'spec.network' : 'spec';
24+
25+
const networkSpec: UserDefinedNetworkSpec = useWatch<UDNForm>({
26+
name: networkSpecPath,
27+
});
28+
29+
const subnets = getSubnetsFromNetworkSpec(networkSpec);
30+
31+
const subnetsText = networkSpec.layer3
32+
? (subnets as UserDefinedNetworkLayer3Subnet[]).map((subnet) => subnet.cidr).join(',')
33+
: subnets?.join(',');
34+
35+
return (
36+
<FormGroup fieldId="input-udn-subnet" isRequired label={t('Subnet CIRD')}>
37+
<TextInput
38+
autoFocus
39+
data-test="input-udn-subnet"
40+
id="input-udn-subnet"
41+
isRequired
42+
name="input-udn-subnet"
43+
onChange={(_, newValue) => {
44+
const subnetField = getSubnetFields(networkSpec, isClusterUDN);
45+
46+
const newSubnet = networkSpec.layer3
47+
? newValue.split(',').map((subnet) => ({ cidr: subnet }))
48+
: newValue.split(',');
49+
50+
setValue(subnetField as FieldPath<UDNForm>, newSubnet, {
51+
shouldValidate: true,
52+
});
53+
}}
54+
type="text"
55+
value={subnetsText}
56+
/>
57+
<SubnetCIRDHelperText />
58+
</FormGroup>
59+
);
60+
};
61+
62+
export default SubnetsInput;

Diff for: src/views/udns/list/components/Topology.tsx

+111
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
import React, { FC, Ref, useState } from 'react';
2+
import { useFormContext, useWatch } from 'react-hook-form';
3+
4+
import {
5+
DropdownItem,
6+
Flex,
7+
FlexItem,
8+
FormGroup,
9+
MenuToggle,
10+
MenuToggleElement,
11+
Radio,
12+
Select,
13+
} from '@patternfly/react-core';
14+
import { useNetworkingTranslation } from '@utils/hooks/useNetworkingTranslation';
15+
import { UserDefinedNetworkRole, UserDefinedNetworkSpec } from '@utils/resources/udns/types';
16+
17+
import { UDNForm } from './constants';
18+
import { createNetworkSpecFromRole, createNetworkSpecFromTopology, getTopology } from './utils';
19+
20+
type TopologyProps = {
21+
isClusterUDN: boolean;
22+
};
23+
24+
const Topology: FC<TopologyProps> = ({ isClusterUDN }) => {
25+
const { t } = useNetworkingTranslation();
26+
const [isDropdownOpen, setIsDropdownOpen] = useState(false);
27+
const { setValue } = useFormContext<UDNForm>();
28+
29+
const networkSpecPath = isClusterUDN ? 'spec.network' : 'spec';
30+
31+
const networkSpec: UserDefinedNetworkSpec = useWatch<UDNForm>({
32+
name: networkSpecPath,
33+
});
34+
35+
const topology = getTopology(networkSpec);
36+
37+
const isPrimary =
38+
networkSpec?.layer2?.role === UserDefinedNetworkRole.Primary ||
39+
networkSpec?.layer3?.role === UserDefinedNetworkRole.Primary;
40+
41+
const onChangeRole = (role: UserDefinedNetworkRole) => {
42+
setValue(networkSpecPath, createNetworkSpecFromRole(networkSpec, role));
43+
};
44+
45+
return (
46+
<>
47+
<FormGroup>
48+
<Flex>
49+
<FlexItem>
50+
<Radio
51+
id="primary-topology"
52+
isChecked={isPrimary}
53+
label="Primary"
54+
name="radio-topology"
55+
onChange={() => onChangeRole(UserDefinedNetworkRole.Primary)}
56+
></Radio>
57+
</FlexItem>
58+
<FlexItem>
59+
<Radio
60+
id="secondary-topology"
61+
isChecked={!isPrimary}
62+
label="Secondary"
63+
name="radio-topology"
64+
onChange={() => onChangeRole(UserDefinedNetworkRole.Secondary)}
65+
></Radio>
66+
</FlexItem>
67+
</Flex>
68+
</FormGroup>
69+
<FormGroup fieldId="select-topology" isRequired label={t('Topology')}>
70+
<Select
71+
id="select-topology"
72+
isOpen={isDropdownOpen}
73+
onOpenChange={setIsDropdownOpen}
74+
onSelect={(_, selection) => {
75+
setValue(
76+
isClusterUDN ? 'spec.network' : 'spec',
77+
createNetworkSpecFromTopology(selection as string, networkSpec),
78+
);
79+
setIsDropdownOpen(false);
80+
}}
81+
selected={topology}
82+
toggle={(toggleRef: Ref<MenuToggleElement>) => (
83+
<MenuToggle
84+
id="toggle-udns-operator"
85+
isDisabled={!isPrimary}
86+
isExpanded={isDropdownOpen}
87+
isFullWidth
88+
onClick={() => setIsDropdownOpen(!isDropdownOpen)}
89+
ref={toggleRef}
90+
>
91+
{topology}
92+
</MenuToggle>
93+
)}
94+
>
95+
<>
96+
{isPrimary ? (
97+
<>
98+
<DropdownItem value="Layer2">{t('Layer 2')}</DropdownItem>
99+
<DropdownItem value="Layer3">{t('Layer 3')}</DropdownItem>
100+
</>
101+
) : (
102+
<DropdownItem value="Locanet">{t('Localnet')}</DropdownItem>
103+
)}
104+
</>
105+
</Select>
106+
</FormGroup>
107+
</>
108+
);
109+
};
110+
111+
export default Topology;

Diff for: src/views/udns/list/components/UserDefinedNetworkCreateForm.tsx

+6-30
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,14 @@
11
import React, { FC, FormEventHandler } from 'react';
2-
import { Controller, useFormContext } from 'react-hook-form';
2+
import { useFormContext } from 'react-hook-form';
33

44
import { Alert, AlertVariant, Content, Form, FormGroup, TextInput } from '@patternfly/react-core';
5-
import SubnetCIRDHelperText from '@utils/components/SubnetCIRDHelperText/SubnetCIRDHelperText';
65
import { useNetworkingTranslation } from '@utils/hooks/useNetworkingTranslation';
76

87
import ClusterUDNNamespaceSelector from './ClusterUDNNamespaceSelector';
98
import { UDNForm } from './constants';
109
import SelectProject from './SelectProject';
10+
import SubnetsInput from './SubnetsInput';
11+
import Topology from './Topology';
1112

1213
type UserDefinedNetworkCreateFormProps = {
1314
error: Error;
@@ -22,9 +23,7 @@ const UserDefinedNetworkCreateForm: FC<UserDefinedNetworkCreateFormProps> = ({
2223
}) => {
2324
const { t } = useNetworkingTranslation();
2425

25-
const { control, register, setValue } = useFormContext<UDNForm>();
26-
27-
const subnetField = isClusterUDN ? 'spec.network.layer2.subnets' : 'spec.layer2.subnets';
26+
const { register } = useFormContext<UDNForm>();
2827

2928
return (
3029
<Form id="create-udn-form" onSubmit={onSubmit}>
@@ -48,32 +47,9 @@ const UserDefinedNetworkCreateForm: FC<UserDefinedNetworkCreateFormProps> = ({
4847
</FormGroup>
4948
)}
5049

51-
<FormGroup fieldId="input-udn-subnet" isRequired label={t('Subnet CIRD')}>
52-
<Controller
53-
control={control}
54-
name={subnetField}
55-
render={({ field: { value } }) => (
56-
<TextInput
57-
autoFocus
58-
data-test="input-udn-subnet"
59-
id="input-udn-subnet"
60-
isRequired
61-
name="input-udn-subnet"
62-
onChange={(_, newValue) =>
63-
setValue(subnetField, newValue.split(','), {
64-
shouldValidate: true,
65-
})
66-
}
67-
type="text"
68-
value={value?.join(',')}
69-
/>
70-
)}
71-
rules={{ required: true }}
72-
/>
73-
74-
<SubnetCIRDHelperText />
75-
</FormGroup>
50+
<SubnetsInput isClusterUDN={isClusterUDN} />
7651

52+
<Topology isClusterUDN={isClusterUDN} />
7753
{isClusterUDN && <ClusterUDNNamespaceSelector />}
7854

7955
{error && (

0 commit comments

Comments
 (0)