|
1 | 1 | #!/bin/bash
|
2 |
| -set -euo pipefail |
| 2 | +set -eo pipefail |
3 | 3 | IFS=$'\n\t'
|
4 | 4 |
|
5 | 5 | transformed_config_dir_path=''
|
6 | 6 | for i in "$@"
|
7 | 7 | do
|
8 | 8 | case $i in
|
9 |
| - --subscription_id=*) |
| 9 | + --subscription-id=*) |
10 | 10 | subscription_id="${i#*=}"
|
11 | 11 | shift
|
12 | 12 | ;;
|
13 |
| - --resource_group_name=*) |
| 13 | + --resource-group-name=*) |
14 | 14 | resource_group_name="${i#*=}"
|
15 | 15 | shift
|
16 | 16 | ;;
|
17 |
| - --nginx_deployment_name=*) |
| 17 | + --nginx-deployment-name=*) |
18 | 18 | nginx_deployment_name="${i#*=}"
|
19 | 19 | shift
|
20 | 20 | ;;
|
21 |
| - --config_dir_path=*) |
| 21 | + --nginx-config-directory-path=*) |
22 | 22 | config_dir_path="${i#*=}"
|
23 | 23 | shift
|
24 | 24 | ;;
|
25 |
| - --root_config_file=*) |
| 25 | + --nginx-root-config-file=*) |
26 | 26 | root_config_file="${i#*=}"
|
27 | 27 | shift
|
28 | 28 | ;;
|
29 |
| - --transformed_config_dir_path=*) |
| 29 | + --transformed-nginx-config-directory-path=*) |
30 | 30 | transformed_config_dir_path="${i#*=}"
|
31 | 31 | shift
|
32 | 32 | ;;
|
33 | 33 | --debug=*)
|
34 | 34 | debug="${i#*=}"
|
35 | 35 | shift
|
36 | 36 | ;;
|
| 37 | + --protected-files=*) |
| 38 | + protected_files="${i#*=}" |
| 39 | + shift |
| 40 | + ;; |
37 | 41 | *)
|
38 |
| - echo "Not matched option '${i#*=}' passed in." |
| 42 | + echo "Unknown option '${i}' passed in." |
39 | 43 | exit 1
|
40 | 44 | ;;
|
41 | 45 | esac
|
42 | 46 | done
|
43 | 47 |
|
44 |
| -if [[ ! -v subscription_id ]]; |
45 |
| -then |
46 |
| - echo "Please set 'subscription-id' ..." |
47 |
| - exit 1 |
| 48 | +# Validate Required Parameters |
| 49 | +missing_params=() |
| 50 | +if [ -z "$subscription_id" ]; then |
| 51 | + missing_params+=("subscription-id") |
48 | 52 | fi
|
49 |
| -if [[ ! -v resource_group_name ]]; |
50 |
| -then |
51 |
| - echo "Please set 'resource-group-name' ..." |
52 |
| - exit 1 |
| 53 | +if [ -z "$resource_group_name" ]; then |
| 54 | + missing_params+=("resource-group-name") |
53 | 55 | fi
|
54 |
| -if [[ ! -v nginx_deployment_name ]]; |
55 |
| -then |
56 |
| - echo "Please set 'nginx-deployment-name' ..." |
57 |
| - exit 1 |
| 56 | +if [ -z "$nginx_deployment_name" ]; then |
| 57 | + missing_params+=("nginx-deployment-name") |
58 | 58 | fi
|
59 |
| -if [[ ! -v config_dir_path ]]; |
60 |
| -then |
61 |
| - echo "Please set 'nginx-config-directory-path' ..." |
62 |
| - exit 1 |
| 59 | +if [ -z "$config_dir_path" ]; then |
| 60 | + missing_params+=("nginx-config-directory-path") |
63 | 61 | fi
|
64 |
| -if [[ ! -v root_config_file ]]; |
65 |
| -then |
66 |
| - echo "Please set 'nginx-root-config-file' ..." |
| 62 | +if [ -z "$root_config_file" ]; then |
| 63 | + missing_params+=("nginx-root-config-file") |
| 64 | +fi |
| 65 | + |
| 66 | +# Check and print if any required params are missing |
| 67 | +if [ ${#missing_params[@]} -gt 0 ]; then |
| 68 | + echo "Error: Missing required variables in the workflow:" |
| 69 | + echo "${missing_params[*]}" |
67 | 70 | exit 1
|
68 | 71 | fi
|
69 | 72 |
|
@@ -121,60 +124,206 @@ fi
|
121 | 124 | transformed_root_config_file_path="$transformed_config_dir_path$root_config_file"
|
122 | 125 | echo "The transformed root NGINX configuration file path is '$transformed_root_config_file_path'."
|
123 | 126 |
|
124 |
| -# Create a NGINX configuration tarball. |
| 127 | +# Common utility functions |
| 128 | + |
| 129 | +# Function to trim whitespace from a string |
| 130 | +trim_whitespace() { |
| 131 | + local var="$1" |
| 132 | + # Trim leading whitespace from the file path (var) |
| 133 | + # ${var%%[![:space:]]*} starts at the file path's end |
| 134 | + # and finds the longest match of non-whitespace |
| 135 | + # characters leaving only leading whitespaces |
| 136 | + # ${var#"..." } removes the leading whitespace found |
| 137 | + var="${var#"${var%%[![:space:]]*}"}" |
| 138 | + # Remove trailing whitespace |
| 139 | + # See explanation above. The process is reversed here. |
| 140 | + var="${var%"${var##*[![:space:]]}"}" |
| 141 | + # Check if the file exists in the repository |
| 142 | + echo "$var" |
| 143 | +} |
| 144 | + |
| 145 | +# Function to encode file content to base64 |
| 146 | +encode_file_base64() { |
| 147 | + local file_path="$1" |
| 148 | + # Use base64 to encode the file content |
| 149 | + # -w 0 option is used to avoid line wrapping in the output |
| 150 | + base64 -w 0 "$file_path" |
| 151 | +} |
125 | 152 |
|
126 |
| -config_tarball="nginx-config.tar.gz" |
| 153 | +# Function to build virtual path from relative path |
| 154 | +build_virtual_path() { |
| 155 | + local relative_path="$1" |
| 156 | + echo "${transformed_config_dir_path}${relative_path}" |
| 157 | +} |
127 | 158 |
|
128 |
| -echo "Creating a tarball from the NGINX configuration directory." |
129 |
| -tar -cvzf "$config_tarball" -C "$config_dir_path" --xform s:'./':"$transformed_config_dir_path": . |
130 |
| -echo "Successfully created the tarball from the NGINX configuration directory." |
| 159 | +# Function to add a file entry to a JSON array |
| 160 | +# The add_file_to_json_array function uses indirect variable references |
| 161 | +# and global assignment to update JSON arrays and flags that track |
| 162 | +# which files have been processed. The variable names for the JSON array |
| 163 | +# and the "first file" flag are passed as arguments, allowing the |
| 164 | +# function to generically update different arrays |
| 165 | +# (for regular and protected files) without hardcoding their names. |
| 166 | +# The syntax ${!var} retrieves the value of the variable whose |
| 167 | +# name is stored in 'var', and declare -g ensures the updated |
| 168 | +# values are set globally, so changes persist outside the function. |
| 169 | +add_file_to_json_array() { |
| 170 | + local file_path="$1" |
| 171 | + local virtual_path="$2" |
| 172 | + local file_type="$3" # "regular" or "protected" |
| 173 | + local json_var_name="$4" # Variable name to modify |
| 174 | + local first_file_var_name="$5" # Variable name for first_file flag |
| 175 | + |
| 176 | + if [ -f "$file_path" ]; then |
| 177 | + echo "Processing $file_type file: $file_path -> $virtual_path" |
| 178 | + |
| 179 | + # Base64 encode the file content |
| 180 | + local file_content_b64 |
| 181 | + file_content_b64=$(encode_file_base64 "$file_path") |
| 182 | + |
| 183 | + # Get current values using indirect variable references |
| 184 | + local current_json="${!json_var_name}" |
| 185 | + local is_first_file="${!first_file_var_name}" |
| 186 | + |
| 187 | + # Add comma separator if not the first file |
| 188 | + if [ "$is_first_file" = false ]; then |
| 189 | + current_json+="," |
| 190 | + fi |
| 191 | + |
| 192 | + # Add the file entry to JSON array |
| 193 | + current_json+="{\"content\":\"$file_content_b64\",\"virtual-path\":\"$virtual_path\"}" |
| 194 | + |
| 195 | + # Update the variables using indirect assignment |
| 196 | + declare -g "$json_var_name=$current_json" |
| 197 | + declare -g "$first_file_var_name=false" |
| 198 | + |
| 199 | + if [[ "$debug" == true ]]; then |
| 200 | + echo "$file_type file virtual path: $virtual_path" |
| 201 | + echo "$file_type file content (base64): ${file_content_b64:0:50}..." |
| 202 | + fi |
| 203 | + else |
| 204 | + echo "Warning: $file_type file '$file_path' not found" |
| 205 | + fi |
| 206 | +} |
| 207 | + |
| 208 | +# Process protected files first to build exclusion list |
| 209 | +protected_files_list=() |
| 210 | +if [ -n "$protected_files" ]; then |
| 211 | + IFS=',' read -ra files <<< "$protected_files" |
| 212 | + |
| 213 | + for file in "${files[@]}"; do |
| 214 | + file=$(trim_whitespace "$file") |
| 215 | + if [ -n "$file" ]; then |
| 216 | + protected_files_list+=("$file") |
| 217 | + fi |
| 218 | + done |
| 219 | +fi |
| 220 | + |
| 221 | +# Function to check if a file is in the protected files list |
| 222 | +is_protected_file() { |
| 223 | + local relative_path="$1" |
| 224 | + for protected_file in "${protected_files_list[@]}"; do |
| 225 | + if [ "$relative_path" = "$protected_file" ]; then |
| 226 | + return 0 # File is protected |
| 227 | + fi |
| 228 | + done |
| 229 | + return 1 # File is not protected |
| 230 | +} |
131 | 231 |
|
132 |
| -echo "Listing the NGINX configuration file paths in the tarball." |
133 |
| -tar -tf "$config_tarball" |
| 232 | +# Process all configuration files individually (excluding protected files) |
| 233 | + |
| 234 | +echo "Processing NGINX configuration files individually." |
| 235 | + |
| 236 | +# Build the files JSON array |
| 237 | +files_json="[" |
| 238 | +files_first_file=true |
| 239 | + |
| 240 | +# Find all files in the config directory and process them (excluding protected files) |
| 241 | +while IFS= read -r -d '' file; do |
| 242 | + # Get relative path from config directory |
| 243 | + relative_path="${file#$config_dir_path}" |
| 244 | + |
| 245 | + # Skip if this file is in the protected files list |
| 246 | + if is_protected_file "$relative_path"; then |
| 247 | + echo "Skipping protected file from regular files: $relative_path" |
| 248 | + continue |
| 249 | + fi |
| 250 | + |
| 251 | + # Apply transformation to get virtual path |
| 252 | + virtual_path=$(build_virtual_path "$relative_path") |
| 253 | + |
| 254 | + add_file_to_json_array "$file" "$virtual_path" "regular" "files_json" "files_first_file" |
| 255 | +done < <(find "$config_dir_path" -type f -print0) |
134 | 256 |
|
135 |
| -encoded_config_tarball=$(base64 "$config_tarball") |
| 257 | +files_json+="]" |
136 | 258 |
|
137 | 259 | if [[ "$debug" == true ]]; then
|
138 |
| - echo "The base64 encoded NGINX configuration tarball" |
139 |
| - echo "$encoded_config_tarball" |
| 260 | + echo "Regular files JSON: $files_json" |
140 | 261 | fi
|
141 |
| -echo "" |
142 | 262 |
|
143 |
| -# Synchronize the NGINX configuration tarball to the NGINXaaS for Azure deployment. |
| 263 | +# Process protected files if specified |
| 264 | +protected_files_arg="" |
| 265 | +if [ -n "$protected_files" ]; then |
| 266 | + echo "Processing protected files: $protected_files" |
| 267 | + |
| 268 | + # Build the protected files JSON array |
| 269 | + protected_files_json="[" |
| 270 | + protected_first_file=true |
| 271 | + IFS=',' read -ra files <<< "$protected_files" |
| 272 | + |
| 273 | + for file in "${files[@]}"; do |
| 274 | + file=$(trim_whitespace "$file") |
| 275 | + if [ -n "$file" ]; then |
| 276 | + repo_file_path="${config_dir_path}${file}" |
| 277 | + virtual_path=$(build_virtual_path "$file") |
| 278 | + |
| 279 | + add_file_to_json_array "$repo_file_path" "$virtual_path" "protected" "protected_files_json" "protected_first_file" |
| 280 | + fi |
| 281 | + done |
| 282 | + |
| 283 | + protected_files_json+="]" |
| 284 | + |
| 285 | + if [ "$protected_first_file" = false ]; then |
| 286 | + protected_files_arg="--protected-files" |
| 287 | + if [[ "$debug" == true ]]; then |
| 288 | + echo "Protected files JSON: $protected_files_json" |
| 289 | + fi |
| 290 | + fi |
| 291 | +fi |
144 | 292 |
|
145 |
| -uuid="$(cat /proc/sys/kernel/random/uuid)" |
146 |
| -template_file="template-$uuid.json" |
147 |
| -template_deployment_name="${nginx_deployment_name:0:20}-$uuid" |
148 | 293 |
|
149 |
| -wget -O "$template_file" https://raw.githubusercontent.com/nginxinc/nginx-for-azure-deploy-action/487d1394d6115d4f42ece6200cbd20859595557d/src/nginx-for-azure-configuration-template.json |
150 |
| -echo "Downloaded the ARM template for synchronizing NGINX configuration." |
151 |
| -cat "$template_file" |
152 |
| -echo "" |
| 294 | +# Synchronize the NGINX configuration files to the NGINXaaS for Azure deployment. |
153 | 295 |
|
154 | 296 | echo "Synchronizing NGINX configuration"
|
155 | 297 | echo "Subscription ID: $subscription_id"
|
156 | 298 | echo "Resource group name: $resource_group_name"
|
157 | 299 | echo "NGINXaaS for Azure deployment name: $nginx_deployment_name"
|
158 |
| -echo "ARM template deployment name: $template_deployment_name" |
159 | 300 | echo ""
|
160 | 301 |
|
161 | 302 | az account set -s "$subscription_id" --verbose
|
162 | 303 |
|
| 304 | +echo "Installing the az nginx extension if not already installed." |
| 305 | +az extension add --name nginx --allow-preview true |
| 306 | + |
163 | 307 | az_cmd=(
|
164 | 308 | "az"
|
| 309 | + "nginx" |
165 | 310 | "deployment"
|
166 |
| - "group" |
167 |
| - "create" |
168 |
| - "--name" "$template_deployment_name" |
| 311 | + "configuration" |
| 312 | + "update" |
| 313 | + "--name" "default" |
| 314 | + "--deployment-name" "$nginx_deployment_name" |
169 | 315 | "--resource-group" "$resource_group_name"
|
170 |
| - "--template-file" "$template_file" |
171 |
| - "--parameters" |
172 |
| - "nginxDeploymentName=$nginx_deployment_name" |
173 |
| - "rootFile=$transformed_root_config_file_path" |
174 |
| - "tarball=$encoded_config_tarball" |
| 316 | + "--root-file" "$transformed_root_config_file_path" |
| 317 | + "--files" "$files_json" |
175 | 318 | "--verbose"
|
176 | 319 | )
|
177 | 320 |
|
| 321 | +# Add protected files argument if present |
| 322 | +if [ -n "$protected_files_arg" ]; then |
| 323 | + az_cmd+=("$protected_files_arg") |
| 324 | + az_cmd+=("$protected_files_json") |
| 325 | +fi |
| 326 | + |
178 | 327 | if [[ "$debug" == true ]]; then
|
179 | 328 | az_cmd+=("--debug")
|
180 | 329 | echo "${az_cmd[@]}"
|
|
0 commit comments