mirror of https://github.com/portainer/portainer
feat(helm): make the atomic flag optional [r8s-314] (#733)
parent
4ee349bd6b
commit
d49fcd8f3e
|
@ -27,6 +27,7 @@ type installChartPayload struct {
|
|||
Repo string `json:"repo"`
|
||||
Values string `json:"values"`
|
||||
Version string `json:"version"`
|
||||
Atomic bool `json:"atomic"`
|
||||
}
|
||||
|
||||
var errChartNameInvalid = errors.New("invalid chart name. " +
|
||||
|
@ -105,6 +106,7 @@ func (handler *Handler) installChart(r *http.Request, p installChartPayload) (*r
|
|||
Version: p.Version,
|
||||
Namespace: p.Namespace,
|
||||
Repo: p.Repo,
|
||||
Atomic: p.Atomic,
|
||||
KubernetesClusterAccess: clusterAccess,
|
||||
}
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ import { Input } from '@@/form-components/Input';
|
|||
import { CodeEditor } from '@@/CodeEditor';
|
||||
import { FormControl } from '@@/form-components/FormControl';
|
||||
import { WidgetTitle } from '@@/Widget';
|
||||
import { Checkbox } from '@@/form-components/Checkbox';
|
||||
|
||||
import { UpdateHelmReleasePayload } from '../queries/useUpdateHelmReleaseMutation';
|
||||
import { ChartVersion } from '../queries/useHelmRepositories';
|
||||
|
@ -37,7 +38,7 @@ export function UpgradeHelmModal({ values, versions, onSubmit }: Props) {
|
|||
versionOptions[0]?.value;
|
||||
const [version, setVersion] = useState<ChartVersion>(defaultVersion);
|
||||
const [userValues, setUserValues] = useState<string>(values.values || '');
|
||||
|
||||
const [atomic, setAtomic] = useState<boolean>(false);
|
||||
return (
|
||||
<Modal
|
||||
onDismiss={() => onSubmit()}
|
||||
|
@ -88,6 +89,20 @@ export function UpgradeHelmModal({ values, versions, onSubmit }: Props) {
|
|||
data-cy="helm-namespace-input"
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
label="Rollback on failure"
|
||||
tooltip="Enables automatic rollback on failure (equivalent to the helm --atomic flag). It may increase the time to upgrade."
|
||||
inputId="atomic-input"
|
||||
className="[&>label]:!pl-0"
|
||||
size="medium"
|
||||
>
|
||||
<Checkbox
|
||||
id="atomic-input"
|
||||
checked={atomic}
|
||||
data-cy="atomic-checkbox"
|
||||
onChange={(e) => setAtomic(e.target.checked)}
|
||||
/>
|
||||
</FormControl>
|
||||
<FormControl
|
||||
label="User-defined values"
|
||||
inputId="user-values-editor"
|
||||
|
@ -125,6 +140,7 @@ export function UpgradeHelmModal({ values, versions, onSubmit }: Props) {
|
|||
chart: values.chart,
|
||||
repo: version.Repo,
|
||||
version: version.Version,
|
||||
atomic,
|
||||
})
|
||||
}
|
||||
color="primary"
|
||||
|
|
|
@ -218,7 +218,9 @@ describe('HelmEventsDatatable', () => {
|
|||
|
||||
await waitFor(() => {
|
||||
expect(
|
||||
screen.getByText('Events reflect the latest revision only.')
|
||||
screen.getByText(
|
||||
'Only events for resources currently in the cluster will be displayed.'
|
||||
)
|
||||
).toBeInTheDocument();
|
||||
});
|
||||
|
||||
|
|
|
@ -42,7 +42,8 @@ export function HelmEventsDatatable({
|
|||
dataset={eventsQuery.data || []}
|
||||
title={
|
||||
<TextTip inline color="blue" className="!text-xs">
|
||||
Events reflect the latest revision only.
|
||||
Only events for resources currently in the cluster will be
|
||||
displayed.
|
||||
</TextTip>
|
||||
}
|
||||
titleIcon={null}
|
||||
|
|
|
@ -167,9 +167,13 @@ describe('ResourcesTable', () => {
|
|||
);
|
||||
|
||||
// Check that success badge is rendered
|
||||
const successBadge = screen.getByText('MinimumReplicasAvailable');
|
||||
const successBadge = screen.getByText(
|
||||
(content, element) =>
|
||||
content.includes('MinimumReplicasAvailable') &&
|
||||
element !== null &&
|
||||
element.className.includes('bg-success')
|
||||
);
|
||||
expect(successBadge).toBeInTheDocument();
|
||||
expect(successBadge.className).toContain('bg-success');
|
||||
});
|
||||
|
||||
it('should show error badges for failed resources', () => {
|
||||
|
@ -177,8 +181,12 @@ describe('ResourcesTable', () => {
|
|||
expect(screen.getByText('probe-failure-nginx-bad')).toBeInTheDocument();
|
||||
|
||||
// Check for the unhealthy status badge and make sure it has the error styling
|
||||
const errorBadge = screen.getByText('InsufficientPods');
|
||||
const errorBadge = screen.getByText(
|
||||
(content, element) =>
|
||||
content.includes('InsufficientPods') &&
|
||||
element !== null &&
|
||||
element.className.includes('bg-error')
|
||||
);
|
||||
expect(errorBadge).toBeInTheDocument();
|
||||
expect(errorBadge.className).toContain('bg-error');
|
||||
});
|
||||
});
|
||||
|
|
|
@ -59,7 +59,7 @@ export function ResourcesTable() {
|
|||
emptyContentLabel="No resources found"
|
||||
title={
|
||||
<TextTip inline color="blue" className="!text-xs">
|
||||
Resources reflect the latest revision only.
|
||||
Only resources currently in the cluster will be displayed.
|
||||
</TextTip>
|
||||
}
|
||||
disableSelect
|
||||
|
|
|
@ -1,6 +1,20 @@
|
|||
import { Row } from '@tanstack/react-table';
|
||||
|
||||
import { filterHOC } from '@@/datatables/Filter';
|
||||
|
||||
import { ResourceRow } from '../types';
|
||||
|
||||
import { columnHelper } from './helper';
|
||||
|
||||
export const resourceType = columnHelper.accessor((row) => row.resourceType, {
|
||||
header: 'Resource type',
|
||||
id: 'resourceType',
|
||||
meta: {
|
||||
filter: filterHOC('Filter by resource type'),
|
||||
},
|
||||
enableColumnFilter: true,
|
||||
filterFn: (row: Row<ResourceRow>, _: string, filterValue: string[]) =>
|
||||
filterValue.length === 0 ||
|
||||
(!!row.original.resourceType &&
|
||||
filterValue.includes(row.original.resourceType)),
|
||||
});
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import { CellContext } from '@tanstack/react-table';
|
||||
import { CellContext, Row } from '@tanstack/react-table';
|
||||
|
||||
import { StatusBadge } from '@@/StatusBadge';
|
||||
import { filterHOC } from '@@/datatables/Filter';
|
||||
|
||||
import { ResourceRow } from '../types';
|
||||
|
||||
|
@ -10,6 +11,21 @@ export const status = columnHelper.accessor((row) => row.status.label, {
|
|||
header: 'Status',
|
||||
id: 'status',
|
||||
cell: Cell,
|
||||
meta: {
|
||||
filter: filterHOC(
|
||||
'Filter by status',
|
||||
// don't include empty values in the filter options
|
||||
(rows: Row<ResourceRow>[]) =>
|
||||
Array.from(
|
||||
new Set(rows.map((row) => row.original.status.label).filter(Boolean))
|
||||
)
|
||||
),
|
||||
},
|
||||
enableColumnFilter: true,
|
||||
filterFn: (row: Row<ResourceRow>, _: string, filterValue: string[]) =>
|
||||
filterValue.length === 0 ||
|
||||
(!!row.original.status.label &&
|
||||
filterValue.includes(row.original.status.label)),
|
||||
});
|
||||
|
||||
function Cell({ row }: CellContext<ResourceRow, string>) {
|
||||
|
|
|
@ -14,6 +14,7 @@ export interface UpdateHelmReleasePayload {
|
|||
name: string;
|
||||
chart: string;
|
||||
version?: string;
|
||||
atomic?: boolean;
|
||||
}
|
||||
export function useUpdateHelmReleaseMutation(environmentId: EnvironmentId) {
|
||||
const queryClient = useQueryClient();
|
||||
|
|
|
@ -11,6 +11,7 @@ type InstallOptions struct {
|
|||
Wait bool
|
||||
ValuesFile string
|
||||
PostRenderer string
|
||||
Atomic bool
|
||||
Timeout time.Duration
|
||||
KubernetesClusterAccess *KubernetesClusterAccess
|
||||
|
||||
|
|
|
@ -133,7 +133,7 @@ func (hspm *HelmSDKPackageManager) Upgrade(upgradeOpts options.InstallOptions) (
|
|||
func initUpgradeClient(actionConfig *action.Configuration, upgradeOpts options.InstallOptions) (*action.Upgrade, error) {
|
||||
upgradeClient := action.NewUpgrade(actionConfig)
|
||||
upgradeClient.DependencyUpdate = true
|
||||
upgradeClient.Atomic = true
|
||||
upgradeClient.Atomic = upgradeOpts.Atomic
|
||||
upgradeClient.ChartPathOptions.RepoURL = upgradeOpts.Repo
|
||||
upgradeClient.Wait = upgradeOpts.Wait
|
||||
|
||||
|
|
Loading…
Reference in New Issue