lib/qesapdeployment.pm

NAME

qe-sap-deployment test lib

COPYRIGHT

Copyright 2022 SUSE LLC
SPDX-License-Identifier: FSFAP

AUTHORS

QE SAP <qe-sap@suse.de>

DESCRIPTION

Package with common methods and default or constant  values for qe-sap-deployment

Methods

qesap_get_file_paths

Returns a hash containing file paths for configuration files

qesap_create_folder_tree

Create all needed folders

qesap_get_variables

Scans yaml configuration for '%OPENQA_VARIABLE%' placeholders and
searches for values in OpenQA defined variables.
Returns hash with openqa variable key/value pairs.

qesap_create_ansible_section

Writes "ansible" section into yaml configuration file.
$args{ansible_section} defines section(key) name.
$args{section_content} defines content of names section.
    Example:
        @playbook_list = ("pre-cluster.yaml", "cluster_sbd_prep.yaml");
        qesap_create_ansible_section(ansible_section=>'create', section_content=>\@playbook_list);

qesap_venv_cmd_exec

Run a command within the Python virtualenv
created by qesap_pip_install.

This function never dies: it always returns an error to the caller.
Timeout error is 124 (the one reported by timeout command line utility).
CMD - command to run within the .venv, usually it is a qesap.py based command
TIMEOUT - default 90 secs, has to be an integer greater than 0
LOG_FILE - optional argument that results in changing the command to redirect the output to a log file

qesap_py

Return string of the python to use

qesap_pip

Return string of the pip to use

qesap_pip_install

Install all Python requirements of the qe-sap-deployment
in a dedicated virtual environment.
This function has no return code but it is expected to die
if something internally fails.

qesap_galaxy_install

Install all Ansible requirements of the qe-sap-deployment.
This function has no return code but it is expected to die
if something internally fails.

qesap_upload_logs

qesap_upload_logs([failok=1])

Collect and upload logs present in @log_files.
FAILOK - used as failok for the upload_logs. continue even in case upload fails

qesap_get_deployment_code

Get the qe-sap-deployment code

qesap_get_roles_code Get the Ansible roles code from github.com/sap-linuxlab/community.sles-for-sap

Keep in mind that to allow qe-sap-deployment to use roles from this repo,
your config.yaml has to have a specific setting ansible::roles_path.

qesap_yaml_replace

Replaces yaml configuration file variables with parameters
defined by OpenQA test code, yaml template or yaml schedule.
Openqa variables need to be added as a hash
with key/value pair inside %run_args{openqa_variables}.
Example:
    my %variables;
    $variables{HANA_SAR} = get_required_var("HANA_SAR");
    $variables{HANA_CLIENT_SAR} = get_required_var("HANA_CLIENT_SAR");
    qesap_yaml_replace(openqa_variables=>\%variables);

qesap_execute

qesap_execute(
    cmd => 'terraform',
    logname => 'terraform_destroy.log.txt'
    [, verbose => 1, cmd_options => $cmd_options] );

Example:
    qesap_execute(cmd => 'terraform', cmd_options => '-d')
result in:
    qesap.py terraform -d

Execute qesap glue script commands. Check project documentation for available options:
https://github.com/SUSE/qe-sap-deployment
Function returns a two element array:
  - first element is an integer representing the execution result
  - second element is the file path of the execution log
This function is not expected to internally die, any failure has to be handled by the caller.
CMD - qesap.py subcommand to run
LOGNAME - filename of the log file. This file will be saved in `/tmp` folder
CMD_OPTIONS - set of arguments for the qesap.py subcommand
VERBOSE - activate verbosity in qesap.py
TIMEOUT - max expected execution time, default 90sec

qesap_execute_conditional_retry

qesap_execute_conditional_retry(
cmd => $qesap_script_cmd,
error_string => 'Fatal:',
logname => 'somefile.txt'
[, verbose => 1s] );

Execute qesap glue script commands. Check project documentation for available options:
https://github.com/SUSE/qe-sap-deployment
Test only returns execution result, failure has to be handled by calling method.
CMD - qesap.py subcommand to run
VERBOSE - activate verbosity in qesap.py
TIMEOUT - max expected execution time, default 90sec
LOGNAME - filename of the log file.
RETRIES - number of retries in case of expected error
ERROR_STRING - error string to look for

qesap_file_find_string

Search for a string in the Ansible log file.
Returns 1 if the string is found in the log file, 0 otherwise.
FILE - Path to the Ansible log file. (Required)
SEARCH_STRING - String to search for in the log file. (Required)

qesap_get_inventory

Return the path of the generated inventory
PROVIDER - Cloud provider name using same format of PUBLIC_CLOUD_PROVIDER setting

qesap_get_nodes_number

Get the number of cluster nodes from the inventory.yaml

PROVIDER - Cloud provider name using same format of PUBLIC_CLOUD_PROVIDER setting

qesap_get_nodes_names

Get the cluster nodes' names from the inventory.yaml

PROVIDER - Cloud provider name using same format of PUBLIC_CLOUD_PROVIDER setting

qesap_get_terraform_dir

Return the path used by the qesap script as -chdir argument for terraform
It is useful if test would like to call terraform
PROVIDER - Cloud provider name using same format of PUBLIC_CLOUD_PROVIDER setting

qesap_get_ansible_roles_dir

Return the path where sap-linuxlab/community.sles-for-sap
has been installed

qesap_prepare_env

qesap_prepare_env(variables=>{dict with variables}, provider => 'aws');

Prepare terraform environment.
- creates file structures
- pulls git repository
- external configuration files
- installs pip requirements and OS packages
- generates configuration files with qesap script

For variables example see 'qesap_yaml_replace'
Returns only result, failure handling has to be done by calling method.
PROVIDER - Cloud provider name, used to optionally activate AWS credential code

qesap_ansible_get_playbook

Download the playbook from the test code repo
that is on the worker within the running JompHost.

qesap_ansible_cmd

Use Ansible to run a command remotely on some or all
the hosts from the inventory.yaml
PROVIDER - Cloud provider name, used to find the inventory
CMD - command to run remotely
USER - user on remote host, default to 'cloudadmin'
FILTER - filter hosts in the inventory
FAILOK - if not set, Ansible failure result in die
HOST_KEYS_CHECK - if set, add some extra argument to the Ansible call to allow contacting hosts not in the KnownHost list yet. This enables the use of this api before the call to qesap.py ansible
TIMEOUT - default 90 secs
VERBOSE - enable verbosity, default is OFF

qesap_ansible_script_output_file

Use Ansible to run a command remotely and get the stdout.
Command could be executed with elevated privileges

qesap_ansible_script_output_file(cmd => 'crm status', provider => 'aws', host => 'vmhana01', root => 1);

It uses playbook data/sles4sap/script_output.yaml

1. ansible-playbook runs the playbook
2. the playbook executes the command remotely and redirects the output to file, both remotely
3. qesap_ansible_fetch_file downloads the file locally
4. the file is read and stored to be returned to the caller

Return is the local full path of the file containing the output of the
remotely executed command.
PROVIDER - Cloud provider name, used to find the inventory
CMD - command to run remotely
HOST - filter hosts in the inventory
FILE - result file name
OUT_PATH - path to save result file locally (without file name)
USER - user on remote host, default to 'cloudadmin'
ROOT - 1 to enable remote execution with elevated user, default to 0
FAILOK - if not set, Ansible failure result in die
VERBOSE - 1 result in ansible-playbook to be called with '-vvvv', default is 0.
TIMEOUT - max expected execution time, default 180sec. Same timeout is used both for the execution of script_output.yaml and for the fetch_file. Timeout of the same amount is started two times.
REMOTE_PATH - Path to save file in the remote (without file name)

qesap_ansible_script_output

Return the output of a command executed on the remote machine via Ansible.
PROVIDER - Cloud provider name, used to find the inventory
CMD - command to run remotely
HOST - filter hosts in the inventory
USER - user on remote host, default to 'cloudadmin'
ROOT - 1 to enable remote execution with elevated user, default to 0
FAILOK - if not set, Ansible failure result in die
TIMEOUT - max expected execution time
FILE - result file name
OUT_PATH - path to save result file locally (without file name)
REMOTE_PATH - Path to save file in the remote (without file name)

qesap_ansible_fetch_file

Use Ansible to fetch a file from remote.
Command could be executed with elevated privileges

qesap_ansible_fetch_file(provider => 'aws', host => 'vmhana01', root => 1);

It uses playbook data/sles4sap/fetch_file.yaml

1. ansible-playbook run the playbook
3. the playbook download the file locally
4. the file is read and stored to be returned to the caller

Return the local path of the downloaded file.
PROVIDER - Cloud provider name, used to find the inventory
HOST - filter hosts in the inventory
REMOTE_PATH - path to find file in the remote (without file name)
USER - user on remote host, default to 'cloudadmin'
ROOT - 1 to enable remote execution with elevated user, default to 0
FAILOK - if not set, Ansible failure result in die
TIMEOUT - max expected execution time, default 180sec
FILE - file name of the local copy of the file
OUT_PATH - path to save file locally (without file name)
VERBOSE - 1 result in ansible-playbook to be called with '-vvvv', default is 0.

qesap_create_aws_credentials

Creates a AWS credentials file as required by QE-SAP Terraform deployment code.

qesap_create_aws_config

Creates a AWS configuration file in ~/.aws
as required by the QE-SAP Terraform & Ansible deployment code.

qesap_remote_hana_public_ips

Return a list of the public IP addresses of the systems
deployed by qe-sap-deployment, as reported by C<terraform output>.
Needs to run after C<qesap_execute(cmd => 'terraform');> call.

qesap_wait_for_ssh

Probe specified port on the remote host each 5sec till response.
Return -1 in case of timeout
Return total time of retry loop in case of pass.
HOST - IP of the host to probe
TIMEOUT - time to wait before to give up, default is 10mins
PORT - port to probe, default is 22

qesap_upload_crm_report

Run crm report on a host and upload the resulting tarball to openqa
HOST - host to get the report from
PROVIDER - Cloud provider name, used to find the inventory
FAILOK - if not set, Ansible failure result in die

qesap_cluster_log_cmds

List of commands to collect logs from a deployed cluster

qesap_cluster_logs

Collect logs from a deployed cluster

qesap_calculate_deployment_name

Compose the deployment name. It always has the JobId

PREFIX - optional substring prepend in front of the job id

qesap_aws_get_region_subnets

Return a list of subnets. Return a single subnet for each region.

VPC_ID - VPC ID of resource to filter list of subnets

qesap_aws_get_vpc_id

Get the vpc_id of a given instance in the cluster.
This function looks for the cluster using the aws describe-instances
and filtering by terraform deployment_name value, that qe-sap-deployment
is kind to use as tag for each resource.
RESOURCE_GROUP - resource group name to query

qesap_aws_get_transit_gateway_vpc_attachment Ged a description of one or more transit-gateway-attachments Function support optional arguments that are translated to filters: - transit_gateway_attach_id - name

Example:
  qesap_aws_get_transit_gateway_vpc_attachment(name => 'SOMETHING')

  Result internally in aws cli to be called like

  aws ec2 describe-transit-gateway-attachments --filter='Name=tag:Name,Values=SOMETHING

Only one filter mode is supported at any time.

Returns a HASH reference to the decoded JSON returned by the AWS command or undef on failure.

qesap_aws_create_transit_gateway_vpc_attachment

Call create-transit-gateway-vpc-attachment and
wait until Transit Gateway Attachment is available.

Return 1 (true) if properly managed to create the transit-gateway-vpc-attachment
Return 0 (false) if create-transit-gateway-vpc-attachment fails or
              the gateway does not become active before the timeout
TRANSIT_GATEWAY_ID - ID of the target Transit gateway (IBS Mirror)
VPC_ID - VPC ID of resource to be attached (SUT HANA cluster)
SUBNET_ID_LIST - List of subnet to connect (SUT HANA cluster)
NAME - Prefix for the Tag Name of transit-gateway-vpc-attachment
TIMEOUT - default is 5 mins

qesap_aws_delete_transit_gateway_vpc_attachment

Call delete-transit-gateway-vpc-attachment and
wait until Transit Gateway Attachment is deleted.

Return 1 (true) if properly managed to delete the transit-gateway-vpc-attachment
Return 0 (false) if delete-transit-gateway-vpc-attachment fails or
     the gateway does not become inactive before the timeout
NAME - Prefix for the Tag Name of transit-gateway-vpc-attachment
TIMEOUT - default is 5 mins

qesap_aws_add_route_to_tgw Adding the route to the transit gateway to the routing table in refhost VPC

RTABLE_ID - Routing table ID
TARGET_IP_NET - Target IP network to be added to the Routing table eg. 192.168.11.0/16
TRANSIT_GATEWAY_ID - ID of the target Transit gateway (IBS Mirror)

qesap_aws_filter_query

Generic function to compose a aws cli command with:
  - `aws ec2` something
  - use both `filter` and `query`
  - has text output

qesap_aws_get_mirror_tg

Return the Transient Gateway ID of the IBS Mirror

qesap_aws_get_vpc_workspace

Get the VPC tag workspace defined in
https://github.com/SUSE/qe-sap-deployment/blob/main/terraform/aws/infrastructure.tf
VPC_ID - VPC ID of resource to be attached (SUT HANA cluster)

qesap_aws_get_routing

Get the Routing table: searching Routing Table with external connection
and get the RouteTableId
VPC_ID - VPC ID of resource to be attached (SUT HANA cluster)

qesap_aws_vnet_peering

Create a pair of network peering between
the two provided deployments.

Return 1 (true) if the overall peering procedure completes successfully
TARGET_IP - Target IP network to be added to the Routing table eg. 192.168.11.0/16
VPC_ID - VPC ID of resource to be attached (SUT HANA cluster)

qesap_add_server_to_hosts

Adds a 'ip -> name' pair in the end of /etc/hosts in the hosts
IP - ip of server to add to hosts
NAME - name of server to add to hosts

qesap_import_instances

Downloads assets required for re-using infrastructure from previously exported test.
qesap_import_instances(<$test_id>)
$test_id - OpenQA test ID from a test previously run with "QESAP_DEPLOYMENT_IMPORT=1" and infrastructure still being up and running

qesap_export_instances

Downloads assets required for re-using infrastructure from previously exported test.
qesap_export_instances()

qesap_is_job_finished

Get whether a specified job is still running or not. 
In cases of ambiguous responses, they are considered to be in `running` state.
JOB_ID - id of job to check

qesap_az_get_vnet

Return the output of az network vnet list

RESOURCE_GROUP - resource group name to query

qesap_az_get_resource_group

Query and return the resource group used by the qe-sap-deployment

SUBSTRING - optional substring to be used with additional grep at the end of the command

qesap_az_calculate_address_range

Calculate the vnet and subnet address ranges. The format is 10.ip2.ip3.0/21 and /24 respectively. ip2 and ip3 are calculated using the slot number as seed.

SLOT - integer to be used as seed in calculating addresses

qesap_az_vnet_peering

Create a pair of network peering between
the two provided deployments.
SOURCE_GROUP - resource group of source
TARGET_GROUP - resource group of target
TIMEOUT - default is 5 mins

qesap_az_simple_peering_delete

Delete a single peering one way
RG - Name of the resource group
VNET_NAME - Name of the vnet
PEERING_NAME - Name of the peering
TIMEOUT - (Optional) Timeout for the script_run command

qesap_az_vnet_peering_delete

Delete all the network peering between the two provided deployments.
TARGET_GROUP - resource group of target. This parameter is mandatory and the associated resource group is supposed to still exist.
TIMEOUT - default is 5 mins

qesap_az_peering_list_cmd

Compose the azure peering list command, using the provided:
- resource group, and
- vnet
Returns the command string to be run.
RESOURCE_GROUP - resource group connected to the peering
VNET - vnet connected to the peering

qesap_az_get_peering_name

Search for all network peering related to both:
 - resource group related to the current job
 - the provided resource group.
Returns the peering name or
empty string if a peering doesn't exist
RESOURCE_GROUP - resource group connected to the peering

qesap_az_get_active_peerings

Get active peering for Azure jobs
RG - Resource group in question
VNET - vnet name of rg

qesap_az_clean_old_peerings

Delete leftover peering for Azure jobs that finished without cleaning up
RG - Resource group in question
VNET - vnet name of rg

qesap_az_setup_native_fencing_permissions

qesap_az_setup_native_fencing_permissions(vmname=>$vm_name,
    resource_group=>$resource_group);

Sets up managed identity (MSI) by enabling system assigned identity and
role 'Virtual Machine Contributor'
VM_NAME - VM name
RESOURCE_GROUP - resource group resource belongs to

qesap_az_get_tenant_id

qesap_az_get_tenant_id( subscription_id=>$subscription_id )

Returns tenant ID related to the specified subscription ID.
subscription_id - valid azure subscription

qesap_az_create_sas_token

Generate a SAS URI token for a storage container of choice

Return the token string

STORAGE - Storage account name used fur the --account-name argument in az commands
CONTAINER - container name within the storage account
KEYNAME - name of the access key within the storage account
PERMISSION - access permissions. Syntax is what documented in 'az storage container generate-sas --help'. Some of them of interest: (a)dd (c)reate (d)elete (e)xecute (l)ist (m)ove (r)ead (w)rite. Default is 'r'
LIFETIME - life time of the token in minutes, default is 10min

qesap_az_list_container_files

Returns a list of the files that exist inside a given path in a given container in Azure storage.

Generated command looks like this:

az storage blob list --account-name <account_name> --container-name <container_name> --sas-token "<my_token>" --prefix <path_inside_container> --query "[].{name:name}" --output tsv

STORAGE - Storage account name used fur the --account-name argument in az commands
CONTAINER - container name within the storage account
TOKEN - name of the SAS token to access the account (needs to have l permission)
PREFIX - the local path inside the container (to list file inside a folder named 'dir', this would be 'dir')

qesap_az_diagnostic_log

Call `az vm boot-diagnostics json` for each running VM in the resource group associated to this openQA job

Return a list of diagnostic file paths on the JumpHost

qesap_terrafom_ansible_deploy_retry

qesap_terrafom_ansible_deploy_retry( error_log=>$error_log )
    error_log - ansible error log file name

Retry to deploy terraform + ansible
Return 0: we manage the failure properly
Return 1: something went wrong or we do not know what to do with the failure
ERROR_LOG - error log filename
PROVIDER - cloud provider name as from PUBLIC_CLOUD_PROVIDER setting

qesap_ansible_error_detection

qesap_ansible_error_detection( error_log=>$error_log )

Inspect the provided Ansible log and search for known issue in the log
Also provide a nice record_info to summarize the error
Return:
 - 0: no errors
 - 1: unknown generic error
 - 2: reboot timeout
 - 3: no sudo password
ERROR_LOG - error log filename

qesap_test_postfail

qesap_test_postfail()

Post fail tasks suitable for post_fail_hook of the test modules.
This API is mainly designed for qesap regresstion test modules.
PROVIDER - cloud provider name as from PUBLIC_CLOUD_PROVIDER setting
NET_PEERING_ID - ID of the network peering, for Azure it has to be the name of the Resource Group of the mirror, for AWS it has to be the something different from an empty string, for example the setting about the IP RANGE.