Skip to content

Instantly share code, notes, and snippets.

@elucify
Last active March 16, 2019 05:00
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save elucify/66b0af4c8e66e590b81351e60f11d244 to your computer and use it in GitHub Desktop.
Save elucify/66b0af4c8e66e590b81351e60f11d244 to your computer and use it in GitHub Desktop.
Upload ssh key to TeamCity server; works for version 2018.1.1 (build 58406).
#!/bin/bash
#
# Upload an SSH private key to a TeamCity project
# See https://youtrack.jetbrains.com/issue/TW-42311
# License: Public domain. No warranty expressed or implied. Use at own risk.
#
# Environment
#
# Must set environment variable TEAMCITY_SERVER_URL to https://<teamcity-hostname>. That
# URL may not return 3xx redirects
#
# TEAMCITY_USER: if not set, uses `whoami`
# TEAMCITY_PASSWORD: if not set, prompts at stdin
#
# Inputs:
# $1 - TeamCity external project ID
# $2 - Filename of SSH private key
# [$3] - Name of key in TeamCity (optional, default is $2)
#
die() {
echo $1 1>&2
exit 1
}
usage() {
die "Usage: $0 tc-project-id private-key-filename [private-key-name]"
}
check_vars() {
for var in $*; do
[ -z "${!var}" ] && die "$var not set or empty"
done
}
# Set global input variables
set_inputs() {
EXTERNAL_PROJECT_ID=$1
PRIVATE_KEY_FILENAME=$2
PRIVATE_KEY_NAME=${3:-$PRIVATE_KEY_FILENAME}
TEAMCITY_USER=${TEAMCITY_USER:-$(whoami)}
[ -z "${TEAMCITY_PASSWORD}" ] && read -p Password: -s TEAMCITY_PASSWORD
check_vars TEAMCITY_USER TEAMCITY_PASSWORD EXTERNAL_PROJECT_ID PRIVATE_KEY_FILENAME \
PRIVATE_KEY_NAME TEAMCITY_SERVER_URL
INTERNAL_PROJECT_ID=$(get_project_id)
[ -z ${INTERNAL_PROJECT_ID} ] && die "Failed to get internal project id"
}
find_project_id() {
# Given source of ssh-keys form, find hidden input with project id
sed -e '/hidden.*projectId.*value="[^"]/!d' -e 's/.*value="\(..*\)".*/\1/'
}
fetch_project_page() {
# Get project ID from ssh-keys form, so we can POST it back
local url="${TEAMCITY_SERVER_URL}/admin/editProject.html?projectId=${EXTERNAL_PROJECT_ID}&tab=ssh-manager"
curl -s --fail -u "${TEAMCITY_USER}:${TEAMCITY_PASSWORD}" $url
[ $? -ne 0 ] && die "$url: curl exit status $?, see \$ man curl"
}
fetch_project_id() {
local url="${TEAMCITY_SERVER_URL}/app/rest/projects/${EXTERNAL_PROJECT_ID}/internalId"
local project_id=$(curl -s -u "${TEAMCITY_USER}:${TEAMCITY_PASSWORD}" $url)
echo $project_id
}
get_project_id() {
fetch_project_id
# If using an earlier version of TeamCity that doesn't support the
# URL /app/rest/projects/<project-id>/internalId, you can get it from the
# text of the ssh-keys page; comment out the line above, and uncomment the
# line below.
# fetch_project_page | find_project_id
}
check_push_error() {
local result=$(sed -e '/Dialog\.error/!d' -e 's/.*SshKeysDialog.error("//' -e 's/".*//')
[ "$result" ] && die "$result"
}
do_push() {
local url="${TEAMCITY_SERVER_URL}/admin/sshKeys.html"
curl -s --fail -X POST -u ${TEAMCITY_USER}:${TEAMCITY_PASSWORD} \
-F "file:fileToUpload=@${PRIVATE_KEY_FILENAME}" \
-F "fileName=${PRIVATE_KEY_NAME}" \
-F "projectId=${INTERNAL_PROJECT_ID}" \
-F "action=createSshKey" \
$url || die "$url: curl exit status $?, see \$ man curl"
}
push_private_key() {
do_push | check_push_error
}
#
# Main
#
set_inputs $*
push_private_key
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment