Skip to content

Commit

Permalink
Merge pull request #768 from SquirrelCorporation/746-bug---selfhosted…
Browse files Browse the repository at this point in the history
…-git-server-certificate-verification-failed

[FEAT] Add support for custom Git environments and SSL error handling.
  • Loading branch information
SquirrelDeveloper authored Feb 22, 2025
2 parents f4f1ae8 + 1a5a8d9 commit 99e8b8a
Show file tree
Hide file tree
Showing 23 changed files with 279 additions and 90 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { capitalizeFirstLetter } from '@/utils/strings';
import {
ProForm,
ProFormCheckbox,
ProFormSelect,
ProFormText,
} from '@ant-design/pro-components';
Expand Down Expand Up @@ -55,20 +56,24 @@ const GitForm: React.FC<GitFormProps> = ({ selectedRecord, repositories }) => (
name={'email'}
label={'Git Email'}
initialValue={selectedRecord?.email}
rules={[{ required: true }]}
rules={[{ required: true }, { type: 'email' }]}
/>
<ProFormText
width={'md'}
name={'userName'}
label={'Git Username'}
initialValue={selectedRecord?.userName}
tooltip={'The username to use when connecting to the remote repository.'}
rules={[{ required: true }]}
/>
<ProFormText
width={'md'}
name={'remoteUrl'}
label={'Remote Url'}
initialValue={selectedRecord?.remoteUrl}
tooltip={
'The remote URL to clone from. E.g: https://github.com/user/repo.git'
}
rules={[
{ required: true },
{ type: 'url' },
Expand All @@ -92,6 +97,7 @@ const GitForm: React.FC<GitFormProps> = ({ selectedRecord, repositories }) => (
name={'branch'}
label={'Branch'}
initialValue={selectedRecord?.branch}
tooltip={'The branch to pull from. E.g: main, develop, master, etc.'}
rules={[{ required: true }]}
/>
<ProFormText.Password
Expand All @@ -100,6 +106,15 @@ const GitForm: React.FC<GitFormProps> = ({ selectedRecord, repositories }) => (
label={'Access Token'}
rules={[{ required: true }]}
/>
<ProFormCheckbox
width={'md'}
name={'ignoreSSLErrors'}
label={'Ignore SSL Errors'}
tooltip={
'Ignore SSL errors when connecting to the remote repository, for example, self-signed certificates.'
}
initialValue={selectedRecord?.ignoreSSLErrors}
/>
</ProForm.Group>
);

Expand Down
2 changes: 1 addition & 1 deletion server/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export const addGitRepository = async (req, res) => {
remoteUrl,
matchesList,
gitService,
ignoreSSLErrors,
}: API.GitContainerStacksRepository = req.body;
await GitRepositoryUseCases.addGitRepository(
name,
Expand All @@ -27,6 +28,7 @@ export const addGitRepository = async (req, res) => {
remoteUrl,
gitService,
matchesList,
ignoreSSLErrors,
);
new SuccessResponse('Added container stacks git repository').send(res);
};
Expand All @@ -51,6 +53,7 @@ export const updateGitRepository = async (req, res) => {
remoteUrl,
matchesList,
gitService,
ignoreSSLErrors,
}: API.GitContainerStacksRepository = req.body;
await GitRepositoryUseCases.updateGitRepository(
uuid,
Expand All @@ -62,6 +65,7 @@ export const updateGitRepository = async (req, res) => {
remoteUrl,
gitService,
matchesList,
ignoreSSLErrors,
);
new SuccessResponse('Updated container stacks git repository').send(res);
};
Expand Down
4 changes: 4 additions & 0 deletions server/src/controllers/rest/playbooks-repository/git.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export const addGitRepository = async (req, res) => {
directoryExclusionList,
gitService,
vaults,
ignoreSSLErrors,
}: API.GitPlaybooksRepository = req.body;
await GitRepositoryUseCases.addGitRepository(
name,
Expand All @@ -30,6 +31,7 @@ export const addGitRepository = async (req, res) => {
gitService,
directoryExclusionList,
vaults,
ignoreSSLErrors,
);
new SuccessResponse('Added playbooks git repository').send(res);
};
Expand Down Expand Up @@ -57,6 +59,7 @@ export const updateGitRepository = async (req, res) => {
directoryExclusionList,
gitService,
vaults,
ignoreSSLErrors,
}: API.GitPlaybooksRepository = req.body;

await GitRepositoryUseCases.updateGitRepository(
Expand All @@ -70,6 +73,7 @@ export const updateGitRepository = async (req, res) => {
gitService,
directoryExclusionList,
vaults,
ignoreSSLErrors,
);
new SuccessResponse('Updated playbooks git repository').send(res);
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export default interface ContainerCustomStackRepository {
onError?: boolean;
onErrorMessage?: string;
gitService: SsmGit.Services;
ignoreSSLErrors?: boolean;
}

const schema = new Schema<ContainerCustomStackRepository>(
Expand Down Expand Up @@ -73,6 +74,10 @@ const schema = new Schema<ContainerCustomStackRepository>(
type: Schema.Types.String,
required: true,
},
ignoreSSLErrors: {
type: Schema.Types.Boolean,
default: false,
},
},
{
timestamps: true,
Expand Down
5 changes: 5 additions & 0 deletions server/src/data/database/model/PlaybooksRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ export default interface PlaybooksRepository {
directory?: string;
enabled: boolean;
default?: boolean;
ignoreSSLErrors?: boolean;
tree?: any;
directoryExclusionList?: string[];
onError?: boolean;
Expand Down Expand Up @@ -107,6 +108,10 @@ const schema = new Schema<PlaybooksRepository>(
type: Schema.Types.String,
required: false,
},
ignoreSSLErrors: {
type: Schema.Types.Boolean,
default: false,
},
vaults: [
{
type: Schema.Types.ObjectId,
Expand Down
11 changes: 6 additions & 5 deletions server/src/helpers/git/clone.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export async function clone(options: {
userInfo?: IGitUserInfos;
}): Promise<void> {
const { dir, remoteUrl, userInfo, logger, defaultGitInfo = defaultDefaultGitInfo } = options;
const { gitUserName, branch, gitService } = userInfo ?? defaultGitInfo;
const { gitUserName, branch, gitService, env } = userInfo ?? defaultGitInfo;
const { accessToken } = userInfo ?? {};

if (accessToken === '' || accessToken === undefined) {
Expand Down Expand Up @@ -57,23 +57,24 @@ export async function clone(options: {
GitStep.PrepareClone,
);
logDebug(`Running git init for clone in dir ${dir}`, GitStep.PrepareClone);
await initGitWithBranch(dir, branch, { initialCommit: false });
const remoteName = await getRemoteName(dir, branch);
await initGitWithBranch(dir, branch, { initialCommit: false, env: env });
const remoteName = await getRemoteName(dir, branch, env);
logDebug(`Successfully Running git init for clone in dir ${dir}`, GitStep.PrepareClone);
logProgress(GitStep.StartConfiguringGithubRemoteRepository);
await credentialOn(dir, remoteUrl, gitUserName, accessToken, remoteName, gitService);
await credentialOn(dir, remoteUrl, gitUserName, accessToken, remoteName, gitService, env);
try {
logProgress(GitStep.StartFetchingFromGithubRemote);
const { stderr: pullStdError, exitCode } = await GitProcess.exec(
['pull', remoteName, `${branch}:${branch}`],
dir,
{ env },
);
if (exitCode === 0) {
logProgress(GitStep.SynchronizationFinish);
} else {
throw new GitPullPushError(options, pullStdError);
}
} finally {
await credentialOff(dir, remoteName, remoteUrl);
await credentialOff(dir, remoteName, remoteUrl, undefined, env);
}
}
49 changes: 34 additions & 15 deletions server/src/helpers/git/commitAndSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,10 +52,10 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi
commitOnly,
} = options;
const { gitUserName, email, branch, gitService } = userInfo ?? defaultGitInfo;
const { accessToken } = userInfo ?? {};
const { accessToken, env } = userInfo ?? {};

const defaultBranchName = (await getDefaultBranchName(dir)) ?? branch;
const remoteName = await getRemoteName(dir, defaultBranchName);
const defaultBranchName = (await getDefaultBranchName(dir, env)) ?? branch;
const remoteName = await getRemoteName(dir, defaultBranchName, env);

const logProgress = (step: GitStep): unknown =>
logger?.info?.(step, {
Expand Down Expand Up @@ -92,8 +92,10 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi
userInfo,
});

await GitProcess.exec(['config', 'user.email', `"${email ?? defaultGitInfo.email}"`], dir);
await GitProcess.exec(['config', `user.name`, `"${gitUserName}"`], dir);
await GitProcess.exec(['config', 'user.email', `"${email ?? defaultGitInfo.email}"`], dir, {
env,
});
await GitProcess.exec(['config', `user.name`, `"${gitUserName}"`], dir, { env });

if (await haveLocalChanges(dir)) {
logProgress(GitStep.HaveThingsToCommit);
Expand All @@ -104,6 +106,8 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi
email ?? defaultGitInfo.email,
commitMessage,
filesToIgnore,
undefined,
env,
);
if (commitExitCode !== 0) {
logWarn(`commit failed ${commitStdError}`, GitStep.CommitComplete);
Expand All @@ -120,13 +124,19 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi
if (remoteUrl === '' || remoteUrl === undefined) {
throw new SyncParameterMissingError('remoteUrl');
}
await credentialOn(dir, remoteUrl, gitUserName, accessToken, remoteName, gitService);
await credentialOn(dir, remoteUrl, gitUserName, accessToken, remoteName, gitService, env);
logProgress(GitStep.FetchingData);
try {
await fetchRemote(dir, remoteName, defaultBranchName);
await fetchRemote(dir, remoteName, defaultBranchName, env);
let exitCode = 0;
let stderr: string | undefined;
const syncStateAfterCommit = await getSyncState(dir, defaultBranchName, remoteName, logger);
const syncStateAfterCommit = await getSyncState(
dir,
defaultBranchName,
remoteName,
logger,
env,
);
switch (syncStateAfterCommit) {
case 'equal': {
logProgress(GitStep.NoNeedToSync);
Expand Down Expand Up @@ -161,6 +171,7 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi
({ exitCode, stderr } = await GitProcess.exec(
['rebase', `${remoteName}/${defaultBranchName}`],
dir,
{ env },
));
logProgress(GitStep.RebaseResultChecking);
if (exitCode !== 0) {
Expand All @@ -171,12 +182,19 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi
}
if (
exitCode === 0 &&
(await getGitRepositoryState(dir, logger)).length === 0 &&
(await getSyncState(dir, defaultBranchName, remoteName, logger)) === 'ahead'
(await getGitRepositoryState(dir, logger, env)).length === 0 &&
(await getSyncState(dir, defaultBranchName, remoteName, logger, env)) === 'ahead'
) {
logProgress(GitStep.RebaseSucceed);
} else {
await continueRebase(dir, gitUserName, email ?? defaultGitInfo.email, logger);
await continueRebase(
dir,
gitUserName,
email ?? defaultGitInfo.email,
logger,
undefined,
env,
);
logProgress(GitStep.RebaseConflictNeedsResolve);
}
await pushUpstream(dir, defaultBranchName, remoteName, userInfo, logger);
Expand All @@ -189,7 +207,7 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi

if (exitCode === 0) {
logProgress(GitStep.PerformLastCheckBeforeSynchronizationFinish);
await assumeSync(dir, defaultBranchName, remoteName, logger);
await assumeSync(dir, defaultBranchName, remoteName, logger, env);
logProgress(GitStep.SynchronizationFinish);
} else {
switch (exitCode) {
Expand All @@ -205,7 +223,7 @@ export async function commitAndSync(options: ICommitAndSyncOptions): Promise<voi
}
} finally {
// always restore original remoteUrl without token
await credentialOff(dir, remoteName, remoteUrl);
await credentialOff(dir, remoteName, remoteUrl, undefined, env);
}
}

Expand All @@ -231,9 +249,9 @@ export async function syncPreflightCheck(configs: {
defaultGitInfo = defaultDefaultGitInfo,
userInfo,
} = configs;
const { gitUserName, email } = userInfo ?? defaultGitInfo;
const { gitUserName, email, env } = userInfo ?? defaultGitInfo;

const repoStartingState = await getGitRepositoryState(dir, logger);
const repoStartingState = await getGitRepositoryState(dir, logger, env);
if (repoStartingState.length === 0 || repoStartingState === '|DIRTY') {
logProgress?.(GitStep.PrepareSync);
logDebug?.(
Expand All @@ -250,6 +268,7 @@ export async function syncPreflightCheck(configs: {
email ?? defaultGitInfo.email,
logger,
repoStartingState,
env,
);
}
}
12 changes: 9 additions & 3 deletions server/src/helpers/git/credential.ts
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ const getUrlWithOutCredential = (urlWithCredential: string): string =>
* @param remoteName
* @param serviceType
* @param domain
* @param env
*/
export async function credentialOn(
directory: string,
Expand All @@ -79,6 +80,7 @@ export async function credentialOn(
accessToken: string,
remoteName: string,
serviceType: SsmGit.Services,
env?: Record<string, string>,
): Promise<void> {
let gitUrlWithCredential;
switch (serviceType) {
Expand Down Expand Up @@ -106,21 +108,25 @@ export async function credentialOn(
throw new Error(`Unknown service type ${serviceType}`);
}
}
await GitProcess.exec(['remote', 'add', remoteName, gitUrlWithCredential], directory);
await GitProcess.exec(['remote', 'set-url', remoteName, gitUrlWithCredential], directory);
await GitProcess.exec(['remote', 'add', remoteName, gitUrlWithCredential], directory, { env });
await GitProcess.exec(['remote', 'set-url', remoteName, gitUrlWithCredential], directory, {
env,
});
}
/**
* Add remote without credential
* @param {string} directory
* @param remoteName
* @param remoteUrl
* @param serviceType
* @param env
*/
export async function credentialOff(
directory: string,
remoteName: string,
remoteUrl?: string,
serviceType = SsmGit.Services.Github,
env?: Record<string, string>,
): Promise<void> {
const gitRepoUrl = remoteUrl ?? (await getRemoteUrl(directory, remoteName));
let gitUrlWithOutCredential: string;
Expand All @@ -137,5 +143,5 @@ export async function credentialOff(
throw new Error(`Unknown service type ${serviceType}`);
}
}
await GitProcess.exec(['remote', 'set-url', remoteName, gitUrlWithOutCredential], directory);
await GitProcess.exec(['remote', 'set-url', remoteName, gitUrlWithOutCredential], directory, env);
}
3 changes: 3 additions & 0 deletions server/src/helpers/git/defaultGitInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,7 @@ export const defaultGitInfo = {
branch: 'main',
remote: 'origin',
gitService: SsmGit.Services.Github,
env: {
GIT_SSL_NO_VERIFY: 'false',
},
};
Loading

0 comments on commit 99e8b8a

Please sign in to comment.