From 1e770b5ea7d4e6eeb9a7a82296b65770ecae94a6 Mon Sep 17 00:00:00 2001 From: Eric Schoville <eric.schoville@wisc.edu> Date: Fri, 17 Jan 2020 10:26:28 -0600 Subject: [PATCH] Update some files --- .gitignore | 1 + Dockerfile | 37 ++--------- run_agent.sh | 180 ++++++++++++++++++++++++++++++++++++++++++++++----- 3 files changed, 172 insertions(+), 46 deletions(-) diff --git a/.gitignore b/.gitignore index ce391bc..e5a7b59 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ agent_token.txt +credentials.env diff --git a/Dockerfile b/Dockerfile index 97f77da..da3a0a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -5,34 +5,27 @@ FROM ubuntu:18.04 MAINTAINER Eric Schoville <> -# These are build time arguments that must be set in order to build this image. -# We need the Informatica user name and IICS token in order to build this image. # POD and REGION can be inferred from the web URL of your Informatica Cloud site. -# The values for POD and REGION probably need changing for you. +# The values for POD and REGION probably need changing for you. Setting these as +# default for UW-Madison hosted service -ARG USER -ARG POD=usw3 -ARG REGION=dm-us +ENV POD=usw3 +ENV REGION=dm-us # You should be able to download the Secure Agent binary from the following URL without authentication: ARG AGENT_URL="https://${POD}.${REGION}.informaticacloud.com/saas/download/linux64/installer/agent64_install_ng_ext.bin" ARG WORK_DIR=/home/agent/infaagent/apps/agentcore -# Use shell parameter expansion to require arguments for build -# https://stackoverflow.com/questions/38438933/how-to-make-a-build-arg-mandatory-during-docker-build - -# Use buildkit build secrets to pass in the token, so it doesn't get stored in the metadata -# https://docs.docker.com/develop/develop-images/build_enhancements/#new-docker-build-secret-information -RUN : "${USER:?Build argument needs to be set and non-empty.}" && \ # install system tools -apt-get update && apt-get install -y \ +RUN apt-get update && apt-get install -y \ curl \ less \ locales \ locales-all \ sudo \ -unzip +unzip \ +jq # Set the locale, Locale defaults are necessary for agent to operate correctly RUN sed -i -e 's/# en_US.UTF-8 UTF-8/en_US.UTF-8 UTF-8/' /etc/locale.gen && \ @@ -66,20 +59,4 @@ EXPOSE 7080 7443 5432 COPY run_agent.sh . -# Start the agent, sleep for 10 (probably should refactor to use inotify tools or somesuch), -# and then try to configure the agent with the user and the token that is read from the secrets -# file. - -RUN --mount='type=secret,id=agent_token,required,uid=1000' \ -./infaagent startup && \ -sleep 10 && \ -# echo $USER && \ -# cat /run/secrets/agent_token && \ -# echo "$(cat /run/secrets/agent_token)" -./consoleAgentManager.sh configureToken $USER "$(cat /run/secrets/agent_token)" && \ -export EXIT="$(grep -c 'Token is invalid' agentcore.log)" && \ -./infaagent shutdown && \ -sleep 10 && \ -exit $EXIT - CMD [ "./run_agent.sh" ] diff --git a/run_agent.sh b/run_agent.sh index 837aea8..7c68e22 100755 --- a/run_agent.sh +++ b/run_agent.sh @@ -1,5 +1,26 @@ #!/usr/bin/env bash +# Check for required environment variables +exit_code=0 + +if [ -z "$INFORMATICA_USER" ]; then + echo "Required environment variable INFORMATICA_USER is not set, exiting." + exit_code=1 +fi + +if [ -z "$INFORMATICA_PASSWORD" ]; then + echo "Required environment variable INFORMATICA_PASSWORD is not set, exiting." + exit_code=1 +fi + +# Region should be set in the image, because it is needed for file download during the build process +if [ -z "$REGION" ]; then + echo "Required environment variable REGION is not set, exiting." + exit_code=1 +fi + +[ "$exit_code" -eq 1 ] && exit $exit_code + ## this wrapper takes care of running the agent and shutdown gracefully Under Docker #set -x @@ -22,32 +43,159 @@ my_handler() { echo "Stopped Wait Loop" } -prep_term() -{ - unset term_child_pid - trap 'handle_term' TERM INT - # kill the last background process, which is `tail -f /dev/null` and execute the specified handler - trap 'kill ${!}; my_handler' SIGUSR1 - echo 'Termination Handler Ready' +prep_term() { + unset term_child_pid + trap 'handle_term' TERM INT + # kill the last background process, which is `tail -f /dev/null` and execute the specified handler + trap 'kill ${!}; my_handler' SIGUSR1 + echo 'Termination Handler Ready' } handle_term() { - echo "TERM Signal Received. Shutting Down PID $term_child_pid..." - if [ -z "$(pgrep -F $PID_FILE)" ]; then - echoRed "Process $term_child_pid not running"; - exit 143; + echo "TERM Signal Received. Shutting Down PID $term_child_pid..." + if [ -z "$(pgrep -F $PID_FILE)" ]; then + echoRed "Process $term_child_pid not running"; + exit 143; + else + echoGreen "PID $term_child_pid found, shuting down..." + ./infaagent shutdown + echo "Secure Agent Stopped" + exit 143; # 128 + 15 -- SIGTERM + fi +} + +# Login to the API with the provided username and password and get the URL and session id +# so we can check the status of this agent. Read results into Bash array + +echo "Logging in to Informatica API" + +json=$(curl -sS -H "Content-Type: application/json" \ +-H "Accept: application/json" \ +-d "{\"username\":\"${INFORMATICA_USER}\",\"password\":\"${INFORMATICA_PASSWORD}\"}" \ +"https://${REGION}.informaticacloud.com/ma/api/v2/user/login") + +if [ -z "$json" ]; then + echo "No result from API" + exit 1 +fi + +status_code=$(jq -nr "${json}|.statusCode") + +if [ -z "$status_code" ]; then + echo "Error connecting to Informatica API" + echo $json + exit 1 +fi + +result=($(jq -nr "${json}|.serverUrl, .icSessionId")) + +if [ -z "$result" ]; then + echo "Unknown error when querying the API, exiting" + exit 1 +fi + +echo "Successfully logged into the API" + +server_url=${result[0]} +ic_session_id=${result[1]} + +if [ -z ${server_url+x} ]; then + echo "No Server URL set" + exit 1 +else + echo "Server URL: ${server_url}" +fi + +if [ -z ${ic_session_id+x} ]; then + echo "No session id" + exit 1 +fi + + +# Check for the existance of infaagent.ini and see if it has been registered. + +register=true +config_file="conf/infaagent.ini" + +if [ -e "$config_file" ]; then + + echo "Found infaagent.ini" + + agent_id=$(grep -oP '^InfaAgent.Id=\K.+' $config_file) + + # Use expansion to check for null + if [ -n "${agent_id+x}" ]; then + + # Check the registered agent ID to see if it is running or not. + # active seems to be set to true if it has been running recently + # readyToRun means it is up and running + result=($(curl -sS -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -H "icSessionId: ${ic_session_id}" \ + "${server_url}/api/v2/agent/${agent_id}" | jq -r '.active, .readyToRun, .name')) + + if [ -z "${result[0]}" ]; then + + echo "Unable to find agent_id, registering a new agent" + + elif [[ "${result[0]}" = "true" && "${result[1]}" = "true" ]]; then + + echo "Already exists a running agent with the id of ${agent_id}: ${result[1]}, registering a new agent" + else - echoGreen "PID $term_child_pid found, shuting down..." - ./infaagent shutdown - echo "Secure Agent Stopped" - exit 143; # 128 + 15 -- SIGTERM + + #Not running, but exists. This should be the default condition, in which case we would just run the agent + register=false + fi -} + + + else + echo "This looks to be a new agent, registering new agent" + fi + +fi # set shutdown hooks prep_term + # run application ./infaagent startup + +# sleep to allow startup (probably should refactor to use inotify tools or somesuch) +sleep 5 + +if [ "$register" = true ]; then + + echo "Registering a new secure agent" + + # Get a token by calling the API + token=$(curl -sS -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -H "icSessionId: ${ic_session_id}" \ + "${server_url}/api/v2/agent/installerInfo/linux64" | jq -r .installToken) + + if [ -z ${token+x} ]; then + echo "Did not retrieve a token from Informatica, exiting" + exit 1 + fi + + # Register this agent with the USER variable and the TOKEN + ./consoleAgentManager.sh configureToken $INFORMATICA_USER $token | \ + grep -q fails && \ + echo "Unable to register agent" && \ + exit 2 + # export exit_code="$(grep -c 'Token is invalid' agentcore.log)" && \ + +fi + +# Logout of informatica API +curl -sS -H "Content-Type: application/json" \ + -H "Accept: application/json" \ + -H "icSessionId: ${ic_session_id}" \ + -X POST \ + "${server_url}/api/v2/user/logout" + # get agent process id term_child_pid=$(cat $PID_FILE) echoGreen "Secure Agent Starting pid:$term_child_pid" -- GitLab