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