diff --git a/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2 b/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2
index e0af1995179..5c55e1fce38 100644
--- a/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2
+++ b/tekton/src/tasks/gitops/gitops-mas-fvt-preparer.yml.j2
@@ -336,6 +336,8 @@ spec:
set -o pipefail
trap '[[ $? -eq 1 ]] && mas must-gather --directory /workspace/mustgather --mas-instance-ids ${MAS_INSTANCE_ID} --extra-namespaces selenium' ERR EXIT
+
+
get_trailing_number() {
local input_string="$1"
local trailing_number=$(echo $input_string | grep -Eo '[0-9]+$')
@@ -552,6 +554,112 @@ spec:
fi
+ echo '
+ # - Automated Initial User Tests
+ # -----------------------------------
+ '
+ # See https://pages.github.ibm.com/maximoappsuite/saas/walkthrough/#automated-creation-of-initial-users for details
+
+ # This test runs twice: once in the core phase and once again in the apps phase (to drive the logic that grants application roles and assigns Manage Security Groups to the initial users):
+ # - The initial_user secret is primed with 2 primary and 2 secondary users with randomised emails
+ # - The ibm-create-initial-users Job that reads the secret and runs creates the users is deleted so ArgoCD resyncs it, causing it to be rerun
+ # - The test passes if the postsyncjobs app that contains the Job becomes healthy again after rerunning the Job
+
+ # The results of the tests are registered with the FVT dashboard under ibm-mas-gitops/initial-users-automation-${LAUNCHER_ID}-${MAS_INSTANCE_ID}
+
+ # Assisted by watsonx Code Assistant
+ get_random_email() {
+ local random_part=$(cat /dev/urandom | tr -dc 'a-zA-Z0-9' | fold -w 16 | head -n 1)
+ echo "${random_part}@example.com"
+ }
+
+ initial_user_test() {
+ # Because some of the functions in gitops_utils call exit 1,
+ # it's important that this function is only called from a subshell
+ # otherwise if it fails it might cause the whole script (and thus the FVT run) to exit
+
+ # Establish the initial_users secret
+ export AVP_TYPE="aws" # required by sm_login (only AWS supported at present)
+ sm_login || return $?
+
+ argocd_login || return $?
+
+ # First check the POSTSYNCJOBS_APP is healthy so we know the initial users job has run already (and so will exist)
+ POSTSYNCJOBS_APP="postsyncjobs.${CLUSTER_NAME}.${MAS_INSTANCE_ID}"
+ check_argo_app_healthy "${POSTSYNCJOBS_APP}" 20 || return $?
+
+ IU_SECRET_NAME="${ACCOUNT_ID}/${CLUSTER_NAME}/${MAS_INSTANCE_ID}/initial_users"
+ IU_SECRET_VALUE="{\"$(get_random_email)\": \"primary,john,smith\", \"$(get_random_email)\": \"primary,jane,doe\", \"$(get_random_email)\": \"secondary,joe,bloggs\", \"$(get_random_email)\": \"secondary,billy,bob\"}"
+ IU_SECRET_TAGS="[{\"Key\": \"source\", \"Value\": \"gitops-mas-fvt-preparer\"}, {\"Key\": \"account\", \"Value\": \"${ACCOUNT_ID}\"}, {\"Key\": \"cluster\", \"Value\": \"${CLUSTER_NAME}\"}]"
+
+ echo "Creating ${IU_SECRET_NAME} secret"
+ sm_update_secret "${IU_SECRET_NAME}" "${IU_SECRET_VALUE}" "${IU_SECRET_TAGS}" || return $?
+
+ # The Job will have already run when MAS Core was installed during the first phase of our FVT process
+ # Since no initial_users secret existed at that time, it will not have done anything
+ # The only way to get it to rerun and pick up the new initial_secret is to delete the Job and get ArgoCD to resync
+ # the application that the Job belongs to:
+
+ IU_JOB_LIST=$(oc get jobs -n mas-${MAS_INSTANCE_ID}-postsyncjobs -o jsonpath='{range .items[?(@.spec.template.metadata.labels.app=="ibm-create-initial-users-l")]}{.metadata.name}{"\n"}{end}') || return $?
+ echo "Deleting the following ibm-create-initial-user Jobs in mas-${MAS_INSTANCE_ID}-postsyncjobs namespace:"
+ echo "${IU_JOB_LIST}"
+ echo "${IU_JOB_LIST}"
+ for IU_JOB in $IU_JOB_LIST; do
+ oc delete job "${IU_JOB}" -n mas-${MAS_INSTANCE_ID}-postsyncjobs || return $?
+ done
+
+ # Force a resync of the postsyncjobs app
+ echo "Forcing ${POSTSYNCJOBS_APP} to resync"
+ argocd_sync "${POSTSYNCJOBS_APP}" || return $?
+ check_argo_app_healthy "${POSTSYNCJOBS_APP}" 20 || return $?
+ }
+
+
+ IU_SYNC_START_TIME=$(date +%s)
+ IU_SYNC_LOGS="$(initial_user_test 2>&1 | tee /dev/fd/2)"
+ IU_RC=$? # NOTE: set -o pipefail ensures we get exit code of initial_user_test (not tee)
+ IU_SYNC_LOGS_CDATA=$(printf '%s\n' "${IU_SYNC_LOGS}"| sed 's|\]\]>|]]]]>|g') # guard against any "]]>" in the output
+ IU_SYNC_ELAPSED_TIME=$(($(date +%s)-$IU_SYNC_START_TIME))
+
+ if [[ "${IU_RC}" == "0" ]]; then
+ IU_TEST_RESULT_XML='
+
+
+
+
+
+ '
+ else
+ IU_TEST_RESULT_XML='
+
+
+
+
+
+
+
+ '
+ fi
+
+
+
+ # Create junit xml for one testsuite of the parent argo app, and the testcase of sync
+ # DEVOPS_MONGO_URI=
+ # DEVOPS_ENVIRONMENT=
+ # DEVOPS_BUILD_NUMBER=
+ export DEVOPS_SUITE_NAME="initial-users-automation-${LAUNCHER_ID}-${MAS_INSTANCE_ID}"
+ export JUNIT_OUTPUT_DIR="/tmp/initial-users-automation-${LAUNCHER_ID}-${MAS_INSTANCE_ID}"
+ export PRODUCT_ID="ibm-mas-gitops"
+
+ mkdir -p $JUNIT_OUTPUT_DIR
+ echo ${IU_TEST_RESULT_XML} > $JUNIT_OUTPUT_DIR/output.xml
+
+ echo "Run save-junit-to-mongo.py"
+ python3 /opt/app-root/src/save-junit-to-mongo.py
+ # -----------------------------------
+
echo "Sleeping for 180 seconds to give postsync job a chance to run before creating sync window"
sleep 180