diff --git a/app/react/kubernetes/configs/queries/useUpdateK8sConfigMapMutation.ts b/app/react/kubernetes/configs/queries/useUpdateK8sConfigMapMutation.ts index 789e8a3a1..d91781658 100644 --- a/app/react/kubernetes/configs/queries/useUpdateK8sConfigMapMutation.ts +++ b/app/react/kubernetes/configs/queries/useUpdateK8sConfigMapMutation.ts @@ -19,12 +19,27 @@ export function useUpdateK8sConfigMapMutation( const queryClient = useQueryClient(); return useMutation({ mutationFn: ({ - data, + configMap, configMapName, }: { - data: ConfigMap; + configMap: ConfigMap; configMapName: string; - }) => updateConfigMap(environmentId, namespace, configMapName, data), + }) => { + if (!configMap.metadata?.uid) { + return createConfigMap( + environmentId, + namespace, + configMapName, + configMap + ); + } + return updateConfigMap( + environmentId, + namespace, + configMapName, + configMap + ); + }, ...withInvalidate(queryClient, [ configMapQueryKeys.configMaps(environmentId, namespace), ]), @@ -50,3 +65,22 @@ async function updateConfigMap( ); } } + +function createConfigMap( + environmentId: EnvironmentId, + namespace: string, + configMap: string, + data: ConfigMap +) { + try { + return axios.post( + `/endpoints/${environmentId}/kubernetes/api/v1/namespaces/${namespace}/configmaps`, + data + ); + } catch (e) { + throw parseKubernetesAxiosError( + e, + `Unable to create ConfigMap '${configMap}'` + ); + } +} diff --git a/app/react/kubernetes/namespaces/AccessView/AccessDatatable/AccessDatatable.tsx b/app/react/kubernetes/namespaces/AccessView/AccessDatatable/AccessDatatable.tsx index c30a06a31..965348097 100644 --- a/app/react/kubernetes/namespaces/AccessView/AccessDatatable/AccessDatatable.tsx +++ b/app/react/kubernetes/namespaces/AccessView/AccessDatatable/AccessDatatable.tsx @@ -95,7 +95,7 @@ export function AccessDatatable() { configMap ); await updateConfigMapMutation.mutateAsync({ - data: configMapPayload, + configMap: configMapPayload, configMapName: PortainerNamespaceAccessesConfigMap.configMapName, }); notifySuccess('Success', 'Namespace access updated'); diff --git a/app/react/kubernetes/namespaces/AccessView/CreateAccessWidget/CreateAccessWidget.tsx b/app/react/kubernetes/namespaces/AccessView/CreateAccessWidget/CreateAccessWidget.tsx index 3625d373e..032fcb1e5 100644 --- a/app/react/kubernetes/namespaces/AccessView/CreateAccessWidget/CreateAccessWidget.tsx +++ b/app/react/kubernetes/namespaces/AccessView/CreateAccessWidget/CreateAccessWidget.tsx @@ -12,6 +12,8 @@ import { useConfigMap } from '@/react/kubernetes/configs/queries/useConfigMap'; import { useTeams } from '@/react/portainer/users/teams/queries'; import { useUpdateK8sConfigMapMutation } from '@/react/kubernetes/configs/queries/useUpdateK8sConfigMapMutation'; import { notifyError, notifySuccess } from '@/portainer/services/notifications'; +import { Configuration } from '@/react/kubernetes/configs/types'; +import { useCurrentUser } from '@/react/hooks/useUser'; import { Widget, WidgetBody, WidgetTitle } from '@@/Widget'; import { TextTip } from '@@/Tip/TextTip'; @@ -28,6 +30,7 @@ export function CreateAccessWidget() { const { params: { id: namespaceName }, } = useCurrentStateAndParams(); + const { user } = useCurrentUser(); const environmentId = useEnvironmentId(); const isRBACEnabledQuery = useIsRBACEnabled(environmentId); const initialValues: { @@ -75,7 +78,9 @@ export function CreateAccessWidget() { initialValues={initialValues} enableReinitialize validationSchema={validationSchema} - onSubmit={onSubmit} + onSubmit={(values, formikHelpers) => + onSubmit(values, formikHelpers) + } validateOnMount > {(formikProps) => ( @@ -104,10 +109,10 @@ export function CreateAccessWidget() { namespaceAccesses, values.selectedUsersAndTeams, namespaceName, - configMap + configMap ?? newConfigMap(user.Username, user.Id) ); await updateConfigMapMutation.mutateAsync({ - data: configMapPayload, + configMap: configMapPayload, configMapName: PortainerNamespaceAccessesConfigMap.configMapName, }); notifySuccess('Success', 'Namespace access updated'); @@ -117,3 +122,18 @@ export function CreateAccessWidget() { } } } + +function newConfigMap(userName: string, userId: number) { + const configMap: Configuration = { + Type: 1, + UID: '', + Name: PortainerNamespaceAccessesConfigMap.configMapName, + Namespace: PortainerNamespaceAccessesConfigMap.namespace, + Data: { [PortainerNamespaceAccessesConfigMap.accessKey]: '{}' }, + ConfigurationOwner: userName, + ConfigurationOwnerId: `${userId}`, + IsUsed: false, + Yaml: '', + }; + return configMap; +}