1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-24 15:59:41 +02:00

refactor(containers): migrate caps tab to react [EE-5215] (#10366)

This commit is contained in:
Chaim Lev-Ari 2023-09-25 19:36:50 +03:00 committed by GitHub
parent 9dde610da3
commit 57e04c3544
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
14 changed files with 324 additions and 190 deletions

View file

@ -0,0 +1,39 @@
import { FormSection } from '@@/form-components/FormSection';
import { SwitchField } from '@@/form-components/SwitchField';
import { capabilities } from './types';
export type Values = string[];
export function CapabilitiesTab({
values,
onChange,
}: {
values: Values;
onChange: (values: Values) => void;
}) {
return (
<FormSection title="Container capabilities">
<div className="form-group flex flex-wrap gap-y-2 px-5">
{capabilities.map((cap) => (
<div key={cap.key} className="w-1/3 text-center">
<SwitchField
labelClass="col-sm-6"
tooltip={cap.description}
checked={values.includes(cap.key)}
label={cap.key}
name={`${cap.key}-capability`}
onChange={(value) => {
if (value) {
onChange([...values, cap.key]);
} else {
onChange(values.filter((v) => v !== cap.key));
}
}}
/>
</div>
))}
</div>
</FormSection>
);
}

View file

@ -0,0 +1,15 @@
import { validation } from './validation';
import { toViewModel, getDefaultViewModel } from './toViewModel';
import { toRequest } from './toRequest';
export {
CapabilitiesTab,
type Values as CapabilitiesTabValues,
} from './CapabilitiesTab';
export const capabilitiesTabUtils = {
toRequest,
toViewModel,
validation,
getDefaultViewModel,
};

View file

@ -0,0 +1,20 @@
import { CreateContainerRequest } from '@/react/docker/containers/CreateView/types';
import { capabilities } from './types';
import { Values } from './CapabilitiesTab';
export function toRequest(
oldConfig: CreateContainerRequest,
values: Values
): CreateContainerRequest {
return {
...oldConfig,
HostConfig: {
...oldConfig.HostConfig,
CapAdd: values,
CapDrop: capabilities
.filter((cap) => !values.includes(cap.key))
.map((cap) => cap.key),
},
};
}

View file

@ -0,0 +1,28 @@
import { ContainerJSON } from '@/react/docker/containers/queries/container';
import { capabilities } from './types';
import { Values } from './CapabilitiesTab';
export function toViewModel(config: ContainerJSON): Values {
const { CapAdd, CapDrop } = getDefaults(config);
const missingCaps = capabilities
.filter(
(cap) =>
cap.default && !CapAdd.includes(cap.key) && !CapDrop.includes(cap.key)
)
.map((cap) => cap.key);
return [...CapAdd, ...missingCaps];
function getDefaults(config: ContainerJSON) {
return {
CapAdd: config.HostConfig?.CapAdd || [],
CapDrop: config.HostConfig?.CapDrop || [],
};
}
}
export function getDefaultViewModel(): Values {
return capabilities.filter((cap) => cap.default).map((cap) => cap.key);
}

View file

@ -0,0 +1,185 @@
export interface Capability {
key: string;
description: string;
default?: boolean;
}
const capDesc: Array<Capability> = [
{
key: 'SETPCAP',
description: 'Modify process capabilities.',
default: true,
},
{
key: 'MKNOD',
description: 'Create special files using mknod(2).',
default: true,
},
{
key: 'AUDIT_WRITE',
description: 'Write records to kernel auditing log.',
default: true,
},
{
key: 'CHOWN',
description: 'Make arbitrary changes to file UIDs and GIDs (see chown(2)).',
default: true,
},
{
key: 'NET_RAW',
description: 'Use RAW and PACKET sockets.',
default: true,
},
{
key: 'DAC_OVERRIDE',
description: 'Bypass file read, write, and execute permission checks.',
default: true,
},
{
key: 'FOWNER',
description:
'Bypass permission checks on operations that normally require the file system UID of the process to match the UID of the file.',
default: true,
},
{
key: 'FSETID',
description:
'Dont clear set-user-ID and set-group-ID permission bits when a file is modified.',
default: true,
},
{
key: 'KILL',
description: 'Bypass permission checks for sending signals.',
default: true,
},
{
key: 'SETGID',
description:
'Make arbitrary manipulations of process GIDs and supplementary GID list.',
default: true,
},
{
key: 'SETUID',
description: 'Make arbitrary manipulations of process UIDs.',
default: true,
},
{
key: 'NET_BIND_SERVICE',
description:
'Bind a socket to internet domain privileged ports (port numbers less than 1024).',
default: true,
},
{
key: 'SYS_CHROOT',
description: 'Use chroot(2), change root directory.',
default: true,
},
{
key: 'SETFCAP',
description: 'Set file capabilities.',
default: true,
},
{
key: 'SYS_MODULE',
description: 'Load and unload kernel modules.',
},
{
key: 'SYS_RAWIO',
description: 'Perform I/O port operations (iopl(2) and ioperm(2)).',
},
{
key: 'SYS_PACCT',
description: 'Use acct(2), switch process accounting on or off.',
},
{
key: 'SYS_ADMIN',
description: 'Perform a range of system administration operations.',
},
{
key: 'SYS_NICE',
description:
'Raise process nice value (nice(2), setpriority(2)) and change the nice value for arbitrary processes.',
},
{
key: 'SYS_RESOURCE',
description: 'Override resource Limits.',
},
{
key: 'SYS_TIME',
description:
'Set system clock (settimeofday(2), stime(2), adjtimex(2)); set real-time (hardware) clock.',
},
{
key: 'SYS_TTY_CONFIG',
description:
'Use vhangup(2); employ various privileged ioctl(2) operations on virtual terminals.',
},
{
key: 'AUDIT_CONTROL',
description:
'Enable and disable kernel auditing; change auditing filter rules; retrieve auditing status and filtering rules.',
},
{
key: 'MAC_ADMIN',
description:
'Allow MAC configuration or state changes. Implemented for the Smack LSM.',
},
{
key: 'MAC_OVERRIDE',
description:
'Override Mandatory Access Control (MAC). Implemented for the Smack Linux Security Module (LSM).',
},
{
key: 'NET_ADMIN',
description: 'Perform various network-related operations.',
},
{
key: 'SYSLOG',
description: 'Perform privileged syslog(2) operations.',
},
{
key: 'DAC_READ_SEARCH',
description:
'Bypass file read permission checks and directory read and execute permission checks.',
},
{
key: 'LINUX_IMMUTABLE',
description: 'Set the FS_APPEND_FL and FS_IMMUTABLE_FL i-node flags.',
},
{
key: 'NET_BROADCAST',
description: 'Make socket broadcasts, and listen to multicasts.',
},
{
key: 'IPC_LOCK',
description: 'Lock memory (mlock(2), mlockall(2), mmap(2), shmctl(2)).',
},
{
key: 'IPC_OWNER',
description:
'Bypass permission checks for operations on System V IPC objects.',
},
{
key: 'SYS_PTRACE',
description: 'Trace arbitrary processes using ptrace(2).',
},
{
key: 'SYS_BOOT',
description:
'Use reboot(2) and kexec_load(2), reboot and load a new kernel for later execution.',
},
{
key: 'LEASE',
description: 'Establish leases on arbitrary files (see fcntl(2)).',
},
{
key: 'WAKE_ALARM',
description: 'Trigger something that will wake up the system.',
},
{
key: 'BLOCK_SUSPEND',
description: 'Employ features that can block system suspend.',
},
];
export const capabilities = capDesc.sort((a, b) => (a.key < b.key ? -1 : 1));

View file

@ -0,0 +1,7 @@
import { array, SchemaOf, string } from 'yup';
import { Values } from './CapabilitiesTab';
export function validation(): SchemaOf<Values> {
return array(string().default('')).default([]);
}