@openshift-assisted/ui-lib 2.56.1 → 2.56.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/@types/common/config/constants.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/NewClusterWizard.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.d.ts +1 -1
- package/build/@types/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/clusterWizardContext/utils.d.ts +7 -0
- package/build/@types/ocm/components/wizard/clusterWizardContext/utils.d.ts.map +1 -0
- package/build/@types/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/disconnected/BasicStep.d.ts +2 -1
- package/build/@types/ocm/components/wizard/steps/disconnected/BasicStep.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.d.ts +4 -0
- package/build/@types/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.d.ts.map +1 -0
- package/build/@types/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/disconnected/index.d.ts +1 -0
- package/build/@types/ocm/components/wizard/steps/disconnected/index.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/StaticIp.d.ts +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/StaticIp.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/commonValidationSchemas.d.ts +6 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/commonValidationSchemas.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.d.ts +24 -0
- package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.d.ts.map +1 -0
- package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.d.ts +46 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/components/StaticIpPage.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/data/dataTypes.d.ts +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/data/dataTypes.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.d.ts +8 -0
- package/build/@types/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.d.ts.map +1 -0
- package/build/@types/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.d.ts +2 -0
- package/build/@types/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/data/index.d.ts +1 -0
- package/build/@types/ocm/components/wizard/steps/staticIp/data/index.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/data/nmstateYaml.d.ts +1 -0
- package/build/@types/ocm/components/wizard/steps/staticIp/data/nmstateYaml.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/steps/staticIp/data/protocolVersion.d.ts +2 -2
- package/build/@types/ocm/components/wizard/steps/staticIp/data/protocolVersion.d.ts.map +1 -1
- package/build/@types/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.d.ts +7 -0
- package/build/@types/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.d.ts.map +1 -1
- package/build/cjs/common/components/clusterWizard/ClusterWizardStep.css +9 -0
- package/build/cjs/common/config/constants.js +1 -0
- package/build/cjs/common/config/constants.js.map +1 -1
- package/build/cjs/common/validationSchemas/addressValidation.js +2 -2
- package/build/cjs/common/validationSchemas/addressValidation.js.map +1 -1
- package/build/cjs/ocm/components/wizard/NewClusterWizard.js +4 -0
- package/build/cjs/ocm/components/wizard/NewClusterWizard.js.map +1 -1
- package/build/cjs/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.js +62 -62
- package/build/cjs/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.js.map +1 -1
- package/build/cjs/ocm/components/wizard/clusterWizardContext/utils.js +61 -0
- package/build/cjs/ocm/components/wizard/clusterWizardContext/utils.js.map +1 -0
- package/build/cjs/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.js +1 -2
- package/build/cjs/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/disconnected/BasicStep.js +95 -7
- package/build/cjs/ocm/components/wizard/steps/disconnected/BasicStep.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.js +20 -9
- package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.js +26 -0
- package/build/cjs/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.js.map +1 -0
- package/build/cjs/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.js +1 -1
- package/build/cjs/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.js +87 -56
- package/build/cjs/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/disconnected/index.js +1 -0
- package/build/cjs/ocm/components/wizard/steps/disconnected/index.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/StaticIp.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/commonValidationSchemas.js +49 -12
- package/build/cjs/ocm/components/wizard/steps/staticIp/commonValidationSchemas.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.js +13 -4
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.js +96 -4
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.js +70 -0
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.js.map +1 -0
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.js +19 -9
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/StaticIpPage.js +8 -2
- package/build/cjs/ocm/components/wizard/steps/staticIp/components/StaticIpPage.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.js +55 -0
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.js.map +1 -0
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.js +5 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.js +48 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/index.js +1 -0
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/index.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/nmstateYaml.js +12 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/nmstateYaml.js.map +1 -1
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/protocolVersion.js +9 -7
- package/build/cjs/ocm/components/wizard/steps/staticIp/data/protocolVersion.js.map +1 -1
- package/build/cjs/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.js +31 -20
- package/build/cjs/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.js.map +1 -1
- package/lib/common/components/clusterWizard/ClusterWizardStep.css +9 -0
- package/lib/common/config/constants.ts +1 -0
- package/lib/common/validationSchemas/_validationSchemas.test.ts +1 -1
- package/lib/common/validationSchemas/addressValidation.tsx +2 -2
- package/lib/ocm/components/wizard/NewClusterWizard.tsx +5 -0
- package/lib/ocm/components/wizard/clusterWizardContext/ClusterWizardContextProvider.tsx +63 -85
- package/lib/ocm/components/wizard/clusterWizardContext/utils.ts +73 -0
- package/lib/ocm/components/wizard/steps/clusterDetails/ClusterDetailsForm.tsx +0 -2
- package/lib/ocm/components/wizard/steps/disconnected/BasicStep.tsx +147 -7
- package/lib/ocm/components/wizard/steps/disconnected/DisconnectedReviewStep.tsx +44 -13
- package/lib/ocm/components/wizard/steps/disconnected/DisconnectedStaticIp.tsx +29 -0
- package/lib/ocm/components/wizard/steps/disconnected/InstallDisconnectedSwitch.tsx +1 -0
- package/lib/ocm/components/wizard/steps/disconnected/OptionalConfigurationsStep.tsx +137 -69
- package/lib/ocm/components/wizard/steps/disconnected/index.tsx +1 -0
- package/lib/ocm/components/wizard/steps/staticIp/StaticIp.tsx +1 -1
- package/lib/ocm/components/wizard/steps/staticIp/commonValidationSchemas.tsx +42 -3
- package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWide.tsx +15 -4
- package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/FormViewNetworkWideFields.tsx +232 -14
- package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/disconnectedNetworkWideValidationSchema.tsx +98 -0
- package/lib/ocm/components/wizard/steps/staticIp/components/FormViewNetworkWide/formViewNetworkWideValidationSchema.tsx +14 -5
- package/lib/ocm/components/wizard/steps/staticIp/components/StaticIpPage.tsx +8 -3
- package/lib/ocm/components/wizard/steps/staticIp/data/dataTypes.ts +1 -1
- package/lib/ocm/components/wizard/steps/staticIp/data/disconnectedNetworkWide.ts +81 -0
- package/lib/ocm/components/wizard/steps/staticIp/data/formDataFromInfraEnvField.ts +6 -2
- package/lib/ocm/components/wizard/steps/staticIp/data/fromInfraEnv.ts +57 -2
- package/lib/ocm/components/wizard/steps/staticIp/data/index.tsx +1 -0
- package/lib/ocm/components/wizard/steps/staticIp/data/nmstateYaml.ts +16 -0
- package/lib/ocm/components/wizard/steps/staticIp/data/protocolVersion.ts +9 -7
- package/lib/ocm/components/wizard/utils/_wizardTransition.test.ts +60 -1
- package/lib/ocm/components/wizard/wizardComponents/ClusterWizardNavigation.tsx +39 -16
- package/package.json +3 -3
|
@@ -23,7 +23,12 @@ import {
|
|
|
23
23
|
PopoverIcon,
|
|
24
24
|
useFieldErrorMsg,
|
|
25
25
|
} from '../../../../../../../common';
|
|
26
|
-
import {
|
|
26
|
+
import {
|
|
27
|
+
OcmCheckboxField,
|
|
28
|
+
OcmInputField,
|
|
29
|
+
OcmRadio,
|
|
30
|
+
OcmRadioField,
|
|
31
|
+
} from '../../../../../ui/OcmFormFields';
|
|
27
32
|
import {
|
|
28
33
|
getAddressObject,
|
|
29
34
|
getProtocolVersionLabel,
|
|
@@ -36,13 +41,16 @@ import {
|
|
|
36
41
|
ProtocolVersion,
|
|
37
42
|
StaticProtocolType,
|
|
38
43
|
getMachineNetworkCidr,
|
|
44
|
+
DISCONNECTED_SINGLE_STACK_FIELD,
|
|
39
45
|
} from '../../data';
|
|
46
|
+
import { detectProtocolVersionFromIp } from '../../commonValidationSchemas';
|
|
40
47
|
import {
|
|
41
48
|
MIN_PREFIX_LENGTH,
|
|
42
49
|
MAX_PREFIX_LENGTH,
|
|
43
50
|
MAX_VLAN_ID,
|
|
44
51
|
MIN_VLAN_ID,
|
|
45
52
|
} from './formViewNetworkWideValidationSchema';
|
|
53
|
+
import { useClusterWizardContext } from '../../../../clusterWizardContext';
|
|
46
54
|
|
|
47
55
|
import '../staticIp.css';
|
|
48
56
|
|
|
@@ -127,6 +135,92 @@ const MachineNetwork: React.FC<{ fieldName: string; protocolVersion: ProtocolVer
|
|
|
127
135
|
);
|
|
128
136
|
};
|
|
129
137
|
|
|
138
|
+
const SingleStackMachineNetwork: React.FC<{ fieldName: string }> = ({ fieldName }) => {
|
|
139
|
+
const [{ value }] = useField<Cidr>(fieldName);
|
|
140
|
+
const ipFieldName = `${fieldName}.ip`;
|
|
141
|
+
const prefixLengthFieldName = `${fieldName}.prefixLength`;
|
|
142
|
+
const ipErrorMessage = useFieldErrorMsg({ name: ipFieldName });
|
|
143
|
+
const prefixLengthErrorMessage = useFieldErrorMsg({ name: prefixLengthFieldName });
|
|
144
|
+
const errorMessage = ipErrorMessage || prefixLengthErrorMessage;
|
|
145
|
+
const protocolVersion = detectProtocolVersionFromIp(value.ip) ?? ProtocolVersion.ipv4;
|
|
146
|
+
const machineNetworkHelptext = React.useMemo(() => {
|
|
147
|
+
if (errorMessage) {
|
|
148
|
+
return '';
|
|
149
|
+
}
|
|
150
|
+
const cidr = getMachineNetworkCidr(value);
|
|
151
|
+
return getHumanizedSubnetRange(getAddressObject(cidr, protocolVersion));
|
|
152
|
+
}, [value, protocolVersion, errorMessage]);
|
|
153
|
+
const fieldId = getFieldId(`${fieldName}`, 'input');
|
|
154
|
+
return (
|
|
155
|
+
<FormGroup
|
|
156
|
+
labelHelp={
|
|
157
|
+
<PopoverIcon noVerticalAlign bodyContent="The range of IP addresses of the hosts." />
|
|
158
|
+
}
|
|
159
|
+
label="Subnet"
|
|
160
|
+
fieldId={fieldId}
|
|
161
|
+
isRequired
|
|
162
|
+
className="subnet"
|
|
163
|
+
>
|
|
164
|
+
<Flex>
|
|
165
|
+
<FlexItem spacer={{ default: 'spacerSm' }}>
|
|
166
|
+
<OcmInputField
|
|
167
|
+
name={`${fieldName}.ip`}
|
|
168
|
+
isRequired={true}
|
|
169
|
+
data-testid="single-stack-machine-network-ip"
|
|
170
|
+
showErrorMessage={false}
|
|
171
|
+
/>
|
|
172
|
+
</FlexItem>
|
|
173
|
+
<FlexItem spacer={{ default: 'spacerSm' }}>{'/'}</FlexItem>
|
|
174
|
+
<FlexItem>
|
|
175
|
+
<OcmInputField
|
|
176
|
+
name={`${fieldName}.prefixLength`}
|
|
177
|
+
isRequired={true}
|
|
178
|
+
data-testid="single-stack-machine-network-prefix-length"
|
|
179
|
+
type={TextInputTypes.number}
|
|
180
|
+
showErrorMessage={false}
|
|
181
|
+
min={MIN_PREFIX_LENGTH}
|
|
182
|
+
max={MAX_PREFIX_LENGTH.ipv6}
|
|
183
|
+
/>
|
|
184
|
+
</FlexItem>
|
|
185
|
+
</Flex>
|
|
186
|
+
{(errorMessage || machineNetworkHelptext) && (
|
|
187
|
+
<FormHelperText>
|
|
188
|
+
<HelperText>
|
|
189
|
+
<HelperTextItem
|
|
190
|
+
icon={errorMessage ? <ExclamationCircleIcon /> : null}
|
|
191
|
+
variant={errorMessage ? 'error' : 'default'}
|
|
192
|
+
id={errorMessage ? `${fieldId}-helper-error` : `${fieldId}-helper`}
|
|
193
|
+
data-testid={`input-machine-network-${fieldId}-helper-text`}
|
|
194
|
+
>
|
|
195
|
+
{errorMessage ? errorMessage : machineNetworkHelptext}
|
|
196
|
+
</HelperTextItem>
|
|
197
|
+
</HelperText>
|
|
198
|
+
</FormHelperText>
|
|
199
|
+
)}
|
|
200
|
+
</FormGroup>
|
|
201
|
+
);
|
|
202
|
+
};
|
|
203
|
+
|
|
204
|
+
const SingleStackIpConfigFields: React.FC<{ fieldName: string }> = ({ fieldName }) => {
|
|
205
|
+
return (
|
|
206
|
+
<Grid hasGutter>
|
|
207
|
+
<SingleStackMachineNetwork fieldName={`${fieldName}.machineNetwork`} />
|
|
208
|
+
<OcmInputField
|
|
209
|
+
isRequired
|
|
210
|
+
label="Default gateway"
|
|
211
|
+
labelIcon={
|
|
212
|
+
<PopoverIcon
|
|
213
|
+
noVerticalAlign
|
|
214
|
+
bodyContent="An IP address to where any IP packet should be forwarded in case there is no other routing rule configured for a destination IP."
|
|
215
|
+
/>
|
|
216
|
+
}
|
|
217
|
+
name={`${fieldName}.gateway`}
|
|
218
|
+
data-testid="single-stack-gateway"
|
|
219
|
+
/>
|
|
220
|
+
</Grid>
|
|
221
|
+
);
|
|
222
|
+
};
|
|
223
|
+
|
|
130
224
|
const IpConfigFields: React.FC<{
|
|
131
225
|
fieldName: string;
|
|
132
226
|
protocolVersion: ProtocolVersion;
|
|
@@ -155,7 +249,7 @@ const ipv6ValuesEmpty = (values: FormViewNetworkWideValues) =>
|
|
|
155
249
|
values.ipConfigs.ipv6.machineNetwork.ip === '' &&
|
|
156
250
|
values.ipConfigs.ipv6.machineNetwork.prefixLength === '';
|
|
157
251
|
|
|
158
|
-
|
|
252
|
+
const ConnectedProtocolTypeSelect = () => {
|
|
159
253
|
const selectFieldName = 'protocolType';
|
|
160
254
|
const [{ value: protocolType }, , { setValue: setProtocolType }] =
|
|
161
255
|
useField<StaticProtocolType>(selectFieldName);
|
|
@@ -171,7 +265,6 @@ export const ProtocolTypeSelect = () => {
|
|
|
171
265
|
if (newProtocolType === 'ipv4' && !ipv6ValuesEmpty(values)) {
|
|
172
266
|
setConfirmModal(true);
|
|
173
267
|
} else {
|
|
174
|
-
//no need to empty ipv4, when switching back dual stack ipv4 remains as is
|
|
175
268
|
setIpv6(getEmptyIpConfig());
|
|
176
269
|
setProtocolType(newProtocolType);
|
|
177
270
|
}
|
|
@@ -239,6 +332,99 @@ export const ProtocolTypeSelect = () => {
|
|
|
239
332
|
}}
|
|
240
333
|
onConfirm={() => {
|
|
241
334
|
setConfirmModal(false);
|
|
335
|
+
setIpv6(getEmptyIpConfig());
|
|
336
|
+
setProtocolType('ipv4');
|
|
337
|
+
}}
|
|
338
|
+
/>
|
|
339
|
+
)}
|
|
340
|
+
</>
|
|
341
|
+
);
|
|
342
|
+
};
|
|
343
|
+
|
|
344
|
+
const DisconnectedProtocolTypeSelect = () => {
|
|
345
|
+
const selectFieldName = 'protocolType';
|
|
346
|
+
const [{ value: protocolType }, , { setValue: setProtocolType }] =
|
|
347
|
+
useField<StaticProtocolType>(selectFieldName);
|
|
348
|
+
const [, , { setValue: setIpv6 }] = useField<IpConfig>(`ipConfigs.ipv6`);
|
|
349
|
+
const [openConfirmModal, setConfirmModal] = React.useState(false);
|
|
350
|
+
const { values } = useFormikContext<FormViewNetworkWideValues>();
|
|
351
|
+
|
|
352
|
+
const isDualStack = protocolType === 'dualStack';
|
|
353
|
+
const singleStackRadioId = getFieldId(selectFieldName, 'radio', 'singleStack');
|
|
354
|
+
const dualStackRadioId = getFieldId(selectFieldName, 'radio', 'dualStack');
|
|
355
|
+
|
|
356
|
+
const switchToSingleStack = () => {
|
|
357
|
+
if (protocolType !== 'dualStack') {
|
|
358
|
+
return;
|
|
359
|
+
}
|
|
360
|
+
if (!ipv6ValuesEmpty(values)) {
|
|
361
|
+
setConfirmModal(true);
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
setIpv6(getEmptyIpConfig());
|
|
365
|
+
setProtocolType('ipv4');
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
const switchToDualStack = () => {
|
|
369
|
+
if (protocolType === 'dualStack') {
|
|
370
|
+
return;
|
|
371
|
+
}
|
|
372
|
+
setProtocolType('dualStack');
|
|
373
|
+
};
|
|
374
|
+
|
|
375
|
+
return (
|
|
376
|
+
<>
|
|
377
|
+
<FormGroup
|
|
378
|
+
fieldId={getFieldId(selectFieldName, 'radio')}
|
|
379
|
+
isInline
|
|
380
|
+
label="Networking stack type"
|
|
381
|
+
isRequired
|
|
382
|
+
>
|
|
383
|
+
<OcmRadio
|
|
384
|
+
id={singleStackRadioId}
|
|
385
|
+
name={`${selectFieldName}-stack-level`}
|
|
386
|
+
data-testid="select-single-stack"
|
|
387
|
+
label={
|
|
388
|
+
<>
|
|
389
|
+
{'Single stack\u00A0'}
|
|
390
|
+
<PopoverIcon
|
|
391
|
+
noVerticalAlign
|
|
392
|
+
bodyContent="Use either IPv4 or IPv6 for all network-wide and host addresses. The address family is determined from the subnet you enter below."
|
|
393
|
+
/>
|
|
394
|
+
</>
|
|
395
|
+
}
|
|
396
|
+
isChecked={!isDualStack}
|
|
397
|
+
onChange={() => switchToSingleStack()}
|
|
398
|
+
/>
|
|
399
|
+
<OcmRadio
|
|
400
|
+
id={dualStackRadioId}
|
|
401
|
+
name={`${selectFieldName}-stack-level`}
|
|
402
|
+
data-testid="select-dual-stack"
|
|
403
|
+
label={
|
|
404
|
+
<>
|
|
405
|
+
{'Dual-stack'}{' '}
|
|
406
|
+
<PopoverIcon
|
|
407
|
+
noVerticalAlign
|
|
408
|
+
bodyContent="Select dual-stack when your hosts are using IPV4 together with IPV6."
|
|
409
|
+
/>
|
|
410
|
+
</>
|
|
411
|
+
}
|
|
412
|
+
isChecked={isDualStack}
|
|
413
|
+
onChange={() => switchToDualStack()}
|
|
414
|
+
/>
|
|
415
|
+
</FormGroup>
|
|
416
|
+
|
|
417
|
+
{openConfirmModal && (
|
|
418
|
+
<ConfirmationModal
|
|
419
|
+
title={'Change networking stack type?'}
|
|
420
|
+
titleIconVariant={'warning'}
|
|
421
|
+
confirmationButtonText={'Change'}
|
|
422
|
+
confirmationButtonVariant={ButtonVariant.primary}
|
|
423
|
+
content={<p>All data and configuration done for 'Dual-stack' will be lost.</p>}
|
|
424
|
+
onClose={() => setConfirmModal(false)}
|
|
425
|
+
onConfirm={() => {
|
|
426
|
+
setConfirmModal(false);
|
|
427
|
+
setIpv6(getEmptyIpConfig());
|
|
242
428
|
setProtocolType('ipv4');
|
|
243
429
|
}}
|
|
244
430
|
/>
|
|
@@ -246,8 +432,30 @@ export const ProtocolTypeSelect = () => {
|
|
|
246
432
|
</>
|
|
247
433
|
);
|
|
248
434
|
};
|
|
435
|
+
|
|
436
|
+
export const ProtocolTypeSelect = () => {
|
|
437
|
+
const { installDisconnected } = useClusterWizardContext();
|
|
438
|
+
if (installDisconnected) {
|
|
439
|
+
return <DisconnectedProtocolTypeSelect />;
|
|
440
|
+
}
|
|
441
|
+
return <ConnectedProtocolTypeSelect />;
|
|
442
|
+
};
|
|
443
|
+
const getIpConfigSectionLabel = (
|
|
444
|
+
protocolVersion: ProtocolVersion,
|
|
445
|
+
protocolType: StaticProtocolType,
|
|
446
|
+
installDisconnected: boolean,
|
|
447
|
+
): string => {
|
|
448
|
+
if (installDisconnected && protocolType !== 'dualStack') {
|
|
449
|
+
return 'Single stack';
|
|
450
|
+
}
|
|
451
|
+
return getProtocolVersionLabel(protocolVersion);
|
|
452
|
+
};
|
|
453
|
+
|
|
249
454
|
export const FormViewNetworkWideFields = ({ hosts }: { hosts: FormViewHost[] }) => {
|
|
455
|
+
const { installDisconnected } = useClusterWizardContext();
|
|
250
456
|
const { values, setFieldValue } = useFormikContext<FormViewNetworkWideValues>();
|
|
457
|
+
const isDisconnectedSingleStack = installDisconnected && values.protocolType !== 'dualStack';
|
|
458
|
+
|
|
251
459
|
return (
|
|
252
460
|
<>
|
|
253
461
|
<Content>
|
|
@@ -297,18 +505,28 @@ export const FormViewNetworkWideFields = ({ hosts }: { hosts: FormViewHost[] })
|
|
|
297
505
|
helperText={'List of your DNS server addresses, separated by commas.'}
|
|
298
506
|
/>
|
|
299
507
|
|
|
300
|
-
{
|
|
301
|
-
<FormGroup
|
|
302
|
-
|
|
303
|
-
label={getProtocolVersionLabel(protocolVersion)}
|
|
304
|
-
fieldId={getFieldId(`ip-configs-${protocolVersion}`, 'input')}
|
|
305
|
-
>
|
|
306
|
-
<IpConfigFields
|
|
307
|
-
fieldName={`ipConfigs.${protocolVersion}`}
|
|
308
|
-
protocolVersion={protocolVersion}
|
|
309
|
-
/>
|
|
508
|
+
{isDisconnectedSingleStack ? (
|
|
509
|
+
<FormGroup label="Single stack" fieldId={getFieldId('ip-configs-single-stack', 'input')}>
|
|
510
|
+
<SingleStackIpConfigFields fieldName={`ipConfigs.${DISCONNECTED_SINGLE_STACK_FIELD}`} />
|
|
310
511
|
</FormGroup>
|
|
311
|
-
)
|
|
512
|
+
) : (
|
|
513
|
+
getShownProtocolVersions(values.protocolType).map((protocolVersion) => (
|
|
514
|
+
<FormGroup
|
|
515
|
+
key={protocolVersion}
|
|
516
|
+
label={getIpConfigSectionLabel(
|
|
517
|
+
protocolVersion,
|
|
518
|
+
values.protocolType,
|
|
519
|
+
installDisconnected,
|
|
520
|
+
)}
|
|
521
|
+
fieldId={getFieldId(`ip-configs-${protocolVersion}`, 'input')}
|
|
522
|
+
>
|
|
523
|
+
<IpConfigFields
|
|
524
|
+
fieldName={`ipConfigs.${protocolVersion}`}
|
|
525
|
+
protocolVersion={protocolVersion}
|
|
526
|
+
/>
|
|
527
|
+
</FormGroup>
|
|
528
|
+
))
|
|
529
|
+
)}
|
|
312
530
|
</>
|
|
313
531
|
);
|
|
314
532
|
};
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import * as Yup from 'yup';
|
|
2
|
+
import { IpConfig, FormViewNetworkWideValues, Cidr } from '../../data';
|
|
3
|
+
import {
|
|
4
|
+
detectProtocolVersionFromIp,
|
|
5
|
+
getDnsMatchingSubnetFamilyValidationSchema,
|
|
6
|
+
getFamilyAgnosticIpValidationSchema,
|
|
7
|
+
isNotReservedHostIPAddress,
|
|
8
|
+
} from '../../commonValidationSchemas';
|
|
9
|
+
import {
|
|
10
|
+
buildNetworkWideValidationSchema,
|
|
11
|
+
getInMachineNetworkValidationSchema,
|
|
12
|
+
getIsNotNetworkOrBroadcastAddressSchema,
|
|
13
|
+
getIPValidationSchema,
|
|
14
|
+
MAX_PREFIX_LENGTH,
|
|
15
|
+
MIN_PREFIX_LENGTH,
|
|
16
|
+
validateNumber,
|
|
17
|
+
MAX_VLAN_ID,
|
|
18
|
+
MUST_BE_A_NUMBER,
|
|
19
|
+
} from './formViewNetworkWideValidationSchema';
|
|
20
|
+
|
|
21
|
+
const REQUIRED_MESSAGE = 'A value is required';
|
|
22
|
+
|
|
23
|
+
const transformNumber = (originalValue: number) => {
|
|
24
|
+
return isNaN(originalValue) ? null : originalValue;
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
const getDisconnectedSingleStackMachineNetworkSchema = (subnetIp: string) =>
|
|
28
|
+
Yup.object<Cidr>().shape({
|
|
29
|
+
ip: getFamilyAgnosticIpValidationSchema().required(REQUIRED_MESSAGE),
|
|
30
|
+
prefixLength: Yup.number()
|
|
31
|
+
.required('Prefix length is required')
|
|
32
|
+
.min(MIN_PREFIX_LENGTH, `Prefix length must be more than or equal to ${MIN_PREFIX_LENGTH}`)
|
|
33
|
+
.test(
|
|
34
|
+
'prefix-length-family',
|
|
35
|
+
`Prefix length must be less than or equal to ${MAX_PREFIX_LENGTH.ipv6}`,
|
|
36
|
+
(prefixLength) => {
|
|
37
|
+
if (prefixLength === undefined || prefixLength === null) {
|
|
38
|
+
return true;
|
|
39
|
+
}
|
|
40
|
+
const family = detectProtocolVersionFromIp(subnetIp);
|
|
41
|
+
const max = family ? MAX_PREFIX_LENGTH[family] : MAX_PREFIX_LENGTH.ipv6;
|
|
42
|
+
return prefixLength <= max;
|
|
43
|
+
},
|
|
44
|
+
)
|
|
45
|
+
.transform(transformNumber) as Yup.NumberSchema,
|
|
46
|
+
});
|
|
47
|
+
|
|
48
|
+
const getDisconnectedSingleStackIpConfigSchema = (ipConfig: IpConfig) => {
|
|
49
|
+
const subnetIp = ipConfig.machineNetwork.ip;
|
|
50
|
+
const family = detectProtocolVersionFromIp(subnetIp);
|
|
51
|
+
|
|
52
|
+
const gatewaySchema = family
|
|
53
|
+
? getIPValidationSchema(family)
|
|
54
|
+
.concat(getInMachineNetworkValidationSchema(family, ipConfig.machineNetwork))
|
|
55
|
+
.concat(getIsNotNetworkOrBroadcastAddressSchema(family, ipConfig.machineNetwork))
|
|
56
|
+
: getFamilyAgnosticIpValidationSchema()
|
|
57
|
+
.required(REQUIRED_MESSAGE)
|
|
58
|
+
.concat(isNotReservedHostIPAddress());
|
|
59
|
+
|
|
60
|
+
return Yup.object({
|
|
61
|
+
machineNetwork: getDisconnectedSingleStackMachineNetworkSchema(subnetIp),
|
|
62
|
+
gateway: gatewaySchema,
|
|
63
|
+
});
|
|
64
|
+
};
|
|
65
|
+
|
|
66
|
+
const buildDisconnectedSingleStackValidationSchema = (values: FormViewNetworkWideValues) => {
|
|
67
|
+
const subnetIp = values.ipConfigs.ipv4.machineNetwork.ip;
|
|
68
|
+
|
|
69
|
+
return Yup.object({
|
|
70
|
+
useVlan: Yup.boolean(),
|
|
71
|
+
vlanId: Yup.mixed().when('useVlan', {
|
|
72
|
+
is: (useVlan: boolean) => useVlan,
|
|
73
|
+
then: () =>
|
|
74
|
+
Yup.number()
|
|
75
|
+
.required(MUST_BE_A_NUMBER)
|
|
76
|
+
.min(1, `Must be more than or equal to 1`)
|
|
77
|
+
.max(MAX_VLAN_ID, `Must be less than or equal to ${MAX_VLAN_ID}`)
|
|
78
|
+
.test('not-number', MUST_BE_A_NUMBER, () => validateNumber(values.vlanId))
|
|
79
|
+
.nullable()
|
|
80
|
+
.transform(transformNumber) as Yup.NumberSchema,
|
|
81
|
+
}),
|
|
82
|
+
protocolType: Yup.string(),
|
|
83
|
+
dns: getDnsMatchingSubnetFamilyValidationSchema(subnetIp),
|
|
84
|
+
ipConfigs: Yup.object({
|
|
85
|
+
ipv4: getDisconnectedSingleStackIpConfigSchema(values.ipConfigs.ipv4),
|
|
86
|
+
ipv6: Yup.object<IpConfig>(),
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
};
|
|
90
|
+
|
|
91
|
+
export const disconnectedNetworkWideValidationSchema = Yup.lazy(
|
|
92
|
+
(values: FormViewNetworkWideValues) => {
|
|
93
|
+
if (values.protocolType === 'dualStack') {
|
|
94
|
+
return buildNetworkWideValidationSchema(values);
|
|
95
|
+
}
|
|
96
|
+
return buildDisconnectedSingleStackValidationSchema(values);
|
|
97
|
+
},
|
|
98
|
+
);
|
|
@@ -19,7 +19,7 @@ import {
|
|
|
19
19
|
} from '../../commonValidationSchemas';
|
|
20
20
|
|
|
21
21
|
const REQUIRED_MESSAGE = 'A value is required';
|
|
22
|
-
const MUST_BE_A_NUMBER = 'Must be a number';
|
|
22
|
+
export const MUST_BE_A_NUMBER = 'Must be a number';
|
|
23
23
|
const ONLY_DIGITS_REGEX = /^\d+$/;
|
|
24
24
|
|
|
25
25
|
export const MIN_PREFIX_LENGTH = 1;
|
|
@@ -68,7 +68,7 @@ const getMachineNetworkValidationSchema = (protocolVersion: ProtocolVersion) =>
|
|
|
68
68
|
.transform(transformNumber) as Yup.NumberSchema, //add casting to not get typescript error caused by nullable
|
|
69
69
|
});
|
|
70
70
|
|
|
71
|
-
const getIPValidationSchema = (protocolVersion: ProtocolVersion) => {
|
|
71
|
+
export const getIPValidationSchema = (protocolVersion: ProtocolVersion) => {
|
|
72
72
|
return getIpAddressValidationSchema(protocolVersion)
|
|
73
73
|
.required(REQUIRED_MESSAGE)
|
|
74
74
|
.concat(isNotReservedHostIPAddress(protocolVersion));
|
|
@@ -80,6 +80,11 @@ const getDNSValidationSchema = (protocolType: StaticProtocolType) => {
|
|
|
80
80
|
.required(REQUIRED_MESSAGE)
|
|
81
81
|
.concat(isNotReservedHostDNSAddress());
|
|
82
82
|
}
|
|
83
|
+
if (protocolType === 'ipv6') {
|
|
84
|
+
return getMultipleIpAddressValidationSchema(ProtocolVersion.ipv6)
|
|
85
|
+
.required(REQUIRED_MESSAGE)
|
|
86
|
+
.concat(isNotReservedHostDNSAddress(ProtocolVersion.ipv6));
|
|
87
|
+
}
|
|
83
88
|
return getMultipleIpAddressValidationSchema(ProtocolVersion.ipv4)
|
|
84
89
|
.required(REQUIRED_MESSAGE)
|
|
85
90
|
.concat(isNotReservedHostDNSAddress(ProtocolVersion.ipv4));
|
|
@@ -94,9 +99,11 @@ const getAddressDataValidationSchema = (protocolVersion: ProtocolVersion, ipConf
|
|
|
94
99
|
});
|
|
95
100
|
};
|
|
96
101
|
|
|
97
|
-
export const
|
|
102
|
+
export const buildNetworkWideValidationSchema = (values: FormViewNetworkWideValues) => {
|
|
98
103
|
const ipConfigsValidationSchemas = Yup.object({
|
|
99
|
-
ipv4:
|
|
104
|
+
ipv4: showProtocolVersion(values.protocolType, ProtocolVersion.ipv4)
|
|
105
|
+
? getAddressDataValidationSchema(ProtocolVersion.ipv4, values.ipConfigs.ipv4)
|
|
106
|
+
: Yup.object<IpConfig>(),
|
|
100
107
|
ipv6: showProtocolVersion(values.protocolType, ProtocolVersion.ipv6)
|
|
101
108
|
? getAddressDataValidationSchema(ProtocolVersion.ipv6, values.ipConfigs.ipv6)
|
|
102
109
|
: Yup.object<IpConfig>(),
|
|
@@ -119,7 +126,9 @@ export const networkWideValidationSchema = Yup.lazy((values: FormViewNetworkWide
|
|
|
119
126
|
dns: getDNSValidationSchema(values.protocolType),
|
|
120
127
|
ipConfigs: ipConfigsValidationSchemas,
|
|
121
128
|
});
|
|
122
|
-
}
|
|
129
|
+
};
|
|
130
|
+
|
|
131
|
+
export const networkWideValidationSchema = Yup.lazy(buildNetworkWideValidationSchema);
|
|
123
132
|
|
|
124
133
|
export const validateNumber = (vlanId: FormViewNetworkWideValues['vlanId']) => {
|
|
125
134
|
//We need to validate that value is a number(without letters) and is not an exponential number (ex: 1e2)
|
|
@@ -95,8 +95,10 @@ export const StaticIpPage: React.FC<StaticIpPageProps> = ({
|
|
|
95
95
|
<GridItem>
|
|
96
96
|
<ClusterWizardStepHeader>Static network configurations</ClusterWizardStepHeader>
|
|
97
97
|
<Content component={ContentVariants.small}>
|
|
98
|
-
Network configuration can be done using either the form view or YAML view.
|
|
99
|
-
|
|
98
|
+
Network configuration can be done using either the form view or YAML view.
|
|
99
|
+
{clusterWizardContext.installDisconnected
|
|
100
|
+
? ' Configurations done in this step are for hosts.'
|
|
101
|
+
: ' Configurations done in this step are for discovering hosts.'}
|
|
100
102
|
</Content>
|
|
101
103
|
</GridItem>
|
|
102
104
|
|
|
@@ -108,7 +110,10 @@ export const StaticIpPage: React.FC<StaticIpPageProps> = ({
|
|
|
108
110
|
onChangeView={onChangeView}
|
|
109
111
|
/>
|
|
110
112
|
)}
|
|
111
|
-
{
|
|
113
|
+
{/* Disconnected flow has no Host discovery step; the ISO is generated at the end */}
|
|
114
|
+
{!clusterWizardContext.installDisconnected &&
|
|
115
|
+
initialStaticIpInfo.isDataComplete &&
|
|
116
|
+
isoRegenerationAlert}
|
|
112
117
|
{content}
|
|
113
118
|
</Grid>
|
|
114
119
|
);
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import { Address4, Address6 } from 'ip-address';
|
|
2
|
+
import { InfraEnv } from '@openshift-assisted/types/assisted-installer-service';
|
|
3
|
+
import { FormViewNetworkWideValues, ProtocolVersion } from './dataTypes';
|
|
4
|
+
import { getEmptyIpConfig } from './emptyData';
|
|
5
|
+
import { getFormViewNetworkWideValues } from './fromInfraEnv';
|
|
6
|
+
import { networkWideToInfraEnvField } from './formDataToInfraEnvField';
|
|
7
|
+
|
|
8
|
+
export const DISCONNECTED_SINGLE_STACK_FIELD = ProtocolVersion.ipv4;
|
|
9
|
+
|
|
10
|
+
const isIpv6OnlyAddress = (ip: string): boolean => Address6.isValid(ip) && !Address4.isValid(ip);
|
|
11
|
+
|
|
12
|
+
export const normalizeDisconnectedNetworkWideForLoad = (
|
|
13
|
+
values: FormViewNetworkWideValues,
|
|
14
|
+
): FormViewNetworkWideValues => {
|
|
15
|
+
if (values.protocolType === 'dualStack') {
|
|
16
|
+
return values;
|
|
17
|
+
}
|
|
18
|
+
if (values.protocolType === 'ipv6') {
|
|
19
|
+
return {
|
|
20
|
+
...values,
|
|
21
|
+
protocolType: 'ipv4',
|
|
22
|
+
ipConfigs: {
|
|
23
|
+
ipv4: { ...values.ipConfigs.ipv6 },
|
|
24
|
+
ipv6: getEmptyIpConfig(),
|
|
25
|
+
},
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
return {
|
|
29
|
+
...values,
|
|
30
|
+
ipConfigs: {
|
|
31
|
+
ipv4: { ...values.ipConfigs.ipv4 },
|
|
32
|
+
ipv6: getEmptyIpConfig(),
|
|
33
|
+
},
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
export const normalizeDisconnectedNetworkWideForSave = (
|
|
38
|
+
values: FormViewNetworkWideValues,
|
|
39
|
+
): FormViewNetworkWideValues => {
|
|
40
|
+
if (values.protocolType === 'dualStack') {
|
|
41
|
+
return values;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const singleStackConfig = values.ipConfigs[DISCONNECTED_SINGLE_STACK_FIELD];
|
|
45
|
+
const subnetIp = singleStackConfig.machineNetwork.ip;
|
|
46
|
+
|
|
47
|
+
if (subnetIp && isIpv6OnlyAddress(subnetIp)) {
|
|
48
|
+
return {
|
|
49
|
+
...values,
|
|
50
|
+
protocolType: 'ipv6',
|
|
51
|
+
ipConfigs: {
|
|
52
|
+
ipv4: getEmptyIpConfig(),
|
|
53
|
+
ipv6: { ...singleStackConfig },
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
return {
|
|
59
|
+
...values,
|
|
60
|
+
protocolType: 'ipv4',
|
|
61
|
+
ipConfigs: {
|
|
62
|
+
ipv4: { ...singleStackConfig },
|
|
63
|
+
ipv6: getEmptyIpConfig(),
|
|
64
|
+
},
|
|
65
|
+
};
|
|
66
|
+
};
|
|
67
|
+
|
|
68
|
+
export const getDisconnectedFormViewNetworkWideValues = (
|
|
69
|
+
infraEnv: InfraEnv,
|
|
70
|
+
): FormViewNetworkWideValues => {
|
|
71
|
+
const values = getFormViewNetworkWideValues(infraEnv);
|
|
72
|
+
return normalizeDisconnectedNetworkWideForLoad(values);
|
|
73
|
+
};
|
|
74
|
+
|
|
75
|
+
export const disconnectedNetworkWideToInfraEnvField = (
|
|
76
|
+
currentInfraEnv: InfraEnv,
|
|
77
|
+
networkWide: FormViewNetworkWideValues,
|
|
78
|
+
) => {
|
|
79
|
+
const normalized = normalizeDisconnectedNetworkWideForSave(networkWide);
|
|
80
|
+
return networkWideToInfraEnvField(currentInfraEnv, normalized);
|
|
81
|
+
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
StaticProtocolType,
|
|
10
10
|
} from './dataTypes';
|
|
11
11
|
import {
|
|
12
|
-
|
|
12
|
+
getRouteGateway,
|
|
13
13
|
YAML_COMMENT_CHAR,
|
|
14
14
|
getMachineNetworks,
|
|
15
15
|
getProtocolType,
|
|
@@ -89,7 +89,11 @@ const getGateway = (nmstate: Nmstate, protocolVersion: ProtocolVersion): string
|
|
|
89
89
|
if (!routesConfig) {
|
|
90
90
|
throw `Nmstate yaml doesn't contain routes section`;
|
|
91
91
|
}
|
|
92
|
-
|
|
92
|
+
const gateway = getRouteGateway(routesConfig, protocolVersion);
|
|
93
|
+
if (!gateway) {
|
|
94
|
+
throw `Nmstate yaml doesn't contain a route for protocol version ${protocolVersion}`;
|
|
95
|
+
}
|
|
96
|
+
return gateway;
|
|
93
97
|
};
|
|
94
98
|
|
|
95
99
|
const getNetworkWideConfigurations = (
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { Address6 } from 'ip-address';
|
|
1
2
|
import {
|
|
2
3
|
HostStaticNetworkConfig,
|
|
3
4
|
InfraEnv,
|
|
4
5
|
} from '@openshift-assisted/types/assisted-installer-service';
|
|
5
6
|
import { stringToJSON } from '../../../../../../common';
|
|
6
|
-
import {
|
|
7
|
+
import {
|
|
8
|
+
FORM_VIEW_PREFIX,
|
|
9
|
+
getProtocolType,
|
|
10
|
+
getYamlComments,
|
|
11
|
+
yamlToNmstateObject,
|
|
12
|
+
} from './nmstateYaml';
|
|
7
13
|
import {
|
|
8
14
|
StaticIpInfo,
|
|
9
15
|
StaticIpView,
|
|
@@ -11,8 +17,10 @@ import {
|
|
|
11
17
|
FormViewHostsValues,
|
|
12
18
|
FormViewNetworkWideValues,
|
|
13
19
|
YamlViewValues,
|
|
20
|
+
ProtocolVersion,
|
|
14
21
|
} from './dataTypes';
|
|
15
|
-
import { isDummyYaml } from './dummyData';
|
|
22
|
+
import { isDummyInterface, isDummyYaml } from './dummyData';
|
|
23
|
+
import { NmstateInterface } from './nmstateTypes';
|
|
16
24
|
import { formDataFromInfraEnvField } from './formDataFromInfraEnvField';
|
|
17
25
|
import { getEmptyFormViewHost } from './emptyData';
|
|
18
26
|
|
|
@@ -91,3 +99,50 @@ export const getYamlViewValues = (infraEnv: InfraEnv): YamlViewValues => {
|
|
|
91
99
|
}
|
|
92
100
|
return { hosts: staticNetworkConfig };
|
|
93
101
|
};
|
|
102
|
+
|
|
103
|
+
export const canonicalizeIp = (ip: string): string => {
|
|
104
|
+
if (Address6.isValid(ip)) {
|
|
105
|
+
return new Address6(ip).correctForm();
|
|
106
|
+
}
|
|
107
|
+
return ip;
|
|
108
|
+
};
|
|
109
|
+
|
|
110
|
+
const getIpsFromInterface = (networkInterface: NmstateInterface): string[] => {
|
|
111
|
+
const ips: string[] = [];
|
|
112
|
+
for (const protocolVersion of [ProtocolVersion.ipv4, ProtocolVersion.ipv6]) {
|
|
113
|
+
const addresses = networkInterface[protocolVersion]?.address;
|
|
114
|
+
if (addresses?.length) {
|
|
115
|
+
for (const entry of addresses) {
|
|
116
|
+
if (entry.ip) {
|
|
117
|
+
ips.push(entry.ip);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return ips;
|
|
123
|
+
};
|
|
124
|
+
|
|
125
|
+
export const getHostIpsFromInfraEnv = (infraEnv: InfraEnv | undefined): string[] => {
|
|
126
|
+
if (!infraEnv) {
|
|
127
|
+
return [];
|
|
128
|
+
}
|
|
129
|
+
const staticNetworkConfig = getStaticNetworkConfig(infraEnv);
|
|
130
|
+
if (!staticNetworkConfig?.length) {
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
const hostIps: string[] = [];
|
|
135
|
+
for (const hostConfig of staticNetworkConfig) {
|
|
136
|
+
if (!hostConfig.networkYaml || isDummyYaml(hostConfig.networkYaml)) {
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
const nmstate = yamlToNmstateObject(hostConfig.networkYaml);
|
|
140
|
+
for (const networkInterface of nmstate.interfaces) {
|
|
141
|
+
if (isDummyInterface(networkInterface.name)) {
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
hostIps.push(...getIpsFromInterface(networkInterface));
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
return hostIps;
|
|
148
|
+
};
|
|
@@ -2,6 +2,7 @@ export * from './dataTypes';
|
|
|
2
2
|
export * from './fromInfraEnv';
|
|
3
3
|
export * from './emptyData';
|
|
4
4
|
export * from './formDataToInfraEnvField';
|
|
5
|
+
export * from './disconnectedNetworkWide';
|
|
5
6
|
export * from './dummyData';
|
|
6
7
|
export * from './protocolVersion';
|
|
7
8
|
export * from './machineNetwork';
|