diff --git a/.all-contributorsrc b/.all-contributorsrc index a4984dac9..c2f60ac4c 100644 --- a/.all-contributorsrc +++ b/.all-contributorsrc @@ -119,6 +119,15 @@ "talk" ] }, + { + "login": "Khushboodholi", + "name": "Khushboodholi", + "avatar_url": "https://avatars.githubusercontent.com/u/12014935?v=4", + "profile": "https://github.com/Khushboodholi", + "contributions": [ + "code" + ] + }, { "login": "araji", "name": "araji", @@ -397,15 +406,6 @@ "test" ] }, - { - "login": "Khushboodholi", - "name": "Khushboodholi", - "avatar_url": "https://avatars.githubusercontent.com/u/12014935?v=4", - "profile": "https://github.com/Khushboodholi", - "contributions": [ - "code" - ] - }, { "login": "naresh3774", "name": "Naresh Sharma", @@ -471,6 +471,16 @@ "test", "code" ] + }, + { + "login": "shridhar-sharma", + "name": "shridhar-sharma", + "avatar_url": "https://avatars.githubusercontent.com/u/104621992?v=4", + "profile": "https://github.com/shridhar-sharma", + "contributions": [ + "test", + "code" + ] } ], "contributorsPerLine": 7, diff --git a/.metadata/omnia_version b/.metadata/omnia_version index e5310cb32..268741fa1 100644 --- a/.metadata/omnia_version +++ b/.metadata/omnia_version @@ -1 +1,2 @@ -Omnia version devel +omnia_version: 1.3 +omnia_installation_path: "" \ No newline at end of file diff --git a/README.md b/README.md index 71f916b0f..d0417631e 100644 --- a/README.md +++ b/README.md @@ -63,44 +63,44 @@ Our thanks go to everyone who makes Omnia possible ([emoji key](https://allcontr
Cassey Goveas

📖 🐛 🚧 📢 +
Khushboodholi

💻
araji

💻
Mike Renfro

📖
Lee Reynolds

💻 📖
blesson-james

💻 ⚠️ 🐛
avinashvishwanath

📖 -
abhishek-s-a

💻 📖 ⚠️ +
abhishek-s-a

💻 📖 ⚠️
Franklin-Johnson

💻 📝
teiland7

💻 📝
VishnupriyaKrish

💻 ⚠️
Ishita Datta

📖
William Dizon


bssitton-BU

🐛 -
John Hearns

🐛 +
John Hearns

🐛
renzo-granados

🐛
kris buggenhout

🐛
jiad-vmware

🐛
Justin Lecher

🤔
Kavyabr23

💻 ⚠️
vedaprakashanp

⚠️ 💻 -
Bhagyashree-shetty

⚠️ 💻 +
Bhagyashree-shetty

⚠️ 💻
Nihal Ranjan

⚠️ 💻
ptrinesh

💻
Ikko Ashimine

💻
Lakshmi-Patneedi

💻
Jie Li

💻
Yong Chen

🎨 -
nvtngan

💻 🔌 +
nvtngan

💻 🔌
tamilarasansubrama1

⚠️ 💻
shemasr

🐛 💻 ⚠️ -
Khushboodholi

💻
Naresh Sharma

🐛
Jon Hass

📖 🎨
KalyanKonatham

🐛 @@ -110,6 +110,7 @@ Our thanks go to everyone who makes Omnia possible ([emoji key](https://allcontr
srinandini-karumuri

💻
Rishabhm47

⚠️ 💻
vaishakh-pm

⚠️ 💻 +
shridhar-sharma

⚠️ 💻 diff --git a/control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml b/control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml index 53a6f52ef..a93c3e602 100644 --- a/control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml +++ b/control_plane/roles/control_plane_common/tasks/fetch_base_inputs.yml @@ -264,13 +264,6 @@ fail_msg: "{{ fail_awx_organization }}" tags: [ validate, awx ] -- name: Create default directory to store omnia files - file: - path: "{{ omnia_default_path }}" - state: directory - mode: "{{ mount_dir_perm }}" - tags: init - - name: Make mount directory for grafana if it doesnt exist file: path: "{{ mount_location }}" diff --git a/control_plane/roles/control_plane_common/tasks/main.yml b/control_plane/roles/control_plane_common/tasks/main.yml index 7ace8d5e2..557272372 100644 --- a/control_plane/roles/control_plane_common/tasks/main.yml +++ b/control_plane/roles/control_plane_common/tasks/main.yml @@ -20,6 +20,10 @@ import_tasks: internet_validation.yml tags: init +- name: Configure omnia version + import_tasks: omnia_version_configuration.yml + tags: init + - name: Common packages installation import_tasks: package_installation.yml tags: init diff --git a/control_plane/roles/control_plane_common/tasks/omnia_version_configuration.yml b/control_plane/roles/control_plane_common/tasks/omnia_version_configuration.yml new file mode 100644 index 000000000..a59004cd7 --- /dev/null +++ b/control_plane/roles/control_plane_common/tasks/omnia_version_configuration.yml @@ -0,0 +1,71 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +- name: Create default directory to store omnia files + file: + path: "{{ omnia_default_path }}" + state: directory + mode: "{{ mount_dir_perm }}" + +- name: Check omnia_version is already present + stat: + path: "{{ dest_omnia_version }}" + register: omnia_version_stat + +- block: + - name: Include {{ dest_omnia_version }} as variable + include_vars: "{{ dest_omnia_version }}" + + - name: Check omnia_version in repository + command: grep "omnia_version:" "{{ src_omnia_version }}" + changed_when: false + register: omnia_version_check + + - name: Set new_omnia_version + set_fact: + new_omnia_version: "{{ omnia_version_check.stdout | regex_replace('omnia_version: ','') }}" + + - name: Do you want to proceed with upgrade + pause: + prompt: "{{ enable_upgrade_prompt_msg }}" + register: enable_upgrade_input + when: new_omnia_version | float > omnia_version | float + + - name: Abort control_plane.yml execution + fail: + msg: "{{ enable_upgrade_fail_msg }}" + when: + - enable_upgrade_input.user_input is defined + - enable_upgrade_input.user_input | lower != "yes" + + - name: Enabling control plane upgrade + fail: + msg: "{{ enable_upgrade_warn_msg }}" + when: + - enable_upgrade_input.user_input is defined + - enable_upgrade_input.user_input | lower == "yes" + when: omnia_version_stat.stat.exists + +- name: Set omnia_installation_path in omnia_version + replace: + path: "{{ src_omnia_version }}" + regexp: "^(.*)omnia_installation_path(.*)" + replace: "omnia_installation_path: {{ playbook_dir.split('control_plane')[0] }}" + +- name: Copy omnia_version + copy: + src: "{{ src_omnia_version }}" + dest: "{{ dest_omnia_version }}" + mode: "{{ mount_dir_perm }}" \ No newline at end of file diff --git a/control_plane/roles/control_plane_common/vars/main.yml b/control_plane/roles/control_plane_common/vars/main.yml index 87209f16f..03a1d91ff 100644 --- a/control_plane/roles/control_plane_common/vars/main.yml +++ b/control_plane/roles/control_plane_common/vars/main.yml @@ -201,7 +201,6 @@ success_network_type: " Success. Network_interface_type has valid values" fail_network_type: " Failed. Give valid value in network_interface_type " success_awx_web_support: "awx_web_support validated" fail_awx_web_support: "Failed. awx_web_support only accepts boolean values true or false" -omnia_default_path: /opt/omnia # Usage: ip_metric.yml public_metric: 101 @@ -336,4 +335,12 @@ rhsm_git_repo: "https://github.com/openstack/ansible-role-redhat-subscription.gi rhsm_git_stable_commit: "0f7ac2a" rhsm_git_dest: "{{ playbook_dir }}/roles/control_plane_rhsm/files/openstack-rhsm" portal_file_path: "{{ playbook_dir }}/roles/control_plane_rhsm/files/openstack-rhsm/tasks/portal.yml" -satellite_file_path: "{{ playbook_dir }}/roles/control_plane_rhsm/files/openstack-rhsm/tasks/satellite.yml" \ No newline at end of file +satellite_file_path: "{{ playbook_dir }}/roles/control_plane_rhsm/files/openstack-rhsm/tasks/satellite.yml" + +# Usage: omnia_version_configuration.yml +omnia_default_path: /opt/omnia +src_omnia_version: "{{ playbook_dir.split('control_plane')[0] }}/.metadata/omnia_version" +dest_omnia_version: "/opt/omnia/omnia_version" +enable_upgrade_prompt_msg: "Detected omnia_version change from {{ omnia_version }} to {{ new_omnia_version }}. Do you want to proceed with upgrade? Enter 'yes' to proceed or 'no' to abort execution" +enable_upgrade_fail_msg: "Failed. Unable to proceed to with control plane upgrade. Re-run control_plane.yml to perform upgrade." +enable_upgrade_warn_msg: "Currently enabling upgrade is not supported. This will be supported in upcoming omnia version" \ No newline at end of file diff --git a/control_plane/roles/powervault/tasks/fetch_powervault_credentials.yml b/control_plane/roles/powervault/tasks/fetch_powervault_credentials.yml new file mode 100644 index 000000000..598226255 --- /dev/null +++ b/control_plane/roles/powervault/tasks/fetch_powervault_credentials.yml @@ -0,0 +1,48 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +- name: Check if {{ login_input_filename }} file is encrypted + command: cat {{ login_input_filename }} + changed_when: false + no_log: true + register: config_content + run_once: true + +- name: Decrpyt {{ login_input_filename }} + command: >- + ansible-vault decrypt {{ login_input_filename }} + --vault-password-file {{ login_vault_filename }} + when: "'$ANSIBLE_VAULT;' in config_content.stdout" + changed_when: false + run_once: true + +- name: Include variable file {{ login_input_filename }} + include_vars: "{{ login_input_filename }}" + no_log: true + run_once: true + +- name: Encrypt {{ login_input_filename }} + command: >- + ansible-vault encrypt {{ login_input_filename }} + --vault-password-file {{ login_vault_filename }} + changed_when: false + when: "'$ANSIBLE_VAULT;' in config_content.stdout" + run_once: true + +- name: Update {{ login_input_filename }} permission + file: + path: "{{ login_input_filename }}" + mode: "{{ file_permission }}" + run_once: true diff --git a/control_plane/roles/powervault/tasks/main.yml b/control_plane/roles/powervault/tasks/main.yml index 46cfc3710..0c43d4aac 100644 --- a/control_plane/roles/powervault/tasks/main.yml +++ b/control_plane/roles/powervault/tasks/main.yml @@ -13,15 +13,20 @@ # limitations under the License. --- -- name: Set powervault credentials +- name: Include variable file base_vars.yml + include_vars: "{{ base_pv_file }}" + no_log: true + +- name: Fetch powervault credentials when awx_web_support is false + include_tasks: fetch_powervault_credentials.yml + when: not awx_web_support + +- name: Set powervault credentials in AWX set_fact: powervault_username: "{{ lookup('env','ANSIBLE_NET_USERNAME') }}" powervault_password: "{{ lookup('env','ANSIBLE_NET_PASSWORD') }}" no_log: true - -- name: Include variable file base_vars.yml - include_vars: "{{ base_pv_file }}" - no_log: true + when: awx_web_support - name: Include variable file for powervault include_vars: "{{ pv_file }}" @@ -44,4 +49,4 @@ - name: Set snmp parameters include_tasks: set_snmp.yml - when: snmp_trap_destination != "" \ No newline at end of file + when: snmp_trap_destination != "" diff --git a/control_plane/roles/powervault/vars/main.yml b/control_plane/roles/powervault/vars/main.yml index c0a8a0b88..db28ba21d 100644 --- a/control_plane/roles/powervault/vars/main.yml +++ b/control_plane/roles/powervault/vars/main.yml @@ -59,4 +59,9 @@ login_pv_vault_file: "{{ playbook_dir }}/control_plane/input_params/.login_vault # Usage: sas_map.yml temp1: 10 -t1: 1 \ No newline at end of file +t1: 1 + +# Usage: fetch_powervault_credentials.yml +login_input_filename: "{{ playbook_dir }}/input_params/login_vars.yml" +login_vault_filename: "{{ playbook_dir }}/input_params/.login_vault_key" +file_permission: 0644 diff --git a/control_plane/test/inventory.txt b/control_plane/test/inventory.txt new file mode 100644 index 000000000..92d6f469f --- /dev/null +++ b/control_plane/test/inventory.txt @@ -0,0 +1,2 @@ +[node] +xx:xx:xx:xx \ No newline at end of file diff --git a/control_plane/test/nodes_validation.yml b/control_plane/test/nodes_validation.yml new file mode 100644 index 000000000..6c05c4f05 --- /dev/null +++ b/control_plane/test/nodes_validation.yml @@ -0,0 +1,66 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +- name: Start + hosts: nodes + vars_files: + - /root/omnia/control_plane/input_params/base_vars.yml + - test_nodes_vars.yml + + + tasks: + + - name: Check hostname + command: hostnamectl + changed_when: false + register: node_host + + - name: Assert if the hostname is correct + assert: + that: + - "'{{ provision_os }}' in node_host.stdout" + success_msg: "{{ hostname_success_msg }}" + fail_msg: "{{ hostname_fail_msg }}" + + - name: Check dns resolv conf + command: cat /etc/resolv.conf + changed_when: false + register: relov_info + + - name: Check if resolv conf is properly configured + assert: + that: + - ' "nameserver 10.8.8.8" in relov_info.stdout' + - ' "nameserver 10.7.7.7" in relov_info.stdout' + success_msg: "{{ resolv_conf_success_msg }}" + fail_msg: "{{ resolv_conf_fail_msg }}" + + - name: Check if internet connectivity is there in the nodes + wait_for: + host: "{{ hostname }}" + port: "{{ port_no }}" + state: started + delay: "{{ internet_delay }}" + timeout: "{{ internet_timeout }}" + msg: "{{ internet_status }}" + register: internet_value + + - name: Print serial number for each node + command: dmidecode --string system-serial-number + changed_when: false + register: serial_number + + - debug: + msg: "{{ serial_number }}" \ No newline at end of file diff --git a/control_plane/test/passwd.txt b/control_plane/test/passwd.txt new file mode 100644 index 000000000..b59c9f53c --- /dev/null +++ b/control_plane/test/passwd.txt @@ -0,0 +1 @@ +qwertyui \ No newline at end of file diff --git a/control_plane/test/passwordless_connectivity.yml b/control_plane/test/passwordless_connectivity.yml new file mode 100644 index 000000000..a16001d3d --- /dev/null +++ b/control_plane/test/passwordless_connectivity.yml @@ -0,0 +1,38 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +- name: Setup Password Less authentication from MS to Nodes + hosts: localhost + connection: local + vars_file: + - test_nodes_vars.yml + + tasks: + - name: Delete the existing rsa file + shell: rm -rf {{ ssh_path }} + changed_when: false + + - name: Generate Keygen + shell: | + ssh-keygen -t rsa -b 4096 -N '' <<<$'\n' + changed_when: false + + - name: Initiate password-less authentication + shell: | + sshpass -f passwd.txt ssh-copy-id root@{{ item }} + changed_when: false + with_items: + - "{{ lookup('file','{{ provisioned_path }}').splitlines() }}" + ignore_errors: true \ No newline at end of file diff --git a/control_plane/test/test_device_discovery.yml b/control_plane/test/test_device_discovery.yml new file mode 100644 index 000000000..0179ee607 --- /dev/null +++ b/control_plane/test/test_device_discovery.yml @@ -0,0 +1,334 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +# Test case to verify inventory groups are present in AWX UI (idrac, ethernet, inifiniband, powervault) +- name: OMNIA_1.3_Device_Discovery_TC_005 + hosts: localhost + connection: local + + vars_files: + - test_vars/test_device_discovery_vars.yml + - ../input_params/base_vars.yml + tasks: + + - name: Execute get pods command + command: "kubectl get pods -n {{ awx_namespace }}" + changed_when: true + register: k8s_pods + run_once: true + ignore_errors: true + tags: TC_005 + + - name: Get awx pod + set_fact: + awx_pods: "{{ item | regex_search(awx_pod_regex) | trim }}" + idrac_status: true + with_items: + - "{{ k8s_pods.stdout_lines }}" + run_once: true + when: item | regex_search(awx_pod_item_regex) + tags: TC_005 + + - name: Get awx cluster ip + shell: "kubectl get svc awx-ui -n {{ awx_namespace }} -o jsonpath='{.spec.clusterIP}'" + register: awx_cluster_ip + changed_when: false + ignore_errors: true + tags: TC_005 + + - name: Get AWX admin password + shell: "kubectl get secret awx-admin-password -n {{ awx_namespace }} -o jsonpath='{.data.password}' | base64 --decode" + register: awx_admin_password + changed_when: false + ignore_errors: true + tags: TC_005 + + - name: Execute awx get inventory hosts command + command: "awx --conf.host http://{{ awx_cluster_ip.stdout }}:8052 --conf.username admin --conf.password {{ awx_admin_password.stdout }} --conf.insecure hosts list --inventory {{ item }} -f human --filter 'name'" + register: idrac_hosts + with_items: + - "idrac_inventory" + - "infiniband_inventory" + - "ethernet_inventory" + - "powervault_inventory" + run_once: true + changed_when: false + tags: TC_005 + + - name: Verify inventory are present in AWX UI + assert: + that: + - item.stdout_lines[0] | regex_search("name") + fail_msg: "{{ item.item }} - {{ inventory_fail_msg }}" + success_msg: "{{ item.item }} - {{ inventory_success_msg }}" + with_items: + - "{{ idrac_hosts.results }}" + changed_when: false + tags: TC_005 + +# Test case to validate iDRAC Devices +- name: OMNIA_1.3_Device_Discovery_TC_007 + hosts: localhost + connection: local + + vars_files: + - test_vars/test_inventory_vars.yml + - ../input_params/base_vars.yml + tasks: + + - name: Execute get pods command + command: "kubectl get pods -n {{ awx_namespace }}" + changed_when: true + register: k8s_pods + run_once: true + ignore_errors: true + tags: TC_007 + + - name: Get awx pod + set_fact: + awx_pods: "{{ item | regex_search(awx_pod_regex) | trim }}" + with_items: + - "{{ k8s_pods.stdout_lines }}" + run_once: true + when: item | regex_search(awx_pod_item_regex) + changed_when: false + tags: TC_007 + + - name: Get awx cluster ip + shell: "kubectl get svc awx-ui -n {{ awx_namespace }} -o jsonpath='{.spec.clusterIP}'" + register: awx_cluster_ip + changed_when: false + tags: TC_007 + + - name: Get AWX admin password + shell: "kubectl get secret awx-admin-password -n {{ awx_namespace }} -o jsonpath='{.data.password}' | base64 --decode" + register: awx_admin_password + changed_when: false + ignore_errors: true + tags: TC_007 + + - name: Execute awx get inventory hosts command + command: "awx --conf.host http://{{ awx_cluster_ip.stdout }}:8052 --conf.username admin --conf.password {{ awx_admin_password.stdout }} --conf.insecure hosts list --inventory {{ idrac_inventory_name }} -f human --filter 'name'" + changed_when: true + register: idrac_hosts + run_once: true + tags: TC_007 + + - name: List of iDRAC host + include_tasks: "{{ validation_script_path ​}}" + with_items: + - "{{ idrac_hosts.stdout_lines[2:] }}" + when: idrac_hosts.stdout_lines | length > 2 + ignore_errors: true + tags: TC_007 + + - name: Empty iDRAC hosts + debug: + msg: "{{ empty_host_err }}" + when: idrac_hosts.stdout_lines | length < 3 + failed_when: false + tags: TC_007 + +# Test case to validate Infiniband Devices +- name: OMNIA_1.3_Device_Discovery_TC_002 + hosts: localhost + connection: local + + vars_files: + - test_vars/test_inventory_vars.yml + - ../input_params/base_vars.yml + tasks: + + - name: Execute get pods command + command: "kubectl get pods -n {{ awx_namespace }}" + changed_when: true + register: k8s_pods + run_once: true + ignore_errors: true + tags: TC_002 + + - name: Get awx pod + set_fact: + awx_pods: "{{ item | regex_search(awx_pod_regex) | trim }}" + with_items: + - "{{ k8s_pods.stdout_lines }}" + run_once: true + when: item | regex_search(awx_pod_item_regex) + changed_when: false + tags: TC_002 + + - name: Get awx cluster ip + shell: "kubectl get svc awx-ui -n {{ awx_namespace }} -o jsonpath='{.spec.clusterIP}'" + register: awx_cluster_ip + changed_when: false + tags: TC_002 + + - name: Get AWX admin password + shell: "kubectl get secret awx-admin-password -n {{ awx_namespace }} -o jsonpath='{.data.password}' | base64 --decode" + register: awx_admin_password + changed_when: false + ignore_errors: true + tags: TC_002 + + - name: Execute awx get inventory hosts command + command: "awx --conf.host http://{{ awx_cluster_ip.stdout }}:8052 --conf.username admin --conf.password {{ awx_admin_password.stdout }} --conf.insecure hosts list --inventory {{ ib_inventory_name }} -f human --filter 'name'" + changed_when: true + register: infiniband_hosts + run_once: true + ignore_errors: true + tags: TC_002 + + - name: List of infiniband hosts + include_tasks: "{{ validation_script_path ​}}" + with_items: + - "{{ infiniband_hosts.stdout_lines[2:] }}" + when: infiniband_hosts.stdout_lines | length > 2 + ignore_errors: true + tags: TC_002 + + - name: Empty infiniband hosts + debug: + msg: "{{ empty_host_err }}" + when: infiniband_hosts.stdout_lines | length < 3 + failed_when: false + tags: TC_002 + +# Test case to validate Ethernet Devices +- name: OMNIA_1.3_Device_Discovery_TC_001 + hosts: localhost + connection: local + + vars_files: + - test_vars/test_inventory_vars.yml + - ../input_params/base_vars.yml + tasks: + + - name: Execute get pods command + command: "kubectl get pods -n {{ awx_namespace }}" + changed_when: true + register: k8s_pods + run_once: true + ignore_errors: true + tags: TC_001 + + - name: Get awx pod + set_fact: + awx_pods: "{{ item | regex_search(awx_pod_regex) | trim }}" + with_items: + - "{{ k8s_pods.stdout_lines }}" + run_once: true + when: item | regex_search(awx_pod_item_regex) + changed_when: false + tags: TC_001 + + - name: Get awx cluster ip + shell: "kubectl get svc awx-ui -n {{ awx_namespace }} -o jsonpath='{.spec.clusterIP}'" + register: awx_cluster_ip + changed_when: false + tags: TC_001 + + - name: Get AWX admin password + shell: "kubectl get secret awx-admin-password -n {{ awx_namespace }} -o jsonpath='{.data.password}' | base64 --decode" + register: awx_admin_password + changed_when: false + ignore_errors: true + tags: TC_001 + + - name: Execute awx get inventory hosts command + command: "awx --conf.host http://{{ awx_cluster_ip.stdout }}:8052 --conf.username admin --conf.password {{ awx_admin_password.stdout }} --conf.insecure hosts list --inventory {{ ethernet_inventory_name }} -f human --filter 'name'" + changed_when: true + register: ethernet_hosts + run_once: true + ignore_errors: true + tags: TC_001 + + - name: List of ethernet hosts + include_tasks: "{{ validation_script_path ​}}" + with_items: + - "{{ ethernet_hosts.stdout_lines[2:] }}" + when: ethernet_hosts.stdout_lines | length > 2 + ignore_errors: true + tags: TC_001 + + - name: Empty ethernet hosts + debug: + msg: "{{ empty_host_err }}" + when: ethernet_hosts.stdout_lines | length < 3 + failed_when: false + tags: TC_001 + +# Test case to validate Powervault Devices +- name: OMNIA_1.3_Device_Discovery_TC_003 + hosts: localhost + connection: local + + vars_files: + - test_vars/test_inventory_vars.yml + - ../input_params/base_vars.yml + tasks: + + - name: Execute get pods command + command: "kubectl get pods -n {{ awx_namespace }}" + changed_when: true + register: k8s_pods + run_once: true + ignore_errors: true + tags: TC_003 + + - name: Get awx pod + set_fact: + awx_pods: "{{ item | regex_search(awx_pod_regex) | trim }}" + with_items: + - "{{ k8s_pods.stdout_lines }}" + run_once: true + when: item | regex_search(awx_pod_item_regex) + changed_when: false + tags: TC_003 + + - name: Get awx cluster ip + shell: "kubectl get svc awx-ui -n {{ awx_namespace }} -o jsonpath='{.spec.clusterIP}'" + register: awx_cluster_ip + changed_when: false + tags: TC_003 + + - name: Get AWX admin password + shell: "kubectl get secret awx-admin-password -n {{ awx_namespace }} -o jsonpath='{.data.password}' | base64 --decode" + register: awx_admin_password + changed_when: false + ignore_errors: true + tags: TC_003 + + - name: Execute awx get inventory hosts command + command: "awx --conf.host http://{{ awx_cluster_ip.stdout }}:8052 --conf.username admin --conf.password {{ awx_admin_password.stdout }} --conf.insecure hosts list --inventory {{ pv_inventory_name }} -f human --filter 'name'" + changed_when: true + register: powervault_hosts + run_once: true + ignore_errors: true + tags: TC_003 + + - name: List of powervault hosts + include_tasks: "{{ validation_script_path ​}}" + with_items: + - "{{ powervault_hosts.stdout_lines[2:] }}" + when: powervault_hosts.stdout_lines | length > 2 + ignore_errors: true + tags: TC_003 + + - name: Empty powervault hosts + debug: + msg: "{{ empty_host_err }}" + when: powervault_hosts.stdout_lines | length < 3 + failed_when: false + tags: TC_003 \ No newline at end of file diff --git a/control_plane/test/test_me4_validation.yml b/control_plane/test/test_me4_validation.yml new file mode 100644 index 000000000..73eacd2eb --- /dev/null +++ b/control_plane/test/test_me4_validation.yml @@ -0,0 +1,101 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +- block: + + # Testcase me4_TC_04 + # When server_shared_path and client_shared_path provided + - name: Check server_shared_path + assert: + that: + - "'pass' in output.stdout" + success_msg: "{{powervault_success_msg}}" + fail_msg: " {{powervault_fail_msg}}" + + # Testcase me4_TC_06 + # Test case to validate multiple powervaults are configured with the same details for which first powervault is already configured. + - name: Check server_shared_path + assert: + that: + - "'pass' in output.stdout" + success_msg: "{{powervault_success_msg}}" + fail_msg: " {{powervault_fail_msg}}" + + # Testcase me4_TC_07 + # Test case to validate the show disk command. + + - name: Execute show disks + command: show disks + register: disks + assert: + that: + -"'Success' in disks.stdout" + success_msg: "Connected Disks are {{ disks }}" + fail_msg: "{{ fail_disk }}" + tags: executing_show_disks + + # Testcase me4_TC_08 + # Test case to validate the show disk-groups command. + + - name: Execute show disk-groups + command: show disk-groups + register: disk-groups + assert: + that: + -"'Success' in disk-groups.stdout" + debug: + success_msg: "Connected Disk-groups are {{ disk-groups }}" + fail_msg: "{{ fail_disk_group }}" + tags: executing_disk_groups + + # Testcase me4_TC_09 + # Test case to validate the show pools command. + + - name: Execute show pools + command: show pools + register: pools + assert: + that: + -"'Success' in pools.stdout" + debug: + success_msg: "The pools are {{ pools }}" + fail_msg: "{{ fail_pools }}" + tags: executing_show_pools + + # Testcase me4_TC_10 + # Test case to validate the show volumes command. + + - name: Execute show volumes + command: show volumes + register: volumes + assert: + that: + -"'Success' in volumes.stdout" + success_msg: "The volumes are {{ volumes }}" + fail_msg: "{{ fail_volumes }}" + tags: executing_show_volumes + + # Testcase me4_TC_11 + # Test case to validate the remove disk groups command. + + - name: Execute remove disk groups + command: remove disk-groups {{ disk_name }} + register: remove_disk_groups + assert: + that: + -"'Success' in remove_disk_groups.stdout" + success_msg: "The remove disk groups are {{ remove_disk_groups }}" + fail_msg: "{{ fail_disk_group }}" + tags: executing_remove_disk_groups diff --git a/control_plane/test/test_me5.yml b/control_plane/test/test_me5.yml new file mode 100644 index 000000000..b9282beb8 --- /dev/null +++ b/control_plane/test/test_me5.yml @@ -0,0 +1,372 @@ +# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +# Testcase OMNIA_1.3_PV_me5_TC_001 +# Test case to validate configuration of disks and disk-groups + +- name: PV_me5_TC_01 + hosts: powervault + connection: local + tags: TC_001 + gather_subset: + - 'min' + vars_files: + - ../input_params/base_vars.yml + - ../input_params/powervault_vars.yml + - test_vars/test_powervault_vars.yml + tasks: + + - name: Check login_vars file is encrypted + command: cat {{ login_vars_path }} + changed_when: false + register: config_content + tags: always + + - name: Decrpyt login_vars.yml + command: >- + ansible-vault decrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + when: "'$ANSIBLE_VAULT;' in config_content.stdout" + tags: always + + - name: Include variable file login_vars.yml + include_vars: "{{ login_vars_path }}" + tags: always + + - name: Get auth string + shell: echo -n {{ powervault_username }}_{{ powervault_password }} | sha256sum + register: auth_string_output + changed_when: false + failed_when: false + tags: always + + - name: Set the powervault username and password + set_fact: + auth_string: "{{ auth_string_output }}" + no_log: true + tags: always + + - name: Encypt login file + command: >- + ansible-vault encrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + tags: always + + - name: Ping the powervault device to validate connectivity + command: ping -c1 {{ inventory_hostname }} + register: validate_login + changed_when: false + failed_when: false + tags: VERIFY_OMNIA_01 + + - name: Validate the powervault connectivity + assert: + that: + - "'ping' in validate_login.stdout" + success_msg: "{{ connectivity_success_msg }}" + fail_msg: "{{ connectivity_failure_msg }}" + tags: VERIFY_OMNIA_01 + + - name: Get session key + uri: + url: https://{{ inventory_hostname }}/api/login/{{ auth_string.stdout | replace(" -", "") }} + method: GET + headers: + {'datatype': 'json'} + validate_certs: no + timeout: 100 + register: session_key + tags: Verify_session + + - name: Execute show disk-groups command + uri: + url: https://{{ inventory_hostname }}/api/show/disk-groups + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: system_info + tags: Verify_show_disk_groups + + - name: Execute show disks command + uri: + url: https://{{ inventory_hostname }}/api/show/disks + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: disks_info + tags: Verify_show_disks + + - block: + - name: Execute default validation script + include_tasks: "{{ me5_validation_script_path }}" + tags: Execute_Validation_Script + +# Testcase OMNIA_1.3_PV_TC_002 +# Test case to validate configuration of pools and volumes + +- name: PV_me5_TC_02 + hosts: powervault + connection: local + tags: TC_002 + gather_subset: + - 'min' + vars_files: + - ../input_params/base_vars.yml + - ../input_params/powervault_vars.yml + - test_vars/test_powervault_vars.yml + tasks: + + - name: Check login_vars file is encrypted + command: cat {{ login_vars_path }} + changed_when: false + register: config_content + tags: always + + - name: Decrpyt login_vars.yml + command: >- + ansible-vault decrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + when: "'$ANSIBLE_VAULT;' in config_content.stdout" + tags: always + + - name: Include variable file login_vars.yml + include_vars: "{{ login_vars_path }}" + tags: always + + - name: Get auth string + shell: echo -n {{ powervault_me5_username }}_{{ powervault_me5_password }} | sha256sum + register: auth_string_output + changed_when: false + failed_when: false + tags: always + + - name: Set the powervault username and password + set_fact: + powervault_username: "{{ powervault_me5_username }}" + powervault_password: "{{ powervault_me5_password }}" + auth_string: "{{ auth_string_output }}" + no_log: true + tags: always + + - name: Encypt login file + command: >- + ansible-vault encrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + tags: always + + - name: Ping the powervault device to validate connectivity + + command: ping -c1 {{ inventory_hostname }} + register: validate_login + changed_when: false + failed_when: false + tags: VERIFY_OMNIA_01 + + - name: Validate the powervault connectivity + assert: + that: + - "'ping' in validate_login.stdout" + success_msg: "{{ connectivity_success_msg }}" + fail_msg: "{{ connectivity_failure_msg }}" + tags: VERIFY_OMNIA_01 + + - name: Get session key + uri: + url: https://{{ inventory_hostname }}/api/login/{{ auth_string.stdout | replace(" -", "") }} + method: GET + headers: + {'datatype': 'json'} + validate_certs: no + timeout: 100 + register: session_key + tags: Verify_session + + - name: Execute show pools command + uri: + url: https://{{ inventory_hostname }}/api/show/pools + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: pools_info + tags: Verify_show_pools + + - name: Execute show volumes command + uri: + url: https://{{ inventory_hostname }}/api/show/volumes + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: volumes_info + tags: Verify_show_volumes + + - block: + - name: Execute default validation script + include_tasks: "{{ me5_validation_script_path }}" + tags: Execute_Validation_Script + + +# Testcase OMNIA_1.3_PV_me5_TC_003 +# Test case to valiate the system behaviour with server_shared_path and client_shared_path are empty + +- name: PV_me5_TC_03 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me5_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_003 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: check_failure + assert: + that: + - '"non-zero return code" in output.msg' + debug: + success_msg: "{{ shared_path_pass_msg }}" + fail_msg: "{{ shared_path_fail_msg }}" + tags: Checking_failures + when: server_shared_path == null and client_shared_path == null + +# Testcase OMNIA_1.3_PV_me5_TC_004 +# Test case to valiate the system behaviour with server_shared_path is empty and client_shared_path is provided + +- name: PV_me5_TC_04 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me5_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_004 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: check_failure + assert: + that: + - '"non-zero return code" in output.msg' + debug: + success_msg: "{{ server_shared_path_pass_msg }}" + fail_msg: "{{ server_shared_path_fail_msg }}" + tags: Checking_failures + when: server_shared_path == null + +# Testcase OMNIA_1.3_PV_me5_TC_005 +# Test case to valiate the system behaviour with server_shared_path is provided and client_shared_path is empty + +- name: PV_me5_TC_05 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me5_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_005 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: check_failure + assert: + that: + - '"non-zero return code" in output.msg' + debug: + success_msg: "{{ client_shared_path_pass_msg }}" + fail_msg: "{{ client_shared_path_fail_msg }}" + tags: Checking_failures + when: client_shared_path == null + +# Testcase OMNIA_1.3_PV_me5_TC_006 +# Test case to valiate the system behaviour with server_shared_path and client_shared_path is provided + +- name: PV_me5_TC_006 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me5_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_006 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: Execute default validation script + include_tasks: "{{ me5_validation_script_path }}" + tags: Execute_Validation_Script diff --git a/control_plane/test/test_me5_validation.yml b/control_plane/test/test_me5_validation.yml new file mode 100644 index 000000000..29dbbad52 --- /dev/null +++ b/control_plane/test/test_me5_validation.yml @@ -0,0 +1,72 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +- block: + + # Testcase OMNIA_1.3_PV_me5_TC_001 + # Test case to validate configuration of disks and disk-groups + + - name: Validating the powervault disk groups + assert: + that: + - system_info.json['disk-groups'][0]['name'] == "{{ powervault_disk_group_name }}" + success_msg: "{{ disk_groups_pass }}" + fail_msg: "{{ disk_groups_fail }}" + tags: Validate_disk_groups + + - name: Validating the powervault disks + assert: + that: + - disks_info.json['drives'][0]['disk-group'] == "{{ powervault_disk_group_name }}" + success_msg: "{{ disks_pass }}" + + fail_msg: "{{ disks_fail }}" + tags: Validate_disks + tags: TC_001 + +- block: + + # Testcase OMNIA_1.3_PV_TC_002 + # Test case to validate configuration of pools and volumes + + - name: Validating the powervault pools + assert: + that: + - pools_info.json['pools'][0]['disk-groups'][0]['pool'] == "{{ powervault_pool }}" + success_msg: "{{ pools_pass }}" + fail_msg: "{{ pools_fail }}" + tags: Validate_pools + + - name: Validating the powervault volumes + assert: + that: + - volumes_info.json['volumes'][0]['volume-name'] in "{{ powervault_volumes }}" + success_msg: "{{ volumes_pass }}" + fail_msg: "{{ volumes_fail }}" + tags: Validate_volumes + tags: TC_002 + +- block: + # Testcase OMNIA_1.3_PV_me5_TC_006 + # When server_shared_path and client_shared_path provided + - name: Check server_shared_path + assert: + that: + - "'pass' in output.stdout" + success_msg: "{{powervault_success_msg}}" + fail_msg: " {{powervault_fail_msg}}" + tags: TC_006 + + diff --git a/control_plane/test/test_nodes.yml b/control_plane/test/test_nodes.yml new file mode 100644 index 000000000..a0281a9fd --- /dev/null +++ b/control_plane/test/test_nodes.yml @@ -0,0 +1,29 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +- name: Create node inventory file + hosts: localhost + connection: local + vars_file: + - test_nodes_vars.yml + + tasks: + - name: Create an inventory file + shell: echo "{{ lookup('file','{{ provisioned_path }}') }}" >> inventory + changed_when: false + + - name: Run test_nodes + command: ansible-playbook nodes_validation.yml -i inventory + changed_when: false \ No newline at end of file diff --git a/control_plane/test/test_powervault_me4.yml b/control_plane/test/test_powervault_me4.yml new file mode 100644 index 000000000..2dfb91500 --- /dev/null +++ b/control_plane/test/test_powervault_me4.yml @@ -0,0 +1,393 @@ +# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +# Testcase OMNIA_1.3_PV_me4_TC_001 +# Test case to validate configuration of disks and disk-groups + +- name: PV_me4_TC_01 + hosts: powervault + connection: local + tags: TC_001 + gather_subset: + - 'min' + vars_files: + - ../input_params/base_vars.yml + - ../input_params/powervault_vars.yml + - test_vars/test_powervault_vars.yml + tasks: + - name: Check login_vars file is encrypted + command: cat {{ login_vars_path }} + changed_when: false + register: config_content + tags: always + + - name: Decrpyt login_vars.yml + command: >- + ansible-vault decrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + when: "'$ANSIBLE_VAULT;' in config_content.stdout" + tags: always + + - name: Include variable file login_vars.yml + include_vars: "{{ login_vars_path }}" + tags: always + + - name: Get auth string + shell: echo -n {{ powervault_username }}_{{ powervault_password }} | sha256sum + register: auth_string_output + changed_when: false + failed_when: false + tags: always + + - name: Set the powervault username and password + set_fact: + pv_username: "{{ powervault_username }}" + pv_password: "{{ powervault_password }}" + auth_string: "{{ auth_string_output }}" + no_log: true + tags: always + + - name: Encypt login file + command: >- + ansible-vault encrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + tags: always + + - name: Ping the powervault device to validate connectivity + command: ping -c1 {{ inventory_hostname }} + register: validate_login + changed_when: false + failed_when: false + tags: VERIFY_OMNIA_01 + + - name: Validate the powervault connectivity + assert: + that: + - "'ping' in validate_login.stdout" + success_msg: "{{ connectivity_success_msg }}" + fail_msg: "{{ connectivity_failure_msg }}" + tags: VERIFY_OMNIA_01 + + - name: Get session key + uri: + url: https://{{ inventory_hostname }}/api/login/{{ auth_string.stdout | replace(" -", "") }} + method: GET + headers: + {'datatype': 'json'} + validate_certs: no + timeout: 100 + register: session_key + tags: Verify_session + + - name: Execute show disk-groups command + uri: + url: https://{{ inventory_hostname }}/api/show/disk-groups + + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: system_info + tags: Verify_show_disk_groups + + - name: Validating the powervault disk groups + assert: + that: + - loop: system_info.json['disk-groups']['name'] == "{{ powervault_disk_group_name }}" + success_msg: "{{ disk_groups_pass }}" + fail_msg: "{{ disk_groups_fail }}" + tags: Validate_disk_groups + + - name: Execute show disks command + uri: + url: https://{{ inventory_hostname }}/api/show/disks + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: disks_info + tags: Verify_show_disks + + + - name: Validating the povervault disks + + assert: + that: + - disks_info.json['drives'][0]['disk-group'] == "{{ powervault_disk_group_name }}" + success_msg: "{{ disks_pass }}" + + fail_msg: "{{ disks_fail }}" + tags: Validate_disks + +# Testcase OMNIA_1.3_PV_TC_002 +# Test case to validate configuration of pools and volumes + +- name: PV_me4_TC_02 + hosts: powervault + connection: local + tags: TC_002 + gather_subset: + - 'min' + vars_files: + - ../input_params/base_vars.yml + - ../input_params/powervault_vars.yml + - test_vars/test_powervault_vars.yml + tasks: + - name: Check login_vars file is encrypted + command: cat {{ login_vars_path }} + changed_when: false + register: config_content + tags: always + + - name: Decrpyt login_vars.yml + command: >- + ansible-vault decrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + when: "'$ANSIBLE_VAULT;' in config_content.stdout" + tags: always + + - name: Include variable file login_vars.yml + include_vars: "{{ login_vars_path }}" + tags: always + + - name: Get auth string + shell: echo -n {{ powervault_username }}_{{ powervault_password }} | sha256sum + register: auth_string_output + changed_when: false + failed_when: false + tags: always + + - name: Set the powervault username and password + set_fact: + powervault_username: "{{ powervault_username }}" + powervault_password: "{{ powervault_password }}" + auth_string: "{{ auth_string_output }}" + no_log: true + tags: always + + - name: Encypt login file + command: >- + ansible-vault encrypt {{ login_vars_path }} + --vault-password-file {{ login_vars_vault_path }} + changed_when: false + tags: always + + - name: Ping the powervault device to validate connectivity + + command: ping -c1 {{ inventory_hostname }} + register: validate_login + changed_when: false + failed_when: false + tags: VERIFY_OMNIA_01 + + - name: Validate the powervault connectivity + assert: + that: + - "'ping' in validate_login.stdout" + success_msg: "{{ connectivity_success_msg }}" + fail_msg: "{{ connectivity_failure_msg }}" + tags: VERIFY_OMNIA_01 + + - name: Get session key + uri: + url: https://{{ inventory_hostname }}/api/login/{{ auth_string.stdout | replace(" -", "") }} + method: GET + headers: + {'datatype': 'json'} + validate_certs: no + timeout: 100 + register: session_key + tags: Verify_session + + - name: Execute show pools command + uri: + url: https://{{ inventory_hostname }}/api/show/pools + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: pools_info + tags: Verify_show_pools + + + - name: Validating the powervault pools + assert: + that: + - pools_info.json['pools'][0]['disk-groups'][0]['pool'] == "{{ powervault_pool }}" + success_msg: "{{ pools_pass }}" + fail_msg: "{{ pools_fail }}" + tags: Validate_pools + + - name: Execute show volumes command + uri: + url: https://{{ inventory_hostname }}/api/show/volumes + method: GET + body_format: json + validate_certs: no + use_proxy: no + headers: + {'sessionKey': "{{ session_key.json.status[0].response }}", 'datatype':'json'} + register: volumes_info + tags: Verify_show_volumes + + + # Testcase OMNIA_1.3_PV_me4_TC_003 +# Test case to valiate the system behaviour with server_shared_path and client_shared_path are empty + +- name: PV_me4_TC_03 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me4_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_003 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: check_failure + assert: + that: + - '"non-zero return code" in output.msg' + debug: + success_msg: "{{ shared_path_pass_msg }}" + fail_msg: "{{ shared_path_fail_msg }}" + tags: Checking_failures + when: server_shared_path == null and client_shared_path == null + +# Testcase OMNIA_1.3_PV_me4_TC_004 +# Test case to valiate the system behaviour with server_shared_path is empty and client_shared_path is provided + +- name: PV_me4_TC_04 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me4_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_004 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: check_failure + assert: + that: + - '"non-zero return code" in output.msg' + debug: + success_msg: "{{ server_shared_path_pass_msg }}" + fail_msg: "{{ server_shared_path_fail_msg }}" + tags: Checking_failures + when: server_shared_path == null + +# Testcase OMNIA_1.3_PV_me4_TC_005 +# Test case to valiate the system behaviour with server_shared_path is provided and client_shared_path is empty + +- name: PV_me4_TC_05 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me4_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_005 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: check_failure + assert: + that: + - '"non-zero return code" in output.msg' + debug: + success_msg: "{{ client_shared_path_pass_msg }}" + fail_msg: "{{ client_shared_path_fail_msg }}" + tags: Checking_failures + when: client_shared_path == null + +# Testcase OMNIA_1.3_PV_me4_TC_006 +# Test case to valiate the system behaviour with server_shared_path and client_shared_path is provided + +- name: PV_me4_TC_006 + hosts: localhost + connection: local + vars_files: + - "test_vars/test_me4_vars.yml" + - "../input_params/powervault_vars.yml" + tags: TC_006 + tasks: + - name: Check Hostname + command: hostnamectl + register: hostdetails + + - block: + - name: Execute powervault playbook using AWX collections + vars: + inventory_name: "{{ powervault_inventory_name }}" + template_name: "{{ template_value }}" + job_template_name: "{{ job_name }}" + playbook_path: "{{ powervault_playbook_path }}" + delete_status: false + include_tasks: "{{ awx_script_path }}" + + - block: + - name: Execute default validation script + include_tasks: "{{ me4_validation_script_path }}" + tags: Execute_Validation_Script + + diff --git a/control_plane/test/test_vars/test_device_discovery_vars.yml b/control_plane/test/test_vars/test_device_discovery_vars.yml new file mode 100644 index 000000000..2974ec52a --- /dev/null +++ b/control_plane/test/test_vars/test_device_discovery_vars.yml @@ -0,0 +1,38 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +awx_namespace: "awx" +awx_pod_regex: "awx-([A-Za-z0-9]{10})-([A-Za-z0-9]{5})" +awx_pod_item_regex: "awx-([A-Za-z0-9]{10})-([A-Za-z0-9]{5})" +idrac_inventory_name: "idrac_inventory" +ib_inventory_name: "infiniband_inventory" +ethernet_inventory_name: "ethernet_inventory" +pv_inventory_name: "powervault_inventory" +empty_host_err: "No hosts available" +inventory_fail_msg: "Inventory creation is failed" +inventory_success_msg: "Inventory creation is successful" +validation_script_path: "test_inventory_validation.yml" +idrac_search_key: "Integrated Dell Remote Access Controller" +ethernet_search_key: "Dell EMC Networking OS10-Enterprise" +infiniband_search_key: "MLNX-OS" +idrac_fail_msg: "iDRAC IP validation is failed" +idrac_success_msg: "iDRAC IP validation is success" +ethernet_fail_msg: "Ethernet IP validation is failed" +ethernet_success_msg: "Ethernet IP validation is success" +infiniband_fail_msg: "Infiniband IP validation is failed" +infiniband_success_msg: "Infiniband IP validation is success" +powervault_fail_msg: "Powervault IP validation is failed" +powervault_success_msg: "Powervault IP validation is success" +failed_msg: "Failed." \ No newline at end of file diff --git a/control_plane/test/test_vars/test_me4_vars.yml b/control_plane/test/test_vars/test_me4_vars.yml new file mode 100644 index 000000000..daadb632e --- /dev/null +++ b/control_plane/test/test_vars/test_me4_vars.yml @@ -0,0 +1,49 @@ +# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +# vars file for test_powervault.yml file + +input_params_folder: "../input_params" +Control_plane_dir: "../" +me4_validation_script_path: test_me4_validation.yml +me4_vars_file_path: /test_vars/test_me4_vars.yml +login_vars_path: "../input_params/login_vars.yml" +login_vars_vault_path: "../input_params/.login_vault_key" +connectivity_success_msg: "Connection was successful" +connectivity_failure_msg: "Connectivity failed" +powervault_inventory_name: "test_powervault_me4_inventory" +template_value: "powervault_template" +job_name: "test_powervault_template" +powervault_playbook_path: "control_plane/powervault.yml" +awx_script_path: "test_powervault.yml" +powervault_var_path: "../input_params/powervault_vars.yml" +base_var_path: "../input_params/base_vars.yml" +disk_groups_pass: "Disk groups are validated successfully" +disk_groups_fail: "Disk groups are not validated successfully" +disks_pass: "Disks are validated successfully" +disks_fail: "Disks are not validated successfully" +pools_pass: "Pools are validated successfully" +pools_fail: "Pools are not validated successfully" +volumes_pass: "Volumes are validated successfully" +volumes_fail: "Volumes are not validated successfully" +powervault_vars_file: "../input_params/powevault_vars.yml" +shared_path_pass_msg: 'Since server_shared_path and client_shared_path are empty. Please provide valid paths.' +shared_path_fail_msg: 'Provided server_shared_path and client_shared_path are valid.' +server_shared_path_pass_msg: 'Since server_shared_path is empty please provide valid path' +server_shared_path_fail_msg: 'Provided server_shared_path and client_shared_path are valid' +client_shared_path_pass_msg: 'Since client_shared_path is empty please provide valid path' +client_shared_path_fail_msg: 'Provided server_shared_path and client_shared_path are valid' +powervault_success_msg: 'Powervault me4 is configured successfully' +powervault_fail_msg: 'Powervault me4 is not configured successfully' \ No newline at end of file diff --git a/control_plane/test/test_vars/test_me5_vars.yml b/control_plane/test/test_vars/test_me5_vars.yml new file mode 100644 index 000000000..c391b3714 --- /dev/null +++ b/control_plane/test/test_vars/test_me5_vars.yml @@ -0,0 +1,49 @@ +# Copyright 2021 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +# vars file for test_powervault.yml file + +input_params_folder: "../input_params" +Control_plane_dir: "../" +me5_validation_script_path: test_me5_validation.yml +me5_vars_file_path: /test_vars/test_me5_vars.yml +login_vars_path: "../input_params/login_vars.yml" +login_vars_vault_path: "../input_params/.login_vault_key" +connectivity_success_msg: "Connection was successful" +connectivity_failure_msg: "Connectivity failed" +powervault_inventory_name: "test_powervault_me5_inventory" +template_value: "powervault_template" +job_name: "test_powervault_template" +powervault_playbook_path: "control_plane/powervault.yml" +awx_script_path: "test_powervault.yml" +powervault_var_path: "../input_params/powervault_vars.yml" +base_var_path: "../input_params/base_vars.yml" +disk_groups_pass: "Disk groups are validated successfully" +disk_groups_fail: "Disk groups are not validated successfully" +disks_pass: "Disks are validated successfully" +disks_fail: "Disks are not validated successfully" +pools_pass: "Pools are validated successfully" +pools_fail: "Pools are not validated successfully" +volumes_pass: "Volumes are validated successfully" +volumes_fail: "Volumes are not validated successfully" +powervault_vars_file: "../input_params/powevault_vars.yml" +shared_path_pass_msg: 'Since server_shared_path and client_shared_path are empty. Please provide valid paths.' +shared_path_fail_msg: 'Provided server_shared_path and client_shared_path are valid.' +server_shared_path_pass_msg: 'Since server_shared_path is empty please provide valid path' +server_shared_path_fail_msg: 'Provided server_shared_path and client_shared_path are valid' +client_shared_path_pass_msg: 'Since client_shared_path is empty please provide valid path' +client_shared_path_fail_msg: 'Provided server_shared_path and client_shared_path are valid' +powervault_success_msg: 'Powervault me5 is configured successfully' +powervault_fail_msg: 'Powervault me5 is not configured successfully' \ No newline at end of file diff --git a/control_plane/test/test_vars/test_nodes_vars.yml b/control_plane/test/test_vars/test_nodes_vars.yml new file mode 100644 index 000000000..70347145b --- /dev/null +++ b/control_plane/test/test_vars/test_nodes_vars.yml @@ -0,0 +1,29 @@ +# Copyright 2022 Dell Inc. or its subsidiaries. All Rights Reserved. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +--- + +internet_delay: 0 +internet_tomeput: 10 +hostname: github.com +port_no: 22 + +internet_status: "Failed. No Internet Connection. Make sure network is up." + +hostname_success_msg: "Hostname is correct" +hostname_fail_msg: "Hostname is incorrect" +resolv_conf_success_msg: "Resolv conf is properly configured" +resolv_conf_fail_msg: "Resolv conf is not properly configured" + +provisioned_path: "/root/omnia/control_plane/roles/collect_node_info/files/provisioned_hosts.yml" +ssh_path: "/root/.ssh/id_rsa" \ No newline at end of file diff --git a/omnia_config.yml b/omnia_config.yml index 2fc3beaba..f0c4fadee 100644 --- a/omnia_config.yml +++ b/omnia_config.yml @@ -134,17 +134,18 @@ powervault_ip: # This variable is used for supportig NFS bolt-on on login_node, compute, and manager nodes # Values should be entered in JSON format only. +# If mount_option values are empty, NFS client will be mounted with these values "nosuid,rw,sync,hard,intr 0 0" # For enabling NFS bolt-on support, atleast one list of valid values should be provided. # Example for single mount file system: # nfs_client_params: -# - { server_ip: , server_share_path: < server_mount>, client_share_path: } +# - { server_ip: 198.168.0.1, server_share_path: "/mnt/share", client_share_path: "/mnt/mount", client_mount_options: "nosuid,rw,sync,hard,intr 0 0" } # Example for suppoting multiple mount points: # nfs_client_params: -# - { server_ip: , server_share_path: < server_mount1>, client_share_path: } -# - { server_ip: , server_share_path: < server_mount2>, client_share_path: } +# - { server_ip: 198.168.0.1, server_share_path: "/mnt/share1", client_share_path: "/mnt/mount1", client_mount_options: "nosuid,rw,sync,hard,intr 0 0" } +# - { server_ip: 198.168.0.1, server_share_path: "/mnt/share2", client_share_path: "/mnt/mount2", client_mount_options: "nosuid,rw,sync,hard,intr 0 0" } # Example for multiple mount file system: # nfs_client_params: -# - { server_ip: , server_share_path: < server_mount1>, client_share_path: } -# - { server_ip: , server_share_path: < server_mount2>, client_share_path: } +# - { server_ip: 198.168.0.1, server_share_path: "/mnt/share1", client_share_path: "/mnt/mount1", client_mount_options: "nosuid,rw,sync,hard,intr 0 0" } +# - { server_ip: 198.168.0.2, server_share_path: "/mnt/share2", client_share_path: "/mnt/mount2", client_mount_options: "nosuid,rw,sync,hard,intr 0 0" } nfs_client_params: - - { server_ip: , server_share_path: , client_share_path: } + - { server_ip: , server_share_path: , client_share_path: , client_mount_options: } \ No newline at end of file diff --git a/roles/cluster_validation/tasks/fetch_nfs_client_params.yml b/roles/cluster_validation/tasks/fetch_nfs_client_params.yml index e958db4aa..c70470a94 100644 --- a/roles/cluster_validation/tasks/fetch_nfs_client_params.yml +++ b/roles/cluster_validation/tasks/fetch_nfs_client_params.yml @@ -34,6 +34,13 @@ success_msg: "{{ client_share_path_success_msg }}" fail_msg: "{{ client_share_path_fail_msg }}" +- name: Verify client_mount_options variable declaration + assert: + that: + - item.client_mount_options is defined + success_msg: "{{ client_mount_options_success_msg }}" + fail_msg: "{{ client_mount_options_fail_msg }}" + - name: Verify server_share_path assert: that: diff --git a/roles/cluster_validation/tasks/validations.yml b/roles/cluster_validation/tasks/validations.yml index a8ec87d6f..47f26223f 100644 --- a/roles/cluster_validation/tasks/validations.yml +++ b/roles/cluster_validation/tasks/validations.yml @@ -35,6 +35,7 @@ nfs_node_status: true when: - groups['nfs_node'] is defined + - groups['nfs_node'] | length | int > 0 - name: NFS group to contain exactly 1 node assert: diff --git a/roles/cluster_validation/vars/main.yml b/roles/cluster_validation/vars/main.yml index 61c3f8db6..b742e50b3 100644 --- a/roles/cluster_validation/vars/main.yml +++ b/roles/cluster_validation/vars/main.yml @@ -137,3 +137,5 @@ server_share_path_fail_msg: "Failed, Declare server_share_path variable in nfs_c client_share_path_success_msg: "Successfully verified client_share_path variable declaration" client_share_path_fail_msg: "Failed, Declare client_share_path variable in nfs_client_params of omnia_config, please refer comments in omnia_config.yml" server_share_path_len_success_msg: "server_share_path validated successfully" +client_mount_options_success_msg: "client_mount_options declaration validated successfully" +client_mount_options_fail_msg: "Failed, please declare client_mount_options variable in nfs_client_params" \ No newline at end of file diff --git a/roles/nfs_client/tasks/nfs_client.yml b/roles/nfs_client/tasks/nfs_client.yml index 7663a1bcb..eb32baa26 100644 --- a/roles/nfs_client/tasks/nfs_client.yml +++ b/roles/nfs_client/tasks/nfs_client.yml @@ -13,16 +13,25 @@ # limitations under the License. --- +- name: Initialize variable for client_mount_options + set_fact: + mount_option_status: false + - name: Initialize variable when client_share_path value is not given set_fact: - client_mount_path: "{{ item.server_share_path }}" + client_mount_path: "{{ item.server_share_path }}" when: item.client_share_path | default("", true) | length < 1 - name: Initialize variable when client_share_path value is given set_fact: - client_mount_path: "{{ item.client_share_path }}" + client_mount_path: "{{ item.client_share_path }}" when: item.client_share_path | default("", true) | length > 1 +- name: Verify client_mount_options value + set_fact: + mount_option_status: true + when: item.client_mount_options | default("", true) | length > 1 + - name: Package installation for NFS package: name: "{{ nfs_packages }}" @@ -51,18 +60,25 @@ msg: "{{ client_mount_path }} {{ client_folder_msg }}" - block: - - name: Mount NFS client with server_share_path as client_share_path + - name: Mount NFS client command: "mount -t nfs {{ item.server_ip }}:{{ item.server_share_path }} {{ client_mount_path }}" changed_when: true args: warn: false rescue: - - name: Status message of NFS mount with server_share_path as client_share_path + - name: Status message of NFS mount fail: msg: "{{ mount_message }} on IP {{ item.server_ip }}" + + - name: NFS mount configuration when client_mount_options were specified + lineinfile: + path: "{{ fstab_path }}" + line: "{{ item.server_ip }}:{{ item.server_share_path }} {{ client_mount_path }} nfs {{ item.client_mount_options }}" + when: mount_option_status - - name: NFS mount configuration with server_share_path as client_share_path + - name: NFS mount configuration when client_mount_options were not specified lineinfile: path: "{{ fstab_path }}" - line: "{{ item.server_ip }}:{{ item.server_share_path }} {{ client_mount_path }} nfs nosuid,rw,sync,hard,intr 0 0" + line: "{{ item.server_ip }}:{{ item.server_share_path }} {{ client_mount_path }} nfs {{ default_client_mount_options }}" + when: not mount_option_status when: '"{{ item.server_ip }}:{{ item.server_share_path }} on {{ client_mount_path }}" not in mounted_share.stdout' \ No newline at end of file diff --git a/roles/nfs_client/vars/main.yml b/roles/nfs_client/vars/main.yml index 58e276131..183bae778 100644 --- a/roles/nfs_client/vars/main.yml +++ b/roles/nfs_client/vars/main.yml @@ -20,4 +20,5 @@ nfs_packages: file_perm: 0777 fstab_path: "/etc/fstab" mount_message: "Failed to mount NFS client, Make sure NFS server is running" -client_folder_msg: "is a stale folder. Please give some other folder for mount" \ No newline at end of file +client_folder_msg: "is a stale folder. Please give some other folder for mount" +default_client_mount_options: "nosuid,rw,sync,hard,intr 0 0" \ No newline at end of file