Wizard: Add firewall services

This adds firewall services, using the `<ChippingInput>` components. New tests were also added.
This commit is contained in:
regexowl 2025-01-20 09:29:08 +01:00 committed by Klara Simickova
parent 3c27f68b97
commit 4145157858
7 changed files with 214 additions and 13 deletions

View file

@ -6,13 +6,13 @@ import { useAppSelector } from '../../../../../store/hooks';
import {
addPort,
removePort,
selectPorts,
selectFirewall,
} from '../../../../../store/wizardSlice';
import ChippingInput from '../../../ChippingInput';
import { isPortValid } from '../../../validators';
const PortsInput = () => {
const ports = useAppSelector(selectPorts);
const ports = useAppSelector(selectFirewall).ports;
return (
<FormGroup label="Ports">

View file

@ -0,0 +1,48 @@
import React from 'react';
import { FormGroup } from '@patternfly/react-core';
import { useAppSelector } from '../../../../../store/hooks';
import {
addDisabledFirewallService,
addEnabledFirewallService,
removeDisabledFirewallService,
removeEnabledFirewallService,
selectFirewall,
} from '../../../../../store/wizardSlice';
import ChippingInput from '../../../ChippingInput';
import { isServiceValid } from '../../../validators';
const Services = () => {
const disabledServices = useAppSelector(selectFirewall).services.disabled;
const enabledServices = useAppSelector(selectFirewall).services.enabled;
return (
<>
<FormGroup label="Disabled services">
<ChippingInput
ariaLabel="Add disabled service"
placeholder="Add disabled service"
validator={isServiceValid}
list={disabledServices}
item="Disabled service"
addAction={addDisabledFirewallService}
removeAction={removeDisabledFirewallService}
/>
</FormGroup>
<FormGroup label="Enabled services">
<ChippingInput
ariaLabel="Add enabled service"
placeholder="Add enabled service"
validator={isServiceValid}
list={enabledServices}
item="Enabled service"
addAction={addEnabledFirewallService}
removeAction={removeEnabledFirewallService}
/>
</FormGroup>
</>
);
};
export default Services;

View file

@ -3,6 +3,7 @@ import React from 'react';
import { Text, Form, Title } from '@patternfly/react-core';
import PortsInput from './components/PortsInput';
import Services from './components/Services';
const FirewallStep = () => {
return (
@ -12,6 +13,7 @@ const FirewallStep = () => {
</Title>
<Text>Customize firewall settings for your image.</Text>
<PortsInput />
<Services />
</Form>
);
};

View file

@ -83,7 +83,7 @@ import {
selectHostname,
selectUsers,
selectMetadata,
selectPorts,
selectFirewall,
} from '../../../store/wizardSlice';
import { FileSystemConfigurationType } from '../steps/FileSystem';
import {
@ -345,6 +345,10 @@ function commonRequestToState(
hostname: request.customizations.hostname || '',
firewall: {
ports: request.customizations.firewall?.ports || [],
services: {
enabled: request.customizations.firewall?.services?.enabled || [],
disabled: request.customizations.firewall?.services?.disabled || [],
},
},
};
}
@ -714,15 +718,25 @@ const getLocale = (state: RootState) => {
};
const getFirewall = (state: RootState) => {
const ports = selectPorts(state);
const ports = selectFirewall(state).ports;
const services = selectFirewall(state).services;
if (ports.length === 0) {
return undefined;
} else {
return {
ports: ports,
};
const firewall = {};
if (ports.length > 0) {
Object.assign(firewall, { ports: ports });
}
if (services.enabled.length > 0 || services.disabled.length > 0) {
Object.assign(firewall, {
services: {
enabled: services.enabled.length > 0 ? services.enabled : undefined,
disabled: services.disabled.length > 0 ? services.disabled : undefined,
},
});
}
return Object.keys(firewall).length > 0 ? firewall : undefined;
};
const getCustomRepositories = (state: RootState) => {

View file

@ -135,3 +135,14 @@ export const isKernelArgumentValid = (arg: string) => {
export const isPortValid = (port: string) => {
return /^(\d{1,5}|[a-z]{1,6})(-\d{1,5})?:[a-z]{1,6}$/.test(port);
};
export const isServiceValid = (service: string) => {
// Restraints taken from service name syntax reference
// https://www.rfc-editor.org/rfc/rfc6335#section-5.1
return (
service.length <= 15 &&
/^[a-zA-Z0-9]([a-zA-Z0-9-]*[a-zA-Z0-9])?$/.test(service) &&
!/--/.test(service) && // does not contain more hyphens in a row
/[a-zA-Z]+/.test(service) // contains at least one letter
);
};