@@ -3,6 +3,8 @@ import React, { useEffect, useState } from 'react';
33import { CheckCircleIcon } from '@patternfly/react-icons' ;
44import { jwtDecode , JwtPayload } from 'jwt-decode' ;
55
6+ import { getListOfDuplicates } from './getListOfDuplicates' ;
7+
68import { UNIQUE_VALIDATION_DELAY } from '../../../constants' ;
79import { useLazyGetBlueprintsQuery } from '../../../store/backendApi' ;
810import { useAppSelector } from '../../../store/hooks' ;
@@ -281,14 +283,26 @@ export function useTimezoneValidation(): StepValidation {
281283 }
282284 }
283285
286+ const duplicateNtpServers = getListOfDuplicates ( ntpServers || [ ] ) ;
287+
284288 const timezoneError =
285289 timezone && ! timezones . includes ( timezone ) ? 'Unknown timezone' : '' ;
286290 const ntpServersError =
287291 invalidServers . length > 0 ? `Invalid NTP servers: ${ invalidServers } ` : '' ;
292+ const duplicateNtpServersError =
293+ duplicateNtpServers . length > 0
294+ ? `Includes duplicate NTP servers: ${ duplicateNtpServers . join ( ', ' ) } `
295+ : '' ;
288296
289297 return {
290- errors : { timezone : timezoneError , ntpServers : ntpServersError } ,
291- disabledNext : timezoneError !== '' || invalidServers . length > 0 ,
298+ errors : {
299+ timezone : timezoneError ,
300+ ntpServers : ntpServersError + '|' + duplicateNtpServersError ,
301+ } ,
302+ disabledNext :
303+ timezoneError !== '' ||
304+ invalidServers . length > 0 ||
305+ duplicateNtpServers . length > 0 ,
292306 } ;
293307}
294308
@@ -363,15 +377,28 @@ export function useKernelValidation(): StepValidation {
363377 }
364378 }
365379
380+ const duplicateKernelArgs = getListOfDuplicates ( kernel . append ) ;
381+
366382 const kernelNameError =
367383 kernel . name && ! isKernelNameValid ( kernel . name ) ? 'Invalid format.' : '' ;
368384
369385 const kernelAppendError =
370386 invalidArgs . length > 0 ? `Invalid kernel arguments: ${ invalidArgs } ` : '' ;
371387
388+ const duplicateKernelArgsError =
389+ duplicateKernelArgs . length > 0
390+ ? `Includes duplicate kernel arguments: ${ duplicateKernelArgs . join ( ', ' ) } `
391+ : '' ;
392+
372393 return {
373- errors : { kernel : kernelNameError , kernelAppend : kernelAppendError } ,
374- disabledNext : kernelNameError !== '' || kernelAppendError !== '' ,
394+ errors : {
395+ kernel : kernelNameError ,
396+ kernelAppend : kernelAppendError + '|' + duplicateKernelArgsError ,
397+ } ,
398+ disabledNext :
399+ kernelNameError !== '' ||
400+ kernelAppendError !== '' ||
401+ duplicateKernelArgs . length > 0 ,
375402 } ;
376403}
377404
@@ -405,8 +432,32 @@ export function useFirewallValidation(): StepValidation {
405432 }
406433 }
407434
435+ const duplicatePorts = getListOfDuplicates ( firewall . ports ) ;
436+ const duplicateDisabledServices = getListOfDuplicates (
437+ firewall . services . disabled
438+ ) ;
439+ const duplicateEnabledServices = getListOfDuplicates (
440+ firewall . services . enabled
441+ ) ;
442+
408443 const portsError =
409444 invalidPorts . length > 0 ? `Invalid ports: ${ invalidPorts } ` : '' ;
445+ const duplicatePortsError =
446+ duplicatePorts . length > 0
447+ ? `Includes duplicate ports: ${ duplicatePorts . join ( ', ' ) } `
448+ : '' ;
449+ const duplicateDisabledServicesError =
450+ duplicateDisabledServices . length > 0
451+ ? `Includes duplicate disabled services: ${ duplicateDisabledServices . join (
452+ ', '
453+ ) } `
454+ : '' ;
455+ const duplicateEnabledServicesError =
456+ duplicateEnabledServices . length > 0
457+ ? `Includes duplicate enabled services: ${ duplicateEnabledServices . join (
458+ ', '
459+ ) } `
460+ : '' ;
410461 const disabledServicesError =
411462 invalidDisabled . length > 0
412463 ? `Invalid disabled services: ${ invalidDisabled } `
@@ -418,14 +469,19 @@ export function useFirewallValidation(): StepValidation {
418469
419470 return {
420471 errors : {
421- ports : portsError ,
422- disabledServices : disabledServicesError ,
423- enabledServices : enabledServicesError ,
472+ ports : portsError + '|' + duplicatePortsError ,
473+ disabledServices :
474+ disabledServicesError + '|' + duplicateDisabledServicesError ,
475+ enabledServices :
476+ enabledServicesError + '|' + duplicateEnabledServicesError ,
424477 } ,
425478 disabledNext :
426479 invalidPorts . length > 0 ||
427480 invalidDisabled . length > 0 ||
428- invalidEnabled . length > 0 ,
481+ invalidEnabled . length > 0 ||
482+ duplicatePorts . length > 0 ||
483+ duplicateDisabledServices . length > 0 ||
484+ duplicateEnabledServices . length > 0 ,
429485 } ;
430486}
431487
@@ -460,6 +516,10 @@ export function useServicesValidation(): StepValidation {
460516 }
461517 }
462518
519+ const duplicateDisabledServices = getListOfDuplicates ( services . disabled ) ;
520+ const duplicateMaskedServices = getListOfDuplicates ( services . masked ) ;
521+ const duplicateEnabledServices = getListOfDuplicates ( services . enabled ) ;
522+
463523 const disabledSystemdServicesError =
464524 invalidDisabled . length > 0
465525 ? `Invalid disabled services: ${ invalidDisabled } `
@@ -470,17 +530,41 @@ export function useServicesValidation(): StepValidation {
470530 invalidEnabled . length > 0
471531 ? `Invalid enabled services: ${ invalidEnabled } `
472532 : '' ;
533+ const duplicateDisabledServicesError =
534+ duplicateDisabledServices . length > 0
535+ ? `Includes duplicate disabled services: ${ duplicateDisabledServices . join (
536+ ', '
537+ ) } `
538+ : '' ;
539+ const duplicateMaskedServicesError =
540+ duplicateMaskedServices . length > 0
541+ ? `Includes duplicate masked services: ${ duplicateMaskedServices . join (
542+ ', '
543+ ) } `
544+ : '' ;
545+ const duplicateEnabledServicesError =
546+ duplicateEnabledServices . length > 0
547+ ? `Includes duplicate enabled services: ${ duplicateEnabledServices . join (
548+ ', '
549+ ) } `
550+ : '' ;
473551
474552 return {
475553 errors : {
476- disabledSystemdServices : disabledSystemdServicesError ,
477- maskedSystemdServices : maskedSystemdServicesError ,
478- enabledSystemdServices : enabledSystemdServicesError ,
554+ disabledSystemdServices :
555+ disabledSystemdServicesError + '|' + duplicateDisabledServicesError ,
556+ maskedSystemdServices :
557+ maskedSystemdServicesError + '|' + duplicateMaskedServicesError ,
558+ enabledSystemdServices :
559+ enabledSystemdServicesError + '|' + duplicateEnabledServicesError ,
479560 } ,
480561 disabledNext :
481562 invalidDisabled . length > 0 ||
482563 invalidMasked . length > 0 ||
483- invalidEnabled . length > 0 ,
564+ invalidEnabled . length > 0 ||
565+ duplicateDisabledServices . length > 0 ||
566+ duplicateMaskedServices . length > 0 ||
567+ duplicateEnabledServices . length > 0 ,
484568 } ;
485569}
486570
@@ -544,20 +628,27 @@ export function useUsersValidation(): UsersStepValidation {
544628 }
545629 }
546630
547- const groupsError =
631+ const duplicateGroups = getListOfDuplicates ( users [ index ] . groups ) ;
632+
633+ const invalidError =
548634 invalidGroups . length > 0 ? `Invalid user groups: ${ invalidGroups } ` : '' ;
635+ const duplicateError =
636+ duplicateGroups . length > 0
637+ ? `Includes duplicate groups: ${ duplicateGroups . join ( ', ' ) } `
638+ : '' ;
549639
550640 if (
551641 userNameError ||
552642 sshKeyError ||
553643 ( users [ index ] . password && ! isPasswordValid ) ||
554- groupsError
644+ invalidError ||
645+ duplicateError
555646 ) {
556- errors [ ` ${ index } ` ] = {
647+ errors [ index ] = {
557648 userName : userNameError ,
558649 userSshKey : sshKeyError ,
559650 userPassword : passwordError ,
560- groups : groupsError ,
651+ groups : invalidError + '|' + duplicateError ,
561652 } ;
562653 }
563654 }
0 commit comments