Merge pull request #144 from sartography/fix-git-ssh-creds
backend: fix use of SSH private key for git ops
This commit is contained in:
commit
e6e82bd0af
|
@ -55,6 +55,14 @@ if [[ "${SPIFFWORKFLOW_BACKEND_RUN_DATA_SETUP:-}" != "false" ]]; then
|
|||
SPIFFWORKFLOW_BACKEND_FAIL_ON_INVALID_PROCESS_MODELS=false poetry run python bin/save_all_bpmn.py
|
||||
fi
|
||||
|
||||
if [[ -n "${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY:-}" ]]; then
|
||||
if [[ -z "${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH}" ]]; then
|
||||
export SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH=$(mktemp /tmp/ssh_private_key.XXXXXX)
|
||||
fi
|
||||
chmod 600 "${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH}"
|
||||
echo "${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY}" >"${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH}"
|
||||
fi
|
||||
|
||||
# Assure that the the Process Models Directory is initialized as a git repo
|
||||
git init "${SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR}"
|
||||
git config --global --add safe.directory "${SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR}"
|
||||
|
|
|
@ -12,17 +12,9 @@ set -o errtrace -o errexit -o nounset -o pipefail
|
|||
bpmn_models_absolute_dir="$1"
|
||||
git_commit_message="$2"
|
||||
git_branch="$3"
|
||||
git_commit_username="$4"
|
||||
git_commit_email="$5"
|
||||
git_commit_password="$6"
|
||||
|
||||
if [[ -z "${5:-}" ]]; then
|
||||
>&2 echo "usage: $(basename "$0") [bpmn_models_absolute_dir] [git_commit_message] [git_branch] [git_commit_username] [git_commit_email]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
if [[ -z "$git_commit_password" && -z "${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY:-}" ]]; then
|
||||
>&2 echo "ERROR: A git password or SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY must be provided"
|
||||
if [[ -z "${3:-}" ]]; then
|
||||
>&2 echo "usage: $(basename "${0}") [bpmn_models_absolute_dir] [git_commit_message] [git_branch]"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
|
@ -32,38 +24,20 @@ function failed_to_get_lock() {
|
|||
}
|
||||
|
||||
function run() {
|
||||
cd "$bpmn_models_absolute_dir"
|
||||
cd "${bpmn_models_absolute_dir}"
|
||||
git add .
|
||||
|
||||
# https://unix.stackexchange.com/a/155077/456630
|
||||
if [ -z "$(git status --porcelain)" ]; then
|
||||
echo "No changes to commit"
|
||||
else
|
||||
|
||||
git config --local user.name "$git_commit_username"
|
||||
git config --local user.email "$git_commit_email"
|
||||
|
||||
if [[ -n "${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY:-}" ]]; then
|
||||
tmpfile=$(mktemp /tmp/tmp_git.XXXXXX)
|
||||
chmod 600 "$tmpfile"
|
||||
echo "$SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY" >"$tmpfile"
|
||||
export GIT_SSH_COMMAND="ssh -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -i ${tmpfile} -F /dev/null"
|
||||
else
|
||||
PAT="${git_commit_username}:${git_commit_password}"
|
||||
AUTH=$(echo -n "$PAT" | openssl base64 | tr -d '\n')
|
||||
git config --local http.extraHeader "Authorization: Basic $AUTH"
|
||||
fi
|
||||
|
||||
git commit -m "$git_commit_message"
|
||||
git push --set-upstream origin "$git_branch"
|
||||
|
||||
if [[ -z "${SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY:-}" ]]; then
|
||||
git config --unset --local http.extraHeader
|
||||
fi
|
||||
return
|
||||
fi
|
||||
|
||||
git commit -m "${git_commit_message}"
|
||||
git push --set-upstream origin "${git_branch}"
|
||||
}
|
||||
|
||||
exec {lock_fd}>/var/lock/mylockfile || failed_to_get_lock
|
||||
flock --timeout 60 "$lock_fd" || failed_to_get_lock
|
||||
exec {lock_fd}>/var/lock/spiff-workflow-git-lock || failed_to_get_lock
|
||||
flock --timeout 60 "${lock_fd}" || failed_to_get_lock
|
||||
run
|
||||
flock -u "$lock_fd"
|
||||
flock -u "${lock_fd}"
|
||||
|
|
|
@ -96,9 +96,6 @@ SPIFFWORKFLOW_BACKEND_GIT_PUBLISH_CLONE_URL = environ.get(
|
|||
SPIFFWORKFLOW_BACKEND_GIT_COMMIT_ON_SAVE = (
|
||||
environ.get("SPIFFWORKFLOW_BACKEND_GIT_COMMIT_ON_SAVE", default="false") == "true"
|
||||
)
|
||||
SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY = environ.get(
|
||||
"SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY"
|
||||
)
|
||||
SPIFFWORKFLOW_BACKEND_GIT_USERNAME = environ.get("SPIFFWORKFLOW_BACKEND_GIT_USERNAME")
|
||||
SPIFFWORKFLOW_BACKEND_GIT_USER_EMAIL = environ.get(
|
||||
"SPIFFWORKFLOW_BACKEND_GIT_USER_EMAIL"
|
||||
|
@ -106,11 +103,8 @@ SPIFFWORKFLOW_BACKEND_GIT_USER_EMAIL = environ.get(
|
|||
SPIFFWORKFLOW_BACKEND_GITHUB_WEBHOOK_SECRET = environ.get(
|
||||
"SPIFFWORKFLOW_BACKEND_GITHUB_WEBHOOK_SECRET", default=None
|
||||
)
|
||||
SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY = environ.get(
|
||||
"SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY", default=None
|
||||
)
|
||||
SPIFFWORKFLOW_BACKEND_GIT_USER_PASSWORD = environ.get(
|
||||
"SPIFFWORKFLOW_BACKEND_GIT_USER_PASSWORD", default=None
|
||||
SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH = environ.get(
|
||||
"SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH", default=None
|
||||
)
|
||||
|
||||
# Database Configuration
|
||||
|
|
|
@ -94,19 +94,7 @@ class GitService:
|
|||
raise ConfigurationError(
|
||||
"SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR config must be set"
|
||||
)
|
||||
if current_app.config["SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY"]:
|
||||
os.environ["SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY"] = (
|
||||
current_app.config["SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY"]
|
||||
)
|
||||
|
||||
git_username = ""
|
||||
git_email = ""
|
||||
if (
|
||||
current_app.config["SPIFFWORKFLOW_BACKEND_GIT_USERNAME"]
|
||||
and current_app.config["SPIFFWORKFLOW_BACKEND_GIT_USER_EMAIL"]
|
||||
):
|
||||
git_username = current_app.config["SPIFFWORKFLOW_BACKEND_GIT_USERNAME"]
|
||||
git_email = current_app.config["SPIFFWORKFLOW_BACKEND_GIT_USER_EMAIL"]
|
||||
shell_command_path = os.path.join(
|
||||
current_app.root_path, "..", "..", "bin", "git_commit_bpmn_models_repo"
|
||||
)
|
||||
|
@ -115,9 +103,6 @@ class GitService:
|
|||
repo_path_to_use,
|
||||
message,
|
||||
branch_name_to_use,
|
||||
git_username,
|
||||
git_email,
|
||||
current_app.config["SPIFFWORKFLOW_BACKEND_GIT_USER_PASSWORD"],
|
||||
]
|
||||
return cls.run_shell_command_to_get_stdout(shell_command)
|
||||
|
||||
|
@ -169,8 +154,17 @@ class GitService:
|
|||
cls, command: list[str], return_success_state: bool = False
|
||||
) -> Union[subprocess.CompletedProcess[bytes], bool]:
|
||||
"""Run_shell_command."""
|
||||
env = {
|
||||
'GIT_COMMITTER_NAME': current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_USERNAME", "unknown"),
|
||||
'GIT_COMMITTER_EMAIL': current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_USER_EMAIL", "unknown@example.org"),
|
||||
}
|
||||
# SSH authentication can be also provided via gitconfig.
|
||||
ssh_key_path = current_app.config.get("SPIFFWORKFLOW_BACKEND_GIT_SSH_PRIVATE_KEY_PATH")
|
||||
if ssh_key_path is not None:
|
||||
env['GIT_SSH_COMMAND'] = 'ssh -F /dev/null -i %s' % ssh_key_path
|
||||
|
||||
# this is fine since we pass the commands directly
|
||||
result = subprocess.run(command, check=False, capture_output=True) # noqa
|
||||
result = subprocess.run(command, check=False, capture_output=True, env=env) # noqa
|
||||
if return_success_state:
|
||||
return result.returncode == 0
|
||||
|
||||
|
@ -178,9 +172,9 @@ class GitService:
|
|||
stdout = result.stdout.decode("utf-8")
|
||||
stderr = result.stderr.decode("utf-8")
|
||||
raise GitCommandError(
|
||||
f"Failed to execute git command: {command} "
|
||||
f"Stdout: {stdout} "
|
||||
f"Stderr: {stderr} "
|
||||
f"Failed to execute git command: {command}"
|
||||
f"Stdout: {stdout}"
|
||||
f"Stderr: {stderr}"
|
||||
)
|
||||
|
||||
return result
|
||||
|
@ -231,7 +225,7 @@ class GitService:
|
|||
with FileSystemService.cd(
|
||||
current_app.config["SPIFFWORKFLOW_BACKEND_BPMN_SPEC_ABSOLUTE_DIR"]
|
||||
):
|
||||
cls.run_shell_command(["git", "pull"])
|
||||
cls.run_shell_command(["git", "pull", "--rebase"])
|
||||
return True
|
||||
|
||||
@classmethod
|
||||
|
@ -252,11 +246,6 @@ class GitService:
|
|||
git_clone_url = current_app.config[
|
||||
"SPIFFWORKFLOW_BACKEND_GIT_PUBLISH_CLONE_URL"
|
||||
]
|
||||
if git_clone_url.startswith("https://"):
|
||||
git_clone_url = git_clone_url.replace(
|
||||
"https://",
|
||||
f"https://{current_app.config['SPIFFWORKFLOW_BACKEND_GIT_USERNAME']}:{current_app.config['SPIFFWORKFLOW_BACKEND_GIT_USER_PASSWORD']}@",
|
||||
)
|
||||
cmd = ["git", "clone", git_clone_url, destination_process_root]
|
||||
|
||||
cls.run_shell_command(cmd)
|
||||
|
|
Loading…
Reference in New Issue