diff --git a/src/scripts/config/mlz_config_create.sh b/src/scripts/config/mlz_config_create.sh index 6ad605a92..4a388d2ad 100755 --- a/src/scripts/config/mlz_config_create.sh +++ b/src/scripts/config/mlz_config_create.sh @@ -20,46 +20,6 @@ usage() { error_log "usage: mlz_config_create.sh " } -sp_exists () { - - sp_name=$1 - sp_property=$2 - - sp_query="az ad sp show \ - --id http://${sp_name} \ - --query ${sp_property}" - - if ! $sp_query &> /dev/null; then - - sleep_time_in_seconds=10 - max_wait_in_minutes=3 - max_wait_in_seconds=180 - max_retries=$((max_wait_in_seconds/sleep_time_in_seconds)) - - echo "INFO: maximum time to wait in seconds = ${max_wait_in_seconds}" - echo "INFO: maximum number of retries = ${max_retries}" - - count=1 - - while ! $sp_query &> /dev/null - do - - echo "INFO: waiting for service principal ${sp_name} to populate property ${sp_property} (${count}/${max_retries})" - echo "INFO: trying again in ${sleep_time_in_seconds} seconds..." - sleep "${sleep_time_in_seconds}" - - if [[ ${count} -eq max_retries ]]; then - error_log "ERROR: unable to determine ${sp_property} for the service principal ${sp_property} in ${max_wait_in_minutes} minutes. Investigate and re-run script." - exit 1 - fi - - count=$((count +1)) - - done - fi - -} - if [[ "$#" -lt 1 ]]; then usage exit 1 @@ -93,6 +53,64 @@ do fi done +# accomodate for transient behavior where Service Principal is created +# but an immediate query for it will fail +# and attempt for max_wait_in_seconds before giving up. +wait_for_sp_creation() { + sp_name=$1 + sp_query="az ad sp show --id ${sp_name}" + + sleep_time_in_seconds=10 + max_wait_in_seconds=180 + max_retries=$((max_wait_in_seconds/sleep_time_in_seconds)) + + count=1 + + while ! $sp_query &> /dev/null + do + echo "INFO: waiting for service principal ${sp_name} to come back from query '${sp_query}' (${count}/${max_retries})..." + echo "INFO: trying again in ${sleep_time_in_seconds} seconds..." + sleep "${sleep_time_in_seconds}" + + if [[ ${count} -eq max_retries ]]; then + error_log "ERROR: unable to retrieve the service principal ${sp_name} from query '${sp_query}' in ${max_wait_in_seconds} seconds. Investigate and re-run script." + exit 1 + fi + + count=$((count +1)) + done +} + +# accomodate for transient behavior where Service Principal is created +# but an immediate query for its properties will fail +# and attempt for max_wait_in_seconds before giving up. +wait_for_sp_property() { + sp_name=$1 + sp_property=$2 + + query="az ad sp show --id ${sp_name} --query ${sp_property} --output tsv" + + sleep_time_in_seconds=10 + max_wait_in_seconds=180 + max_retries=$((max_wait_in_seconds/sleep_time_in_seconds)) + + count=1 + + while [[ -z $($query) ]] + do + echo "INFO: waiting for query \"${query}\" to return results (${count}/${max_retries})" + echo "INFO: trying again in ${sleep_time_in_seconds} seconds..." + sleep "${sleep_time_in_seconds}" + + if [[ ${count} -eq max_retries ]]; then + error_log "ERROR: unable to get results from query \"${query}\" in ${max_wait_in_seconds} seconds. Investigate and re-run script." + exit 1 + fi + + count=$((count +1)) + done +} + # Create Azure AD application registration and Service Principal # TODO: Lift the subscription scoping out of here and move into conditional echo "INFO: verifying service principal ${mlz_sp_name} is unique..." @@ -105,22 +123,14 @@ if [[ -z $(az ad sp list --filter "displayName eq '${mlz_sp_name}'" --query "[]. --only-show-errors \ --output tsv) - # Get Service Principal AppId - # Added the sleep below to accomodate for the transient behavior where the Service Principal creation - # is complete but an immediate query for it will fail. The sleep loop will run for 3 minutes and then - # the script will exit due to a platform problem - sp_exists "${mlz_sp_name}" "appId" + wait_for_sp_creation "http://${mlz_sp_name}" + wait_for_sp_property "http://${mlz_sp_name}" "appId" + wait_for_sp_property "http://${mlz_sp_name}" "objectId" sp_clientid=$(az ad sp show \ - --id "http://${mlz_sp_name}" \ - --query appId \ - --output tsv) - - # Get Service Principal ObjectId - # Added the sleep below to accomodate for the transient behavior where the Service Principal creation - # is complete but an immediate query for it will fail. The sleep loop will run for 3 minutes and then - # the script will exit due to a platform problem - sp_exists "${mlz_sp_name}" "objectId" + --id "http://${mlz_sp_name}" \ + --query appId \ + --output tsv) sp_objid=$(az ad sp show \ --id "http://${mlz_sp_name}" \ diff --git a/src/scripts/container-registry/add_auth_scopes.sh b/src/scripts/container-registry/add_auth_scopes.sh index 9c18347e4..4ae489f06 100755 --- a/src/scripts/container-registry/add_auth_scopes.sh +++ b/src/scripts/container-registry/add_auth_scopes.sh @@ -37,17 +37,51 @@ required_resources_json_file="$(dirname "$(realpath "${BASH_SOURCE%/*}")")/confi # generate app registration echo "INFO: creating app registration ${mlz_fe_app_name} to facilitate user logon at ${fqdn}..." -client_id=$(az ad app create \ +az ad app create \ --display-name "${mlz_fe_app_name}" \ --reply-urls "http://${fqdn}/redirect" \ --required-resource-accesses "${required_resources_json_file}" \ - --query appId \ - --output tsv) -client_password=$(az ad app credential reset \ - --id ${client_id} \ - --query password \ --only-show-errors \ - --output tsv) + --output none + +# wait_for_query_success will attempt the query passed by argument +# if the query does not return a result within max_wait_in_seconds it will exit. +wait_for_query_success() { + query=$1 + + sleep_time_in_seconds=10 + max_wait_in_seconds=180 + max_retries=$((max_wait_in_seconds/sleep_time_in_seconds)) + + count=1 + + while [[ -z $($query) ]] + do + echo "INFO: waiting for query \"${query}\" to return results (${count}/${max_retries})" + echo "INFO: trying again in ${sleep_time_in_seconds} seconds..." + sleep "${sleep_time_in_seconds}" + + if [[ ${count} -eq max_retries ]]; then + error_log "ERROR: unable to get results from query \"${query}\" in ${max_wait_in_seconds} seconds. Investigate and re-run script." + exit 1 + fi + + count=$((count +1)) + done +} + +# use `wait_for_query_success` to accomodate transient failures where +# app creation completes but an immediate query for it will fail +app_id_query="az ad app list --display-name ${mlz_fe_app_name} --query [].appId --output tsv" +wait_for_query_success "$app_id_query" + +client_id=$($app_id_query) + +client_password=$(az ad app credential reset \ + --id ${client_id} \ + --query password \ + --only-show-errors \ + --output tsv) # update keyvault with the app registration information echo "INFO: storing app registration information for client ID ${client_id} in ${mlz_kv_name}..." diff --git a/src/scripts/setup_ezdeploy.sh b/src/scripts/setup_ezdeploy.sh index 3884ce964..30966cd54 100755 --- a/src/scripts/setup_ezdeploy.sh +++ b/src/scripts/setup_ezdeploy.sh @@ -44,7 +44,6 @@ usage() { timestamp=$(date +%s) metadata_host="management.azure.com" # TODO (20210401): pass this by parameter or derive from cloud -acr_endpoint="azurecr.io" # TODO (20210401): pass this by parameter or derive from cloud # set helpful defaults that can be overridden or 'notset' for mandatory input docker_strategy="build" @@ -166,8 +165,8 @@ if [[ $docker_strategy == "load" ]]; then docker load -i mlz.tar fi -docker tag "${image_name}:${image_tag}" "${mlz_acr_name}.${acr_endpoint}/${image_name}:${image_tag}" -docker push "${mlz_acr_name}.${acr_endpoint}/${image_name}:${image_tag}" +docker tag "${image_name}:${image_tag}" "${mlz_acr_name}${mlz_acrLoginServerEndpoint}/${image_name}:${image_tag}" +docker push "${mlz_acr_name}${mlz_acrLoginServerEndpoint}/${image_name}:${image_tag}" # deploy an instance "${container_registry_path}/deploy_instance.sh" "$mlz_config_file" "$image_name" "$image_tag"