Skip to content

Commit 3a276d2

Browse files
Adding updates for fetch-keyvault functionality (Azure#54)
1 parent dadf37e commit 3a276d2

File tree

2 files changed

+173
-25
lines changed

2 files changed

+173
-25
lines changed

WORKSPACES/SYSTEM/DEV-WEEU-SAP01-X00/sap-parameters.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,3 +27,5 @@ database_cluster_type: AFA
2727
# Storage Profile #
2828
#############################################################################
2929
NFS_provider: AFS
30+
key_vault_id: /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/<key-vault-name>
31+
secret_id: https://<key-vault-name>.vault.azure.net/secrets/<secret-name>/<id>

scripts/sap_automation_qa.sh

Lines changed: 171 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,12 @@ RED='\033[0;31m'
1818
GREEN='\033[0;32m'
1919
NC='\033[0m'
2020

21-
# Function to print logs with color based on severity
21+
# Global variable to store the path of the temporary file.
22+
temp_file=""
23+
24+
# Print logs with color based on severity.
25+
# :param severity: The severity level of the log (e.g., "INFO", "ERROR").
26+
# :param message: The message to log.
2227
log() {
2328
local severity=$1
2429
local message=$2
@@ -37,12 +42,15 @@ log "INFO" "ANSIBLE_MODULE_UTILS: $ANSIBLE_MODULE_UTILS"
3742
# Define the path to the vars.yaml file
3843
VARS_FILE="${cmd_dir}/../vars.yaml"
3944

40-
# Function to check if a command exists
45+
# Check if a command exists.
46+
# :param command: The command to check.
47+
# :return: None. Exits with a non-zero status if the command does not exist.
4148
command_exists() {
4249
command -v "$1" &> /dev/null
4350
}
4451

45-
# Function to validate input parameters from vars.yaml
52+
# Validate input parameters from vars.yaml.
53+
# :return: None. Exits with a non-zero status if validation fails.
4654
validate_params() {
4755
local missing_params=()
4856
local params=("TEST_TYPE" "SYSTEM_CONFIG_NAME" "sap_functional_test_type" "AUTHENTICATION_TYPE")
@@ -71,18 +79,37 @@ validate_params() {
7179
fi
7280
}
7381

74-
# Function to check if a file exists
82+
# Check if a file exists.
83+
# :param file_path: The path to the file to check.
84+
# :param error_message: The error message to display if the file does not exist.
85+
# :return: None. Exits with a non-zero status if the file does not exist.
7586
check_file_exists() {
7687
local file_path=$1
7788
local error_message=$2
78-
89+
log "INFO" "Checking if file exists: $file_path"
7990
if [[ ! -f "$file_path" ]]; then
8091
log "ERROR" "Error: $error_message"
8192
exit 1
8293
fi
8394
}
8495

85-
# Function to determine the playbook name based on the sap_functional_test_type
96+
# Extract the error message from a command's output.
97+
# :param error_output: The output containing the error message.
98+
# :return: The extracted error message or a default message if none is found.
99+
extract_error_message() {
100+
local error_output=$1
101+
local extracted_message
102+
103+
extracted_message=$(echo "$error_output" | grep -oP '(?<=Message: ).*' | head -n 1)
104+
if [[ -z "$extracted_message" ]]; then
105+
extracted_message="An unknown error occurred. See full error details above."
106+
fi
107+
echo "$extracted_message"
108+
}
109+
110+
# Determine the playbook name based on the sap_functional_test_type.
111+
# :param test_type: The type of SAP functional test.
112+
# :return: The name of the playbook.
86113
get_playbook_name() {
87114
local test_type=$1
88115

@@ -100,24 +127,144 @@ get_playbook_name() {
100127
esac
101128
}
102129

103-
# Function to run the ansible playbook
130+
# Retrieve a secret from Azure Key Vault.
131+
# :param key_vault_id: The ID of the Key Vault.
132+
# :param secret_id: The ID of the secret in the Key Vault.
133+
# :param auth_type: The authentication type (e.g., "SSHKEY", "VMPASSWORD").
134+
# :return: None. Exits with a non-zero status if retrieval fails.
135+
retrieve_secret_from_key_vault() {
136+
local key_vault_id=$1
137+
local secret_id=$2
138+
local auth_type=$3 # Add auth_type as a parameter
139+
140+
subscription_id=$(echo "$key_vault_id" | awk -F'/' '{for(i=1;i<=NF;i++){if($i=="subscriptions"){print $(i+1)}}}')
141+
142+
if [[ -z "$key_vault_id" || -z "$secret_id" ]]; then
143+
log "ERROR" "Key Vault ID or secret ID is missing."
144+
exit 1
145+
fi
146+
147+
log "INFO" "Using Key Vault ID: $key_vault_id"
148+
log "INFO" "Using secret ID: $secret_id"
149+
150+
# Authenticate using MSI
151+
log "INFO" "Authenticating using MSI..."
152+
az login --identity
153+
az account set --subscription "$subscription_id"
154+
if [[ $? -ne 0 ]]; then
155+
log "ERROR" "Failed to authenticate using MSI."
156+
exit 1
157+
fi
158+
159+
# Attempt to retrieve the secret value and handle errors
160+
log "INFO" "Retrieving secret from Key Vault using resource ID..."
161+
set +e # Temporarily disable exit on error
162+
secret_value=$(az keyvault secret show --id "$secret_id" --query "value" -o tsv 2>&1)
163+
az_exit_code=$? # Capture the exit code of the az command
164+
set -e # Re-enable exit on error
165+
166+
if [[ $az_exit_code -ne 0 || -z "$secret_value" ]]; then
167+
extracted_message=$(extract_error_message "$secret_value")
168+
log "ERROR" "Failed to retrieve secret from Key Vault: $extracted_message"
169+
exit 1
170+
fi
171+
172+
log "INFO" "Successfully retrieved secret from Key Vault."
173+
174+
# Define a unique temporary file path based on auth_type
175+
if [[ "$auth_type" == "SSHKEY" ]]; then
176+
temp_file=$(mktemp --dry-run --suffix=.ppk)
177+
elif [[ "$auth_type" == "VMPASSWORD" ]]; then
178+
temp_file=$(mktemp --dry-run)
179+
else
180+
log "ERROR" "Unknown authentication type: $auth_type"
181+
exit 1
182+
fi
183+
184+
if [[ -f "$temp_file" ]]; then
185+
log "ERROR" "Temporary file already exists: $temp_file"
186+
exit 1
187+
fi
188+
189+
# Create the temporary file and write the secret value to it
190+
echo "$secret_value" > "$temp_file"
191+
chmod 600 "$temp_file" # Set the correct permissions for the file
192+
if [[ ! -s "$temp_file" ]]; then
193+
log "ERROR" "Failed to store the retrieved secret in the temporary file."
194+
exit 1
195+
fi
196+
log "INFO" "Temporary file created with secure permissions: $temp_file"
197+
}
198+
199+
# Run the ansible playbook.
200+
# :param playbook_name: The name of the playbook to run.
201+
# :param system_hosts: The path to the inventory file.
202+
# :param system_params: The path to the SAP parameters file.
203+
# :param auth_type: The authentication type (e.g., "SSHKEY", "VMPASSWORD").
204+
# :param system_config_folder: The path to the system configuration folder.
205+
# :return: None. Exits with the return code of the ansible-playbook command.
104206
run_ansible_playbook() {
105207
local playbook_name=$1
106208
local system_hosts=$2
107209
local system_params=$3
108210
local auth_type=$4
109211
local system_config_folder=$5
110212

213+
# Set local secret_id and key_vault_id if defined
214+
local secret_id=$(grep "^secret_id:" "$system_params" | awk '{split($0,a,": "); print a[2]}' | xargs || true)
215+
local key_vault_id=$(grep "^key_vault_id:" "$system_params" | awk '{split($0,a,": "); print a[2]}' | xargs || true)
216+
217+
if [[ -n "$secret_id" ]]; then
218+
log "INFO" "Extracted secret_id: $secret_id"
219+
fi
220+
221+
if [[ -n "$key_vault_id" ]]; then
222+
log "INFO" "Extracted key_vault_id: $key_vault_id"
223+
fi
224+
111225
if [[ "$auth_type" == "SSHKEY" ]]; then
112-
local ssh_key="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk"
113-
log "INFO" "Using SSH key: $ssh_key."
114-
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $ssh_key \
115-
-e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
226+
log "INFO" "Authentication type is SSHKEY."
227+
228+
if [[ -n "$key_vault_id" && -n "$secret_id" ]]; then
229+
log "INFO" "Key Vault ID and Secret ID are set. Retrieving SSH key from Key Vault."
230+
retrieve_secret_from_key_vault "$key_vault_id" "$secret_id" "SSHKEY"
231+
232+
check_file_exists "$temp_file" \
233+
"Temporary SSH key file not found. Please check the Key Vault secret ID."
234+
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $temp_file \
235+
-e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
236+
else
237+
check_file_exists "${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk" \
238+
"ssh_key.ppk not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
239+
ssh_key="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk"
240+
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $ssh_key \
241+
-e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
242+
fi
243+
244+
elif [[ "$auth_type" == "VMPASSWORD" ]]; then
245+
log "INFO" "Authentication type is VMPASSWORD."
246+
247+
if [[ -n "$key_vault_id" && -n "$secret_id" ]]; then
248+
log "INFO" "Key Vault ID and Secret ID are set. Retrieving VM password from Key Vault."
249+
retrieve_secret_from_key_vault "$key_vault_id" "$secret_id" "VMPASSWORD"
250+
251+
check_file_exists "$temp_file" \
252+
"Temporary SSH key file not found. Please check the Key Vault secret ID."
253+
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \
254+
--extra-vars \"ansible_ssh_pass=$(cat $temp_file)\" --extra-vars @$VARS_FILE -e @$system_params \
255+
-e '_workspace_directory=$system_config_folder'"
256+
else
257+
local password_file="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password"
258+
check_file_exists "$password_file" \
259+
"password file not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
260+
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \
261+
--extra-vars \"ansible_ssh_pass=$(cat $password_file)\" --extra-vars @$VARS_FILE -e @$system_params \
262+
-e '_workspace_directory=$system_config_folder'"
263+
fi
264+
116265
else
117-
log "INFO" "Using password authentication."
118-
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \
119-
--extra-vars \"ansible_ssh_pass=$(cat ${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password)\" \
120-
--extra-vars @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
266+
log "ERROR" "Unknown authentication type: $auth_type"
267+
exit 1
121268
fi
122269

123270
log "INFO" "Running ansible playbook..."
@@ -126,10 +273,17 @@ run_ansible_playbook() {
126273
return_code=$?
127274
log "INFO" "Ansible playbook execution completed with return code: $return_code"
128275

276+
# Clean up temporary file if it exists
277+
if [[ -n "$temp_file" && -f "$temp_file" ]]; then
278+
rm -f "$temp_file"
279+
log "INFO" "Temporary file deleted: $temp_file"
280+
fi
281+
129282
exit $return_code
130283
}
131284

132-
# Main script execution
285+
# Main script execution.
286+
# :return: None. Exits with a non-zero status if any step fails.
133287
main() {
134288
log "INFO" "Activate the virtual environment..."
135289
set -e
@@ -152,19 +306,11 @@ main() {
152306
check_file_exists "$SYSTEM_PARAMS" \
153307
"sap-parameters.yaml not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
154308

155-
log "INFO" "Checking if the SSH key or password file exists..."
156-
if [[ "$AUTHENTICATION_TYPE" == "SSHKEY" ]]; then
157-
check_file_exists "${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk" \
158-
"ssh_key.ppk not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
159-
else
160-
check_file_exists "${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password" \
161-
"password file not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
162-
fi
163-
164309
playbook_name=$(get_playbook_name "$sap_functional_test_type")
165310
log "INFO" "Using playbook: $playbook_name."
166311

167312
run_ansible_playbook "$playbook_name" "$SYSTEM_HOSTS" "$SYSTEM_PARAMS" "$AUTHENTICATION_TYPE" "$SYSTEM_CONFIG_FOLDER"
313+
168314
}
169315

170316
# Execute the main function

0 commit comments

Comments
 (0)