fix(container): hide capabilities tab EE-6258 (#10540)

pull/10541/head
cmeng 2023-10-26 15:44:31 +13:00 committed by GitHub
parent 403fdf7ce3
commit 3964852fda
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 58 additions and 34 deletions

View File

@ -7,6 +7,7 @@ export interface Option<T extends string | number = string> {
label: ReactNode;
children?: ReactNode;
id: T;
hidden?: boolean;
}
interface Props<T extends string | number> {
@ -33,31 +34,34 @@ export function NavTabs<T extends string | number = string>({
<ul
className={clsx('nav', `nav-${type}`, { 'nav-justified': justified })}
>
{options.map((option) => (
<li
className={clsx({
active: option.id === selectedId,
[styles.parent]: !option.children,
disabled,
})}
key={option.id}
>
{/* rule disabled because `nav-tabs` requires an anchor */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a
onClick={() => handleSelect(option)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
handleSelect(option);
}
}}
role="button"
tabIndex={0}
>
{option.label}
</a>
</li>
))}
{options.map(
(option) =>
!option.hidden && (
<li
className={clsx({
active: option.id === selectedId,
[styles.parent]: !option.children,
disabled,
})}
key={option.id}
>
{/* rule disabled because `nav-tabs` requires an anchor */}
{/* eslint-disable-next-line jsx-a11y/anchor-is-valid */}
<a
onClick={() => handleSelect(option)}
onKeyDown={(e) => {
if (e.key === 'Enter' || e.key === ' ') {
handleSelect(option);
}
}}
role="button"
tabIndex={0}
>
{option.label}
</a>
</li>
)
)}
</ul>
{selected && selected.children && (
<div className="tab-content mt-3">{selected.children}</div>

View File

@ -5,16 +5,19 @@ import { Values } from './CapabilitiesTab';
export function toRequest(
oldConfig: CreateContainerRequest,
values: Values
values: Values,
hideCapabilities: boolean
): CreateContainerRequest {
return {
...oldConfig,
HostConfig: {
...oldConfig.HostConfig,
CapAdd: values,
CapDrop: capabilities
.filter((cap) => !values.includes(cap.key))
.map((cap) => cap.key),
CapAdd: hideCapabilities ? [] : values,
CapDrop: hideCapabilities
? []
: capabilities
.filter((cap) => !values.includes(cap.key))
.map((cap) => cap.key),
},
};
}

View File

@ -2,7 +2,7 @@ import { Formik } from 'formik';
import { useRouter } from '@uirouter/react';
import { useEffect, useState } from 'react';
import { useCurrentUser } from '@/react/hooks/useUser';
import { useCurrentUser, useIsEnvironmentAdmin } from '@/react/hooks/useUser';
import { useEnvironmentId } from '@/react/hooks/useEnvironmentId';
import { useCurrentEnvironment } from '@/react/hooks/useCurrentEnvironment';
import { useEnvironmentRegistries } from '@/react/portainer/environments/queries/useEnvironmentRegistries';
@ -48,6 +48,7 @@ function CreateForm() {
const router = useRouter();
const { trackEvent } = useAnalytics();
const { isAdmin } = useCurrentUser();
const isEnvironmentAdmin = useIsEnvironmentAdmin();
const [isDockerhubRateLimited, setIsDockerhubRateLimited] = useState(false);
const mutation = useCreateOrReplaceMutation();
@ -79,6 +80,10 @@ function CreateForm() {
const environment = envQuery.data;
const hideCapabilities =
!environment.SecuritySettings.allowContainerCapabilitiesForRegularUsers &&
!isEnvironmentAdmin;
const {
isDuplicating = false,
initialValues,
@ -112,6 +117,7 @@ function CreateForm() {
validationSchema={validationSchema}
>
<InnerForm
hideCapabilities={hideCapabilities}
onChangeName={syncName}
isDuplicate={isDuplicating}
isLoading={mutation.isLoading}
@ -136,7 +142,7 @@ function CreateForm() {
}
const registry = getRegistry(values.image, registriesQuery.data || []);
const config = toRequest(values, registry);
const config = toRequest(values, registry, hideCapabilities);
mutation.mutate(
{ config, environment, values, registry, oldContainer, extraNetworks },

View File

@ -24,11 +24,13 @@ import { EnvVarsTab } from './EnvVarsTab';
import { EditResourcesForm } from './ResourcesTab/EditResourceForm';
export function InnerForm({
hideCapabilities = false,
isLoading,
isDuplicate,
onChangeName,
onRateLimit,
}: {
hideCapabilities: boolean;
isDuplicate: boolean;
isLoading: boolean;
onChangeName: (value: string) => void;
@ -202,6 +204,7 @@ export function InnerForm({
{
id: 'capabilities',
label: 'Capabilities',
hidden: hideCapabilities,
children: (
<CapabilitiesTab
values={values.capabilities}

View File

@ -13,7 +13,11 @@ import { restartPolicyTabUtils } from './RestartPolicyTab';
import { envVarsTabUtils } from './EnvVarsTab';
import { Values } from './useInitialValues';
export function toRequest(values: Values, registry?: Registry) {
export function toRequest(
values: Values,
registry?: Registry,
ignoreCapabilities?: boolean
) {
let config: CreateContainerRequest = {
HostConfig: {},
NetworkingConfig: {},
@ -25,7 +29,11 @@ export function toRequest(values: Values, registry?: Registry) {
config = labelsTabUtils.toRequest(config, values.labels);
config = restartPolicyTabUtils.toRequest(config, values.restartPolicy);
config = resourcesTabUtils.toRequest(config, values.resources);
config = capabilitiesTabUtils.toRequest(config, values.capabilities);
config = capabilitiesTabUtils.toRequest(
config,
values.capabilities,
!!ignoreCapabilities
);
config = baseFormUtils.toRequest(config, values);
config = envVarsTabUtils.toRequest(config, values.env);
config.Image = buildImageFullURI(values.image.image, registry);