Last active
March 16, 2019 05:00
-
-
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).
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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