1
0
Fork 0
mirror of https://github.com/portainer/portainer.git synced 2025-07-25 00:09:40 +02:00

feat(helm): enhance helm chart install [r8s-341] (#766)

This commit is contained in:
Ali 2025-06-05 13:13:45 +12:00 committed by GitHub
parent caac45b834
commit a9061e5258
29 changed files with 864 additions and 562 deletions

View file

@ -1,103 +0,0 @@
import { useQuery, useQueries } from '@tanstack/react-query';
import { useMemo } from 'react';
import { compact, flatMap } from 'lodash';
import { withGlobalError } from '@/react-tools/react-query';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { useCurrentUser } from '@/react/hooks/useUser';
import { getHelmRepositories } from '../../queries/useHelmChartList';
interface HelmSearch {
entries: Entries;
}
interface Entries {
[key: string]: { version: string }[];
}
export interface ChartVersion {
Repo: string;
Version: string;
}
/**
* Hook to fetch all Helm repositories for the current user
*/
export function useHelmRepositories() {
const { user } = useCurrentUser();
return useQuery(
['helm', 'repositories'],
async () => getHelmRepositories(user.Id),
{
enabled: !!user.Id,
...withGlobalError('Unable to retrieve helm repositories'),
}
);
}
/**
* React hook to get a list of available versions for a chart from specified repositories
*
* @param chart The chart name to get versions for
* @param repositories Array of repository URLs to search in
*/
export function useHelmRepoVersions(
chart: string,
staleTime: number,
repositories: string[] = [],
useCache: boolean = true
) {
// Fetch versions from each repository in parallel as separate queries
const versionQueries = useQueries({
queries: useMemo(
() =>
repositories.map((repo) => ({
queryKey: ['helm', 'repositories', chart, repo, useCache],
queryFn: () => getSearchHelmRepo(repo, chart, useCache),
enabled: !!chart && repositories.length > 0,
staleTime,
...withGlobalError(`Unable to retrieve versions from ${repo}`),
})),
[repositories, chart, staleTime, useCache]
),
});
// Combine the results from all repositories for easier consumption
const allVersions = useMemo(() => {
const successfulResults = compact(versionQueries.map((q) => q.data));
return flatMap(successfulResults);
}, [versionQueries]);
return {
data: allVersions,
isInitialLoading: versionQueries.some((q) => q.isLoading),
isError: versionQueries.some((q) => q.isError),
isFetching: versionQueries.some((q) => q.isFetching),
refetch: () => Promise.all(versionQueries.map((q) => q.refetch())),
};
}
/**
* Get Helm repositories for user
*/
async function getSearchHelmRepo(
repo: string,
chart: string,
useCache: boolean = true
): Promise<ChartVersion[]> {
try {
const { data } = await axios.get<HelmSearch>(`templates/helm`, {
params: { repo, chart, useCache },
});
const versions = data.entries[chart];
return (
versions?.map((v) => ({
Repo: repo,
Version: v.version,
})) ?? []
);
} catch (err) {
throw parseAxiosError(err, 'Unable to retrieve helm repositories for user');
}
}

View file

@ -1,45 +0,0 @@
import { useQueryClient, useMutation } from '@tanstack/react-query';
import axios, { parseAxiosError } from '@/portainer/services/axios';
import { withGlobalError, withInvalidate } from '@/react-tools/react-query';
import { queryKeys as applicationsQueryKeys } from '@/react/kubernetes/applications/queries/query-keys';
import { EnvironmentId } from '@/react/portainer/environments/types';
import { HelmRelease } from '../../types';
export interface UpdateHelmReleasePayload {
namespace: string;
values?: string;
repo?: string;
name: string;
chart: string;
version?: string;
atomic?: boolean;
}
export function useUpdateHelmReleaseMutation(environmentId: EnvironmentId) {
const queryClient = useQueryClient();
return useMutation({
mutationFn: (payload: UpdateHelmReleasePayload) =>
updateHelmRelease(environmentId, payload),
...withInvalidate(queryClient, [
[environmentId, 'helm', 'releases'],
applicationsQueryKeys.applications(environmentId),
]),
...withGlobalError('Unable to uninstall helm application'),
});
}
async function updateHelmRelease(
environmentId: EnvironmentId,
payload: UpdateHelmReleasePayload
) {
try {
const { data } = await axios.post<HelmRelease>(
`endpoints/${environmentId}/kubernetes/helm`,
payload
);
return data;
} catch (err) {
throw parseAxiosError(err, 'Unable to update helm release');
}
}