|
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