Skip to content

Instantly share code, notes, and snippets.

@giannivh
Forked from unguiculus/keycloak_impex.sh
Last active September 18, 2020 06:57
Show Gist options
  • Star 6 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save giannivh/6826b39f9813b72bb5cf414db332c04b to your computer and use it in GitHub Desktop.
Save giannivh/6826b39f9813b72bb5cf414db332c04b to your computer and use it in GitHub Desktop.
Import/Export Keycloak Config running on Kubernetes
#!/usr/bin/env bash
set -e
set -u
set -o pipefail
show_help() {
cat << EOF
Usage: $(basename "$0") <options>
-h, --help Display help
-v, --verbose Display verbose output
-n, --namespace The namespace Keycloak runs in (default: dev)
-a, --action The action to perform (import|export)
-d, --dir The json file to import from or export to (default: impex)
-p, --pod The pod name prefix (default: keycloak)
EOF
}
main() {
local verbose=
local action=
local namespace=dev
local dir=impex
local pod=keycloak
while :; do
case "${1:-}" in
-h|--help)
show_help
exit
;;
-v|--verbose)
verbose=true
;;
-a|--action)
case "${2:-}" in
import|export)
action="$2"
shift
;;
*)
echo "ERROR: '-a|--action' does not match (import|export)." >&2
show_help
exit 1
;;
esac
;;
-n|--namespace)
if [ -n "${2:-}" ]; then
namespace="$2"
shift
else
echo "ERROR: '-n|--namespace' cannot be empty." >&2
show_help
exit 1
fi
;;
-d|--dir)
if [ -n "${2:-}" ]; then
dir="$2"
shift
else
echo "ERROR: '-d|--dir' cannot be empty." >&2
show_help
exit 1
fi
;;
-p|--pod)
if [ -n "${2:-}" ]; then
pod="$2"
shift
else
echo "ERROR: '-p|--pod' cannot be empty." >&2
show_help
exit 1
fi
;;
*)
break
;;
esac
shift
done
if [[ -z "$action" ]]; then
echo "ERROR: '-a|--action' is required." >&2
show_help
exit 1
fi
[[ -n "$verbose" ]] && set -x
impex "$namespace" "$action" "$dir" "$pod"
}
impex() {
local namespace="$1"
local action="$2"
local dir="$3"
local pod="$4"
local server_dir
server_dir="/opt/jboss/$(basename "$dir")"
local log_file
log_file="/opt/jboss/$action.log"
# shellcheck disable=SC2064
trap "cleanup '$namespace' '$server_dir' '$log_file' '$pod'" EXIT
if [[ "$action" == 'import' ]]; then
echo "Copying '$dir' to Keycloak container..."
kubectl cp --namespace "$namespace" "$dir" "$pod-0:$server_dir"
fi
local cmd
cmd=$(create_impex_cmd "$namespace" "$action" "$dir" "$server_dir")
kubectl exec --namespace "$namespace" "$pod-0" -- sh -c "$cmd"
echo "Copying '$action.log' from container..."
kubectl cp --namespace "$namespace" "$pod-0:$log_file" .
if [[ "$action" == 'export' ]]; then
echo "Copying '$dir' from Keycloak container..."
kubectl cp --namespace "$namespace" "$pod-0:$server_dir" "$dir"
fi
}
create_impex_cmd() {
local namespace="$1"
local action="$2"
local dir="$3"
local server_dir="$4"
cat << EOF
# Start up non-HA Keycloak for impex only using different ports
echo "Starting up Keycloak $action instance..."
# JAVA_OPTS configures the heap. If we reuse this here we get an additional container
# with the same amount of heap. The pod would get OOMKilled.
unset JAVA_OPTS
/opt/jboss/keycloak/bin/standalone.sh \
-Dkeycloak.migration.action="$action" \
-Dkeycloak.migration.dir="$server_dir" \
-Dkeycloak.migration.strategy=OVERWRITE_EXISTING \
-Dkeycloak.migration.usersExportStrategy=SAME_FILE \
-Djboss.http.port=8888 \
-Djboss.https.port=9999 \
-Djboss.management.http.port=7777 > "$action.log" &
pid="\$!"
echo "Waiting for Keycloak $action instance to start up..."
until grep 'Deployed "keycloak-server.war"' "$action.log" ; do
printf '.'
sleep 1
done
echo '✓'
echo "Shutting down Keycloak $action instance..."
kill "\$pid"
EOF
}
cleanup() {
local namespace="$1"
local server_dir="$2"
local log_file="$3"
local pod="$4"
echo 'Performing clean-up...'
kubectl exec --namespace "$namespace" "$pod-0" -- rm -rf "$server_dir" "$log_file"
echo 'Done.'
}
main "$@"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment