diff --git a/kcidb/cloud/function.sh b/kcidb/cloud/function.sh index c8e40973..62c0b372 100644 --- a/kcidb/cloud/function.sh +++ b/kcidb/cloud/function.sh @@ -9,25 +9,97 @@ declare _FUNCTION_SH= # The region used to host our Cloud Functions declare -r FUNCTION_REGION="us-central1" +# Add a function's IAM policy binding +# Args: project prefix name member role +function function_iam_policy_binding_deploy() { + declare -r project="$1"; shift + declare -r prefix="$1"; shift + declare -r name="$1"; shift + declare -r member="$1"; shift + declare -r role="$1"; shift + mute gcloud functions add-iam-policy-binding \ + --quiet --project="$project" \ + "${prefix}${name}" \ + --region="$FUNCTION_REGION" \ + --member="$member" \ + --role="$role" +} + +# Delete a function's IAM policy binding, if it exists +# Args: project prefix name member role +function function_iam_policy_binding_withdraw() { + declare -r project="$1"; shift + declare -r prefix="$1"; shift + declare -r name="$1"; shift + declare -r member="$1"; shift + declare -r role="$1"; shift + declare output + if ! output=$( + gcloud functions remove-iam-policy-binding \ + --quiet --project="$project" \ + "${prefix}${name}" \ + --region="$FUNCTION_REGION" \ + --member="$member" \ + --role="$role" 2>&1 + ) && [[ $output != *\ not\ found!* ]]; then + echo "$output" >&2 + false + fi +} + +# Deploy a Cloud Function regardless if its section is enabled or not. +# Args: source project prefix name auth [param_arg...] +# Where "auth" is either "true" or "false" for an authenticated and +# unauthenticated deployment respectively. +function function_deploy_unconditional() { + declare -r source="$1"; shift + declare -r project="$1"; shift + declare -r prefix="$1"; shift + declare -r name="$1"; shift + declare -r auth="$1"; shift + declare iam_action + + assert test "$auth" = "true" -o "$auth" = "false" + + # TODO Upgrade to gen2 + mute gcloud functions deploy --quiet --project="$project" \ + --region="$FUNCTION_REGION" \ + --docker-registry=artifact-registry \ + --runtime python39 \ + --no-gen2 \ + --source "$source" "${prefix}${name}" \ + --entry-point "kcidb_${name}" \ + "$@" + + # Work around broken --allow-unauthenticated option + if "$auth"; then + iam_action="withdraw" + else + iam_action="deploy" + fi + "function_iam_policy_binding_$iam_action" \ + "$project" "$prefix" "$name" "allUsers" "roles/cloudfunctions.invoker" +} + # Deploy a Cloud Function -# Args: sections source project prefix name [param_arg...] +# Args: sections source project prefix name auth [param_arg...] +# Where "auth" is either "true" or "false" for an authenticated and +# unauthenticated deployment respectively. function function_deploy() { declare -r sections="$1"; shift declare -r source="$1"; shift declare -r project="$1"; shift declare -r prefix="$1"; shift declare -r name="$1"; shift + declare -r auth="$1"; shift + + assert test "$auth" = "true" -o "$auth" = "false" + # TODO Upgrade to gen2 sections_run_explicit "$sections" \ "functions.$name" deploy \ - mute gcloud functions deploy --quiet --project="$project" \ - --region="$FUNCTION_REGION" \ - --docker-registry=artifact-registry \ - --runtime python39 \ - --no-gen2 \ - --source "$source" "${prefix}${name}" \ - --entry-point "kcidb_${name}" \ - "$@" + function_deploy_unconditional "$source" "$project" "$prefix" \ + "$name" "$auth" "$@" } # Delete a Cloud Function (without complaining it doesn't exist). diff --git a/kcidb/cloud/functions.sh b/kcidb/cloud/functions.sh index bd9f7548..d9eff196 100644 --- a/kcidb/cloud/functions.sh +++ b/kcidb/cloud/functions.sh @@ -172,7 +172,7 @@ function functions_deploy() { declare trigger_resource="projects/$project/databases/(default)/documents/" trigger_resource+="${spool_collection_path}/{notification_id}" function_deploy "$sections" "$source" "$project" "$prefix" \ - purge_db \ + purge_db true \ --env-vars-file "$env_yaml_file" \ --trigger-topic "${purge_db_trigger_topic}" \ --memory 256MB \ @@ -180,7 +180,7 @@ function functions_deploy() { --timeout 540 function_deploy "$sections" "$source" "$project" "$prefix" \ - pick_notifications \ + pick_notifications true \ --env-vars-file "$env_yaml_file" \ --trigger-topic "${pick_notifications_trigger_topic}" \ --memory 256MB \ @@ -188,7 +188,7 @@ function functions_deploy() { --timeout 540 function_deploy "$sections" "$source" "$project" "$prefix" \ - send_notification \ + send_notification true \ --env-vars-file "$env_yaml_file" \ --trigger-event "${trigger_event}" \ --trigger-resource "${trigger_resource}" \ @@ -198,7 +198,7 @@ function functions_deploy() { --timeout 540 function_deploy "$sections" "$source" "$project" "$prefix" \ - spool_notifications \ + spool_notifications true \ --env-vars-file "$env_yaml_file" \ --trigger-topic "${updated_topic}" \ --memory 4096MB \ @@ -206,16 +206,15 @@ function functions_deploy() { --timeout 540 function_deploy "$sections" "$source" "$project" "$prefix" \ - "$cache_redirect_function_name" \ + "$cache_redirect_function_name" false \ --env-vars-file "$env_yaml_file" \ --trigger-http \ - --allow-unauthenticated \ --memory 256MB \ --max-instances=16 \ --timeout 30 function_deploy "$sections" "$source" "$project" "$prefix" \ - cache_urls \ + cache_urls true \ --env-vars-file "$env_yaml_file" \ --trigger-topic "${updated_urls_topic}" \ --memory 512MB \ @@ -223,7 +222,7 @@ function functions_deploy() { --timeout 540 function_deploy "$sections" "$source" "$project" "$prefix" \ - load_queue \ + load_queue true \ --env-vars-file "$env_yaml_file" \ --trigger-topic "${load_queue_trigger_topic}" \ --memory 1024MB \