Skip to content
Closed
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
64 commits
Select commit Hold shift + click to select a range
a83f8bc
created branch for fetching key_vault_Feature
dhruvmicrosoft Mar 31, 2025
62fe0a7
testing
dhruvmicrosoft Mar 31, 2025
eb59eff
testing
dhruvmicrosoft Mar 31, 2025
1e7bb75
testing
dhruvmicrosoft Mar 31, 2025
4470685
testing
dhruvmicrosoft Mar 31, 2025
9917f84
testing
dhruvmicrosoft Mar 31, 2025
0a5dec8
testing
dhruvmicrosoft Mar 31, 2025
7e6a0de
testing
dhruvmicrosoft Mar 31, 2025
c516567
testing
dhruvmicrosoft Mar 31, 2025
209a480
testing
dhruvmicrosoft Mar 31, 2025
b6e57fc
testing
dhruvmicrosoft Mar 31, 2025
7a94811
testing
dhruvmicrosoft Mar 31, 2025
3d6525b
testing
dhruvmicrosoft Mar 31, 2025
7119de6
testing
dhruvmicrosoft Mar 31, 2025
59150ae
testing
dhruvmicrosoft Mar 31, 2025
6752a37
testing
dhruvmicrosoft Mar 31, 2025
7cdb16b
testing
dhruvmicrosoft Apr 1, 2025
a929ea0
testing
dhruvmicrosoft Apr 1, 2025
4db7056
testing
dhruvmicrosoft Apr 1, 2025
37057c4
testing
dhruvmicrosoft Apr 1, 2025
7b96b1a
testing
dhruvmicrosoft Apr 2, 2025
afc0f1d
testing
dhruvmicrosoft Apr 2, 2025
7dafd6f
testing
dhruvmicrosoft Apr 2, 2025
f4043b7
testing
dhruvmicrosoft Apr 2, 2025
61b4528
testing
dhruvmicrosoft Apr 2, 2025
6b96c4e
testing
dhruvmicrosoft Apr 2, 2025
dae054a
testing
dhruvmicrosoft Apr 2, 2025
641f567
testing
dhruvmicrosoft Apr 2, 2025
9deec6b
testing
dhruvmicrosoft Apr 2, 2025
6a2cbd3
testing
dhruvmicrosoft Apr 2, 2025
f988652
fixed all changes
dhruvmicrosoft Apr 2, 2025
6002730
fixing when SSH-KEY is given secret name shouldnt be defined
dhruvmicrosoft Apr 3, 2025
018f8ff
testing
dhruvmicrosoft Apr 3, 2025
3bb1a0c
testing
dhruvmicrosoft Apr 3, 2025
cd82685
testing
dhruvmicrosoft Apr 3, 2025
dbad57e
testing
dhruvmicrosoft Apr 3, 2025
a209f0a
testing
dhruvmicrosoft Apr 3, 2025
1c7e4ec
Testing
dhruvmicrosoft Apr 3, 2025
35f83f3
fixed comments
dhruvmicrosoft Apr 3, 2025
977e489
fixed comments
dhruvmicrosoft Apr 3, 2025
7850a7b
testing
dhruvmicrosoft Apr 3, 2025
3c98c77
testing
dhruvmicrosoft Apr 3, 2025
1ee31a1
testing
dhruvmicrosoft Apr 3, 2025
1f332fe
testing
dhruvmicrosoft Apr 3, 2025
1569d02
added /dev/null
dhruvmicrosoft Apr 3, 2025
5e3f611
added /dev/null
dhruvmicrosoft Apr 3, 2025
38205f0
added /dev/null
dhruvmicrosoft Apr 3, 2025
6653302
added /dev/null
dhruvmicrosoft Apr 3, 2025
52fe2d6
added /dev/null
dhruvmicrosoft Apr 3, 2025
01ae1f6
reworked the logic
dhruvmicrosoft Apr 3, 2025
c9c6fb3
reworked the logic
dhruvmicrosoft Apr 3, 2025
a4fc8e6
reworked the logic
dhruvmicrosoft Apr 3, 2025
3dd79ab
reworked the logic
dhruvmicrosoft Apr 3, 2025
9125023
final_testing
dhruvmicrosoft Apr 3, 2025
4e373f8
changed logic for extraction
dhruvmicrosoft Apr 3, 2025
4ceaa92
changed logic for extraction
dhruvmicrosoft Apr 3, 2025
0999ea0
called check file function
dhruvmicrosoft Apr 3, 2025
d0ac2d0
moved cleanup function
dhruvmicrosoft Apr 3, 2025
1d8f2b6
removed duplicate code
dhruvmicrosoft Apr 3, 2025
dfcd380
removed else block
dhruvmicrosoft Apr 3, 2025
62cc6d9
testing temp file
dhruvmicrosoft Apr 3, 2025
f682228
adding ssh_key variables
dhruvmicrosoft Apr 3, 2025
c2da030
fixed temp file creation
dhruvmicrosoft Apr 3, 2025
dd34ca3
fixed temp file creation
dhruvmicrosoft Apr 3, 2025
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
5 changes: 5 additions & 0 deletions WORKSPACES/SYSTEM/DEV-WEEU-SAP01-X00/sap-parameters.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -27,3 +27,8 @@ database_cluster_type: AFA
# Storage Profile #
#############################################################################
NFS_provider: AFS
#############################################################################
# Key Vault #
#############################################################################
key_vault_id: /subscriptions/<subscription-id>/resourceGroups/<resource-group>/providers/Microsoft.KeyVault/vaults/<key-vault-name>
secret_name: <secure-secret-name>
251 changes: 228 additions & 23 deletions scripts/sap_automation_qa.sh
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,17 @@ RED='\033[0;31m'
GREEN='\033[0;32m'
NC='\033[0m'

# Function to print logs with color based on severity
"""
Global variable to store the path of the temporary file.
"""
temp_file=""

"""
Print logs with color based on severity.

:param severity: The severity level of the log (e.g., "INFO", "ERROR").
:param message: The message to log.
"""
log() {
local severity=$1
local message=$2
Expand All @@ -37,12 +47,21 @@ log "INFO" "ANSIBLE_MODULE_UTILS: $ANSIBLE_MODULE_UTILS"
# Define the path to the vars.yaml file
VARS_FILE="${cmd_dir}/../vars.yaml"

# Function to check if a command exists
"""
Check if a command exists.

:param command: The command to check.
:return: None. Exits with a non-zero status if the command does not exist.
"""
command_exists() {
command -v "$1" &> /dev/null
}

# Function to validate input parameters from vars.yaml
"""
Validate input parameters from vars.yaml.

:return: None. Exits with a non-zero status if validation fails.
"""
validate_params() {
local missing_params=()
local params=("TEST_TYPE" "SYSTEM_CONFIG_NAME" "sap_functional_test_type" "AUTHENTICATION_TYPE")
Expand Down Expand Up @@ -71,7 +90,13 @@ validate_params() {
fi
}

# Function to check if a file exists
"""
Check if a file exists.

:param file_path: The path to the file to check.
:param error_message: The error message to display if the file does not exist.
:return: None. Exits with a non-zero status if the file does not exist.
"""
check_file_exists() {
local file_path=$1
local error_message=$2
Expand All @@ -82,7 +107,29 @@ check_file_exists() {
fi
}

# Function to determine the playbook name based on the sap_functional_test_type
"""
Extract the error message from a command's output.

:param error_output: The output containing the error message.
:return: The extracted error message or a default message if none is found.
"""
extract_error_message() {
local error_output=$1
local extracted_message

extracted_message=$(echo "$error_output" | grep -oP '(?<=Message: ).*' | head -n 1)
if [[ -z "$extracted_message" ]]; then
extracted_message="An unknown error occurred. See full error details above."
fi
echo "$extracted_message"
}

"""
Determine the playbook name based on the sap_functional_test_type.

:param test_type: The type of SAP functional test.
:return: The name of the playbook.
"""
get_playbook_name() {
local test_type=$1

Expand All @@ -100,24 +147,155 @@ get_playbook_name() {
esac
}

# Function to run the ansible playbook
"""
Retrieve a secret from Azure Key Vault.

:param key_vault_id: The ID of the Key Vault.
:return: None. Exits with a non-zero status if retrieval fails.
"""
retrieve_secret_from_key_vault() {
local key_vault_id=$1
local required_permission="Get"

# Extract resource group name and key vault name from key_vault_id
resource_group_name=$(echo "$key_vault_id" | awk -F'/' '{for(i=1;i<=NF;i++){if($i=="resourceGroups"){print $(i+1)}}}')
key_vault_name=$(echo "$key_vault_id" | awk -F'/' '{for(i=1;i<=NF;i++){if($i=="vaults"){print $(i+1)}}}')
subscription_id=$(echo "$key_vault_id" | awk -F'/' '{for(i=1;i<=NF;i++){if($i=="subscriptions"){print $(i+1)}}}')

if [[ -z "$resource_group_name" || -z "$key_vault_name" ]]; then
log "ERROR" "Failed to extract resource group name or key vault name from key_vault_id: $key_vault_id"
exit 1
fi

log "INFO" "Extracted resource group name: $resource_group_name"
log "INFO" "Extracted key vault name: $key_vault_name"

# Authenticate using MSI
log "INFO" "Authenticating using MSI..."
az login --identity
az account set --subscription "$subscription_id"
if [[ $? -ne 0 ]]; then
log "ERROR" "Failed to authenticate using MSI."
exit 1
fi

# Attempt to access Key Vault to verify permissions
log "INFO" "Verifying permissions on Key Vault: $key_vault_name..."
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

we're not doing this

set +e # Temporarily disable exit on error
error_message=$(az keyvault secret list --vault-name "$key_vault_name" 2>&1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will only ensure that the std error is redirected to std output
please add > /dev/null to discard std output

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

everytime I add this I get an error

az_exit_code=$? # Capture the exit code of the az command
set -e # Re-enable exit on error

if [[ $az_exit_code -ne 0 ]]; then
extracted_message=$(extract_error_message "$error_message")
log "ERROR" "Azure CLI error: $extracted_message"
exit 1
fi

# Attempt to retrieve the secret value and handle errors
log "INFO" "Retrieving secret '$secret_name' from Key Vault '$key_vault_name'..."
set +e # Temporarily disable exit on error
secret_value=$(az keyvault secret show --vault-name "$key_vault_name" --name "$secret_name" --query "value" -o tsv 2>&1)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this will only ensure that the std error is redirected to std output
please add > /dev/null to discard std output

az_exit_code=$? # Capture the exit code of the az command
set -e # Re-enable exit on error

if [[ $az_exit_code -ne 0 ]]; then
extracted_message=$(extract_error_message "$secret_value")
log "ERROR" "Failed to retrieve secret '$secret_name' from Key Vault '$key_vault_name': $extracted_message"
exit 1
fi

log "INFO" "Successfully retrieved secret from Key Vault."
temp_file=$(mktemp --suffix=.ppk)

# Check if the temporary file already exists
check_file_exists "$temp_file" "Temporary file already exists: $temp_file"

echo "$secret_value" > "$temp_file"
log "INFO" "Temporary SSH key file created: $temp_file"
}

"""
Run the ansible playbook.

:param playbook_name: The name of the playbook to run.
:param system_hosts: The path to the inventory file.
:param system_params: The path to the SAP parameters file.
:param auth_type: The authentication type (e.g., "SSHKEY", "VMPASSWORD").
:param system_config_folder: The path to the system configuration folder.
:param secret_name: The name of the secret in the Key Vault.
:return: None. Exits with the return code of the ansible-playbook command.
"""
run_ansible_playbook() {
local playbook_name=$1
local system_hosts=$2
local system_params=$3
local auth_type=$4
local system_config_folder=$5
local secret_name=$6

if [[ "$auth_type" == "SSHKEY" ]]; then
local ssh_key="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk"
log "INFO" "Using SSH key: $ssh_key."
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $ssh_key \
-e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
log "INFO" "Authentication type is SSHKEY."

# Extract key_vault_id from sap-parameters.yaml
key_vault_id=$(grep "^key_vault_id:" "$system_params" | awk '{split($0,a,": "); print a[2]}' | xargs)

if [[ -z "$key_vault_id" ]]; then
local ssh_key="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check if this file exists
bring the code from the main function here

if [[ -f "$ssh_key" ]]; then
log "INFO" "key_vault_id is not provided, but local SSH key is present: $ssh_key."
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $ssh_key \
-e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
else
log "ERROR" "Error: key_vault_id is not defined in $system_params, and no local SSH key is present."
exit 1
fi
else
log "INFO" "Extracted key_vault_id: $key_vault_id"

# Extract Key Vault details and retrieve secret
retrieve_secret_from_key_vault "$key_vault_id"
if [[ -z "$secret_value" ]]; then
local ssh_key="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk"
if [[ -f "$ssh_key" ]]; then
log "INFO" "Secret value is not retrieved, but local SSH key is present: $ssh_key."
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $ssh_key \
-e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
else
log "ERROR" "Error: Secret value is not retrieved, and no local SSH key is present."
exit 1
fi
else
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why is this block required?

log "INFO" "Using Key Vault for SSH key retrieval."
log "INFO" "Temporary SSH key file: $temp_file"
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts --private-key $temp_file \
-e @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
fi
fi
elif [[ "$auth_type" == "VMPASSWORD" ]]; then
if [[ -z "$secret_value" ]]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

where is this value being set?

local password_file="${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password"
if [[ -f "$password_file" ]]; then
log "INFO" "Secret value is not retrieved, but local password file is present: $password_file."
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \
--extra-vars \"ansible_ssh_pass=$(cat $password_file)\" --extra-vars @$VARS_FILE -e @$system_params \
-e '_workspace_directory=$system_config_folder'"
else
log "ERROR" "Error: Secret value is not retrieved, and no local password file is present."
exit 1
fi
else
log "INFO" "Using Key Vault for password retrieval."
temp_file=$(mktemp --suffix=.password)
echo "$secret_value" > "$temp_file"
log "INFO" "Temporary password file created: $temp_file"
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \
--extra-vars \"ansible_ssh_pass=$(cat $temp_file)\" --extra-vars @$VARS_FILE -e @$system_params \
-e '_workspace_directory=$system_config_folder'"
fi
else
log "INFO" "Using password authentication."
command="ansible-playbook ${cmd_dir}/../src/$playbook_name.yml -i $system_hosts \
--extra-vars \"ansible_ssh_pass=$(cat ${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password)\" \
--extra-vars @$VARS_FILE -e @$system_params -e '_workspace_directory=$system_config_folder'"
log "ERROR" "Unknown authentication type: $auth_type"
exit 1
fi

log "INFO" "Running ansible playbook..."
Expand All @@ -126,10 +304,20 @@ run_ansible_playbook() {
return_code=$?
log "INFO" "Ansible playbook execution completed with return code: $return_code"

# Clean up temporary file if it exists
if [[ -n "$temp_file" && -f "$temp_file" ]]; then
rm -f "$temp_file"
log "INFO" "Temporary file deleted: $temp_file"
fi

exit $return_code
}

# Main script execution
"""
Main script execution.

:return: None. Exits with a non-zero status if any step fails.
"""
main() {
log "INFO" "Activate the virtual environment..."
set -e
Expand All @@ -152,19 +340,36 @@ main() {
check_file_exists "$SYSTEM_PARAMS" \
"sap-parameters.yaml not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."

log "INFO" "Checking if the SSH key or password file exists..."
if [[ "$AUTHENTICATION_TYPE" == "SSHKEY" ]]; then
check_file_exists "${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk" \
"ssh_key.ppk not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
else
check_file_exists "${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password" \
"password file not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
# log "INFO" "Checking if the SSH key or password file exists..."
# if [[ "$AUTHENTICATION_TYPE" == "SSHKEY" ]]; then
# check_file_exists "${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/ssh_key.ppk" \
# "ssh_key.ppk not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
# elif [[ "$AUTHENTICATION_TYPE" == "VMPASSWORD" ]]; then
# check_file_exists "${cmd_dir}/../WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME/password" \
# "password file not found in WORKSPACES/SYSTEM/$SYSTEM_CONFIG_NAME directory."
# elif [[ "$AUTHENTICATION_TYPE" == "KEYVAULT" ]]; then
# log "INFO" "Key Vault authentication selected. Ensure Key Vault parameters are set."
# fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this should be moved in the if-else loop where the users use the local files?


# Extract secret_name from sap-parameters.yaml
secret_name=$(grep "^secret_name:" "$SYSTEM_PARAMS" | awk '{split($0,a,": "); print a[2]}' | xargs)

if [[ -z "$secret_name" ]]; then
log "ERROR" "Error: secret_name is not defined in $SYSTEM_PARAMS."
exit 1
fi
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

similar comment as above, what if the user wants to user local ssh key

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

and what if the user wants to use vmpassword and not sshkey?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if the secret name is not provided, then we are exiting out of it.

log "INFO" "Extracted secret_name: $secret_name"

playbook_name=$(get_playbook_name "$sap_functional_test_type")
log "INFO" "Using playbook: $playbook_name."

run_ansible_playbook "$playbook_name" "$SYSTEM_HOSTS" "$SYSTEM_PARAMS" "$AUTHENTICATION_TYPE" "$SYSTEM_CONFIG_FOLDER"
run_ansible_playbook "$playbook_name" "$SYSTEM_HOSTS" "$SYSTEM_PARAMS" "$AUTHENTICATION_TYPE" "$SYSTEM_CONFIG_FOLDER" "$secret_name"

# Clean up any remaining temporary files
if [[ -n "$temp_file" && -f "$temp_file" ]]; then
rm -f "$temp_file"
log "INFO" "Temporary file deleted: $temp_file"
fi
}

# Execute the main function
Expand Down
Loading