Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update Docker push commands and add checks for App properties #149

Merged
merged 3 commits into from
Apr 13, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
118 changes: 64 additions & 54 deletions src/scripts/config/mlz_config_create.sh
Original file line number Diff line number Diff line change
Expand Up @@ -20,46 +20,6 @@ usage() {
error_log "usage: mlz_config_create.sh <mlz config>"
}

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
Expand Down Expand Up @@ -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..."
Expand All @@ -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}" \
Expand Down
48 changes: 41 additions & 7 deletions src/scripts/container-registry/add_auth_scopes.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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}..."
Expand Down
5 changes: 2 additions & 3 deletions src/scripts/setup_ezdeploy.sh
Original file line number Diff line number Diff line change
Expand Up @@ -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"
Expand Down Expand Up @@ -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"
Expand Down