fix(gitops): manifest validation warning [EE-6859] (#11664)

pull/11820/head
Ali 2024-05-13 15:09:25 +12:00 committed by GitHub
parent a0ab82b866
commit 55667a878a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 62 additions and 16 deletions

View File

@ -1,7 +1,7 @@
import { IFormController } from 'angular';
import { FormikErrors } from 'formik';
import { GitFormModel } from '@/react/portainer/gitops/types';
import { DeployMethod, GitFormModel } from '@/react/portainer/gitops/types';
import { validateGitForm } from '@/react/portainer/gitops/GitForm';
import { notifyError } from '@/portainer/services/notifications';
import { IAuthenticationService } from '@/portainer/services/types';
@ -26,6 +26,8 @@ export default class GitFormController {
createdFromCustomTemplateId?: number;
deployMethod?: DeployMethod;
/* @ngInject */
constructor(
$async: <T>(fn: () => Promise<T>) => Promise<T>,
@ -67,7 +69,8 @@ export default class GitFormController {
this.errors = await validateGitForm(
this.gitCredentials,
value,
isCreatedFromCustomTemplate
isCreatedFromCustomTemplate,
this.deployMethod
);
if (this.errors && Object.keys(this.errors).length > 0) {
this.gitForm?.$setValidity('gitForm', false, this.gitForm);

View File

@ -6,7 +6,7 @@ import { withUserProvider } from '@/react/test-utils/withUserProvider';
import { GitCredential } from '@/react/portainer/account/git-credentials/types';
import { GitForm, buildGitValidationSchema } from './GitForm';
import { GitFormModel } from './types';
import { DeployMethod, GitFormModel } from './types';
export default {
component: GitForm,
@ -45,7 +45,7 @@ interface Args {
isAdditionalFilesFieldVisible: boolean;
isAuthExplanationVisible: boolean;
isDockerStandalone: boolean;
deployMethod: 'compose' | 'manifest';
deployMethod: DeployMethod;
isForcePullVisible: boolean;
}
@ -73,7 +73,7 @@ export function Primary({
return (
<Formik
initialValues={initialValues}
validationSchema={() => buildGitValidationSchema([], false)}
validationSchema={() => buildGitValidationSchema([], false, 'compose')}
onSubmit={() => {}}
>
{({ values, errors, setValues }) => (

View File

@ -5,7 +5,7 @@ import { useState } from 'react';
import { ComposePathField } from '@/react/portainer/gitops/ComposePathField';
import { RefField } from '@/react/portainer/gitops/RefField';
import { GitFormUrlField } from '@/react/portainer/gitops/GitFormUrlField';
import { GitFormModel } from '@/react/portainer/gitops/types';
import { DeployMethod, GitFormModel } from '@/react/portainer/gitops/types';
import { TimeWindowDisplay } from '@/react/portainer/gitops/TimeWindowDisplay';
import { FormSection } from '@@/form-components/FormSection';
@ -24,7 +24,7 @@ interface Props {
value: GitFormModel;
onChange: (value: Partial<GitFormModel>) => void;
environmentType?: 'DOCKER' | 'KUBERNETES' | undefined;
deployMethod?: 'compose' | 'manifest';
deployMethod?: DeployMethod;
isDockerStandalone?: boolean;
isAdditionalFilesFieldVisible?: boolean;
isForcePullVisible?: boolean;
@ -142,17 +142,24 @@ export function GitForm({
export async function validateGitForm(
gitCredentials: Array<GitCredential>,
formValues: GitFormModel,
isCreatedFromCustomTemplate: boolean
isCreatedFromCustomTemplate: boolean,
deployMethod: DeployMethod = 'compose'
) {
return validateForm<GitFormModel>(
() => buildGitValidationSchema(gitCredentials, isCreatedFromCustomTemplate),
() =>
buildGitValidationSchema(
gitCredentials,
isCreatedFromCustomTemplate,
deployMethod
),
formValues
);
}
export function buildGitValidationSchema(
gitCredentials: Array<GitCredential>,
isCreatedFromCustomTemplate: boolean
isCreatedFromCustomTemplate: boolean,
deployMethod: DeployMethod
): SchemaOf<GitFormModel> {
return object({
RepositoryURL: string()
@ -171,7 +178,9 @@ export function buildGitValidationSchema(
.required('Repository URL is required'),
RepositoryReferenceName: refFieldValidation(),
ComposeFilePathInRepository: string().required(
'Compose file path is required'
deployMethod === 'compose'
? 'Compose file path is required'
: 'Manifest file path is required'
),
AdditionalFiles: array(string().required('Path is required')).default([]),
RepositoryURLValid: boolean().default(false),

View File

@ -52,6 +52,8 @@ export type GitNewCredentialModel = {
export type GitAuthModel = GitCredentialsModel & GitNewCredentialModel;
export type DeployMethod = 'compose' | 'manifest';
export interface GitFormModel extends GitAuthModel {
RepositoryURL: string;
RepositoryURLValid?: boolean;

View File

@ -8,6 +8,7 @@ import { EnvironmentId } from '@/react/portainer/environments/types';
import { useEnvironmentDeploymentOptions } from '@/react/portainer/environments/queries/useEnvironment';
import { useCurrentEnvironment } from '@/react/hooks/useCurrentEnvironment';
import { isKubernetesEnvironment } from '@/react/portainer/environments/utils';
import { DeployMethod } from '@/react/portainer/gitops/types';
import { useInitialValues } from './useInitialValues';
import { FormValues, initialBuildMethods } from './types';
@ -23,10 +24,12 @@ export function CreateForm({
viewType: 'kube' | 'docker' | 'edge';
defaultType: StackType;
}) {
const deployMethod: DeployMethod =
defaultType === StackType.Kubernetes ? 'manifest' : 'compose';
const isEdge = !environmentId;
const router = useRouter();
const mutation = useCreateTemplateMutation();
const validation = useValidation({ viewType });
const validation = useValidation({ viewType, deployMethod });
const buildMethods = useBuildMethods();
const initialValues = useInitialValues({

View File

@ -23,6 +23,10 @@ export function useInitialValues({
const { appTemplateId, type = defaultType } = useAppTemplateParams();
// don't make the file path 'docker-compose.yml' in a kube environment. Keep it empty with the existing 'manifest.yml' placeholder
const initialFilePathInRepository =
type === StackType.Kubernetes ? '' : 'docker-compose.yml';
const {
params: { fileContent = '' },
} = useCurrentStateAndParams();
@ -49,7 +53,7 @@ export function useInitialValues({
RepositoryAuthentication: false,
RepositoryUsername: '',
RepositoryPassword: '',
ComposeFilePathInRepository: 'docker-compose.yml',
ComposeFilePathInRepository: initialFilePathInRepository,
AdditionalFiles: [],
RepositoryURLValid: true,
TLSSkipVerify: false,

View File

@ -10,6 +10,7 @@ import { useGitCredentials } from '@/react/portainer/account/git-credentials/git
import { useCurrentUser } from '@/react/hooks/useUser';
import { useCustomTemplates } from '@/react/portainer/templates/custom-templates/queries/useCustomTemplates';
import { edgeFieldsetValidation } from '@/react/portainer/templates/custom-templates/CreateView/EdgeSettingsFieldset.validation';
import { DeployMethod } from '@/react/portainer/gitops/types';
import { file } from '@@/form-components/yup-file-validation';
import {
@ -22,8 +23,10 @@ import { initialBuildMethods } from './types';
export function useValidation({
viewType,
deployMethod,
}: {
viewType: 'kube' | 'docker' | 'edge';
deployMethod: DeployMethod;
}) {
const { user } = useCurrentUser();
const gitCredentialsQuery = useGitCredentials(user.Id);
@ -58,7 +61,11 @@ export function useValidation({
Git: mixed().when('Method', {
is: git.value,
then: () =>
buildGitValidationSchema(gitCredentialsQuery.data || [], false),
buildGitValidationSchema(
gitCredentialsQuery.data || [],
false,
deployMethod
),
}),
Variables: variablesValidation(),
EdgeSettings: viewType === 'edge' ? edgeFieldsetValidation() : mixed(),
@ -68,6 +75,11 @@ export function useValidation({
viewType,
})
),
[customTemplatesQuery.data, gitCredentialsQuery.data, viewType]
[
customTemplatesQuery.data,
gitCredentialsQuery.data,
viewType,
deployMethod,
]
);
}

View File

@ -6,6 +6,8 @@ import { EnvironmentId } from '@/react/portainer/environments/types';
import { useEnvironmentDeploymentOptions } from '@/react/portainer/environments/queries/useEnvironment';
import { useCurrentEnvironment } from '@/react/hooks/useCurrentEnvironment';
import { isKubernetesEnvironment } from '@/react/portainer/environments/utils';
import { DeployMethod } from '@/react/portainer/gitops/types';
import { StackType } from '@/react/common/stacks/types';
import { CustomTemplate } from '../types';
import { useUpdateTemplateMutation } from '../queries/useUpdateTemplateMutation';
@ -32,10 +34,13 @@ export function EditForm({
const router = useRouter();
const disableEditor = useDisableEditor(isGit);
const mutation = useUpdateTemplateMutation();
const deployMethod: DeployMethod =
template.Type === StackType.Kubernetes ? 'manifest' : 'compose';
const validation = useValidation({
viewType,
isGit,
templateId: template.Id,
deployMethod,
});
const fileContentQuery = useCustomTemplateFile(template.Id);

View File

@ -10,6 +10,7 @@ import { useGitCredentials } from '@/react/portainer/account/git-credentials/git
import { useCurrentUser } from '@/react/hooks/useUser';
import { useCustomTemplates } from '@/react/portainer/templates/custom-templates/queries/useCustomTemplates';
import { edgeFieldsetValidation } from '@/react/portainer/templates/custom-templates/CreateView/EdgeSettingsFieldset.validation';
import { DeployMethod } from '@/react/portainer/gitops/types';
import { CustomTemplate } from '../types';
import { TemplateViewType } from '../useViewType';
@ -18,10 +19,12 @@ export function useValidation({
isGit,
templateId,
viewType,
deployMethod,
}: {
isGit: boolean;
templateId: CustomTemplate['Id'];
viewType: TemplateViewType;
deployMethod: DeployMethod;
}) {
const { user } = useCurrentUser();
const gitCredentialsQuery = useGitCredentials(user.Id);
@ -47,7 +50,11 @@ export function useValidation({
FileContent: string().required('Template is required.'),
Git: isGit
? buildGitValidationSchema(gitCredentialsQuery.data || [], false)
? buildGitValidationSchema(
gitCredentialsQuery.data || [],
false,
deployMethod
)
: mixed(),
Variables: variablesValidation(),
EdgeSettings: viewType === 'edge' ? edgeFieldsetValidation() : mixed(),
@ -64,6 +71,7 @@ export function useValidation({
isGit,
templateId,
viewType,
deployMethod,
]
);
}