summaryrefslogtreecommitdiffstats
path: root/ansible_collections/dellemc/powerflex/roles/powerflex_tb
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-18 05:52:22 +0000
commit38b7c80217c4e72b1d8988eb1e60bb6e77334114 (patch)
tree356e9fd3762877d07cde52d21e77070aeff7e789 /ansible_collections/dellemc/powerflex/roles/powerflex_tb
parentAdding upstream version 7.7.0+dfsg. (diff)
downloadansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.tar.xz
ansible-38b7c80217c4e72b1d8988eb1e60bb6e77334114.zip
Adding upstream version 9.4.0+dfsg.upstream/9.4.0+dfsg
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'ansible_collections/dellemc/powerflex/roles/powerflex_tb')
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/README.md210
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/defaults/main.yml8
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_spec.yml85
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_specs.yml65
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/main.yml25
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/converge.yml35
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/molecule.yml1
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/converge.yml19
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/molecule.yml1
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/var_values.yml7
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/converge.yml20
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/inventory4
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/molecule.yml11
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb.yml8
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb3x.yml81
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb4x.yml69
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/main.yml31
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/set_tb_ips.yml29
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/uninstall_tb.yml97
-rw-r--r--ansible_collections/dellemc/powerflex/roles/powerflex_tb/vars/main.yml6
20 files changed, 812 insertions, 0 deletions
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/README.md b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/README.md
new file mode 100644
index 000000000..dec61fec9
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/README.md
@@ -0,0 +1,210 @@
+# powerflex_tb
+
+Role to manage the installation and uninstallation of Powerflex TB.
+
+## Table of contents
+
+* [Requirements](#requirements)
+* [Ansible collections](#ansible-collections)
+* [Role Variables](#role-variables)
+* [Examples](#examples)
+* [Notes](#notes)
+* [Usage instructions](#usage-instructions)
+* [Author Information](#author-information)
+
+## Requirements
+
+```
+ansible
+python
+```
+
+## Ansible collections
+
+Collections required to use the role.
+
+```
+dellemc.powerflex
+```
+
+## Role Variables
+
+<table>
+<thead>
+ <tr>
+ <th>Name</th>
+ <th>Required</th>
+ <th>Description</th>
+ <th>Choices</th>
+ <th>Type</th>
+ <th>Default Value</th>
+ </tr>
+</thead>
+<tbody>
+ <tr>
+ <td>hostname</td>
+ <td>true</td>
+ <td>IP or FQDN of the PowerFlex gateway.</td>
+ <td></td>
+ <td>str</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>username</td>
+ <td>true</td>
+ <td>The username of the PowerFlex gateway.</td>
+ <td></td>
+ <td>str</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>password</td>
+ <td>true</td>
+ <td>The password of the PowerFlex gateway.</td>
+ <td></td>
+ <td>str</td>
+ <td></td>
+ </tr>
+ <tr>
+ <td>port</td>
+ <td>false</td>
+ <td>Port of the PowerFlex gateway.</td>
+ <td></td>
+ <td>int</td>
+ <td>443</td>
+ </tr>
+ <tr>
+ <td>validate_certs</td>
+ <td>false</td>
+ <td>If C(false), the SSL certificates will not be validated.<br>Configure C(false) only on personally controlled sites where self-signed certificates are used.</td>
+ <td></td>
+ <td>bool</td>
+ <td>false</td>
+ </tr>
+ <tr>
+ <td>timeout</td>
+ <td>false</td>
+ <td>Timeout.</td>
+ <td></td>
+ <td>int</td>
+ <td>120</td>
+ </tr>
+ <tr>
+ <td>powerflex_common_file_install_location</td>
+ <td>false</td>
+ <td>Location of installation and rpm gpg files to be installed.
+ <br>The required, compatible installation software package based on the operating system of the node.
+ <br> The files can be downloaded from the Dell Product support page for PowerFlex software.</td>
+ <td></td>
+ <td>str</td>
+ <td>/var/tmp</td>
+ </tr>
+ <tr>
+ <td>powerflex_tb_state</td>
+ <td>false</td>
+ <td>Specify state of TB.<br></td>
+ <td>absent, present</td>
+ <td>str</td>
+ <td>present</td>
+ </tr>
+ <tr>
+ <td>powerflex_tb_primary_name</td>
+ <td>false</td>
+ <td>Name of the primary TB.<br></td>
+ <td></td>
+ <td>str</td>
+ <td>primary_tb</td>
+ </tr>
+ <tr>
+ <td>powerflex_tb_secondary_name</td>
+ <td>false</td>
+ <td>Name of the secondary TB.<br></td>
+ <td></td>
+ <td>str</td>
+ <td>secondary_tb</td>
+ </tr>
+ <tr>
+ <td>powerflex_tb_cluster_mode</td>
+ <td>false</td>
+ <td>Mode of the cluster.<br></td>
+ <td>ThreeNodes, FiveNodes</td>
+ <td>str</td>
+ <td>ThreeNodes</td>
+ </tr>
+ <tr>
+ <td>powerflex_tb_cert_password</td>
+ <td>false</td>
+ <td>The CLI certificate password for login to the primary MDM.<br></td>
+ <td></td>
+ <td>str</td>
+ <td></td>
+ </tr>
+</tbody>
+</table>
+
+## Examples
+----
+```
+ - name: Install and configure PowerFlex TB
+ ansible.builtin.import_role:
+ name: "powerflex_tb"
+ vars:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ validate_certs: "{{ validate_certs }}"
+ port: "{{ port }}"
+ powerflex_tb_primary_name: "primary_tb"
+ powerflex_tb_secondary_name: "secondary_tb"
+ powerflex_tb_cluster_mode: "ThreeNodes"
+ powerflex_common_file_install_location: "/var/tmp"
+ powerflex_tb_state: present
+
+ - name: Uninstall powerflex TB
+ ansible.builtin.import_role:
+ name: "powerflex_tb"
+ vars:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ validate_certs: "{{ validate_certs }}"
+ port: "{{ port }}"
+ powerflex_tb_state: 'absent'
+
+```
+
+## Notes
+----
+
+- As a pre-requisite for PowerFlex 3.6, the Gateway must be installed.
+- For PowerFlex 4.x, after installing the TB perform initial configuration steps on PowerFlex Manager GUI. These steps can be found in Install and Update of Dell PowerFlex 4.x from Dell Support page.
+
+## Usage instructions
+----
+### To install all dependency packages, including TB, on node:
+- PowerFlex 3.6:
+ ```
+ ansible-playbook -i inventory site.yml
+ ```
+- PowerFlex 4.5:
+ ```
+ ansible-playbook -i inventory site_powerflex45.yml
+ ```
+
+### To uninstall TB:
+- PowerFlex 3.6:
+ ```
+ ansible-playbook -i inventory uninstall_powerflex.yml
+ ```
+- PowerFlex 4.5:
+ ```
+ ansible-playbook -i inventory uninstall_powerflex45.yml
+ ```
+
+Sample playbooks and inventory can be found in the playbooks directory.
+
+## Author Information
+------------------
+
+Dell Technologies <br>
+Ananthu S Kuttattu (ansible.team@Dell.com) 2023
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/defaults/main.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/defaults/main.yml
new file mode 100644
index 000000000..b4b0b5a30
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/defaults/main.yml
@@ -0,0 +1,8 @@
+---
+# defaults file for powerflex_tb
+powerflex_tb_primary_name: primary_tb
+powerflex_tb_secondary_name: secondary_tb
+powerflex_tb_cluster_mode: "ThreeNodes"
+file_glob_name: mdm
+powerflex_role_environment:
+ MDM_IP: "{{ powerflex_tb_mdm_ips }}"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_spec.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_spec.yml
new file mode 100644
index 000000000..f3072df80
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_spec.yml
@@ -0,0 +1,85 @@
+---
+argument_specs:
+ main:
+ short_description: Role to manage the installation and uninstallation of Powerflex TB.
+ description:
+ - Role to manage the installation and uninstallation of Powerflex TB.
+ options:
+ hostname:
+ required: true
+ type: str
+ description: IP or FQDN of the PowerFlex gateway.
+ username:
+ required: true
+ type: str
+ description: The username of the PowerFlex gateway.
+ password:
+ required: true
+ type: str
+ description: The password of the PowerFlex gateway.
+ port:
+ type: int
+ description: Port of the PowerFlex gateway.
+ default: 443
+ validate_certs:
+ description:
+ - If C(false), the SSL certificates will not be validated.
+ - Configure C(false) only on personally controlled sites where self-signed certificates are used.
+ type: bool
+ default: false
+ timeout:
+ description: Timeout.
+ type: int
+ default: 120
+ powerflex_common_file_install_location:
+ description:
+ - Location of installation and rpm gpg files to be installed.
+ - The required, compatible installation software package based on the operating system of the node.
+ type: str
+ default: /var/tmp
+ powerflex_tb_state:
+ description:
+ - Specify state of TB.
+ type: str
+ choices: ['absent', 'present']
+ default: present
+ powerflex_tb_primary_name:
+ required: true
+ description:
+ - Name of the primary TB.
+ type: str
+ default: 'primary_tb'
+ powerflex_tb_secondary_name:
+ required: true
+ description:
+ - Name of the secondary TB.
+ type: str
+ default: 'secondary_tb'
+ powerflex_tb_cluster_mode:
+ required: true
+ description:
+ - Mode of the cluster.
+ choices: ['ThreeNodes', 'FiveNodes']
+ type: str
+ default: 'ThreeNodes'
+ powerflex_protection_domain_name:
+ description:
+ - Name of the protection domain.
+ type: str
+ default: 'tb_protection_domain'
+ powerflex_fault_sets:
+ description:
+ - List of fault sets.
+ type: list
+ default: ['fs1', 'fs2', 'fs3']
+ powerflex_media_type:
+ description:
+ - Media type of the storage pool.
+ type: str
+ choices: ['SSD', 'HDD', 'TRANSITIONAL']
+ default: 'SSD'
+ powerflex_storage_pool_name:
+ description:
+ - Name of the storage pool.
+ type: str
+ default: 'tb_storage_pool'
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_specs.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_specs.yml
new file mode 100644
index 000000000..ac5a3e3ef
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/argument_specs.yml
@@ -0,0 +1,65 @@
+---
+argument_specs:
+ main:
+ short_description: Role to manage the installation and uninstallation of Powerflex TB.
+ description:
+ - Role to manage the installation and uninstallation of Powerflex TB.
+ options:
+ hostname:
+ required: true
+ type: str
+ description: IP or FQDN of the PowerFlex gateway.
+ username:
+ required: true
+ type: str
+ description: The username of the PowerFlex gateway.
+ password:
+ required: true
+ type: str
+ description: The password of the PowerFlex gateway.
+ port:
+ type: int
+ description: Port of the PowerFlex gateway.
+ default: 443
+ validate_certs:
+ description:
+ - If C(false), the SSL certificates will not be validated.
+ - Configure C(false) only on personally controlled sites where self-signed certificates are used.
+ type: bool
+ default: false
+ timeout:
+ description: Timeout.
+ type: int
+ default: 120
+ powerflex_common_file_install_location:
+ description:
+ - Location of installation and rpm gpg files to be installed.
+ - The required, compatible installation software package based on the operating system of the node.
+ type: str
+ default: /var/tmp
+ powerflex_tb_state:
+ description:
+ - Specify state of TB.
+ type: str
+ choices: ['absent', 'present']
+ default: present
+ powerflex_tb_primary_name:
+ description:
+ - Name of the primary TB.
+ type: str
+ default: 'primary_tb'
+ powerflex_tb_secondary_name:
+ description:
+ - Name of the secondary TB.
+ type: str
+ default: 'secondary_tb'
+ powerflex_tb_cluster_mode:
+ description:
+ - Mode of the cluster.
+ choices: ['ThreeNodes', 'FiveNodes']
+ type: str
+ default: 'ThreeNodes'
+ powerflex_tb_cert_password:
+ description:
+ - The CLI certificate password for login to the primary MDM.
+ type: str
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/main.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/main.yml
new file mode 100644
index 000000000..c3179cd1e
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/meta/main.yml
@@ -0,0 +1,25 @@
+---
+galaxy_info:
+ author: Ananthu S Kuttattu
+ description: Role to manage the installation and uninstallation of Powerflex TB.
+ company: Dell Technologies
+ license: GPL-3.0-only
+ role_name: powerflex_tb
+ namespace: dellemc
+
+ min_ansible_version: "2.14.0"
+ platforms:
+ - name: EL
+ versions:
+ - "9"
+ - "8"
+ - name: Ubuntu
+ versions:
+ - jammy
+
+ - name: SLES
+ versions:
+ - "15SP3"
+ - "15SP4"
+
+ galaxy_tags: []
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/converge.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/converge.yml
new file mode 100644
index 000000000..77d00ec11
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/converge.yml
@@ -0,0 +1,35 @@
+---
+- name: TB installation
+ hosts: tb
+ vars_files:
+ - ../../../../playbooks/roles/vars_files/connection.yml
+ gather_facts: true
+ tasks:
+ - name: Install common packages
+ ansible.builtin.import_role:
+ name: powerflex_common
+
+ - name: "Install PowerFlex TieBreaker"
+ ansible.builtin.import_role:
+ name: "powerflex_tb"
+ vars:
+ powerflex_tb_state: present
+ register: powerflex_tb_results
+
+ - name: "Verifying installation package"
+ ansible.builtin.assert:
+ that:
+ - " 'Installed' in powerflex_common_install_package_output.results[0]"
+ when: not ansible_check_mode and powerflex_common_install_package_output.changed
+
+ - name: "Verifying cluster mode switch from 1 node to 3 node MDM cluster"
+ ansible.builtin.assert:
+ that:
+ - powerflex_tb_cluster_to_three_output.stdout == "Successfully switched the cluster mode."
+ when: not ansible_check_mode and powerflex_tb_cluster_to_three_output.changed and powerflex_tb_cluster_mode == "ThreeNodes"
+
+ - name: "Verifying cluster mode switch from 1 node to 5 node MDM cluster"
+ ansible.builtin.assert:
+ that:
+ - powerflex_tb_cluster_to_five_output.stdout == "Successfully switched the cluster mode."
+ when: not ansible_check_mode and powerflex_tb_cluster_to_five_output.changed and powerflex_tb_cluster_mode == "FiveNodes"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/molecule.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/molecule.yml
new file mode 100644
index 000000000..ed97d539c
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_installation/molecule.yml
@@ -0,0 +1 @@
+---
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/converge.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/converge.yml
new file mode 100644
index 000000000..986b270de
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/converge.yml
@@ -0,0 +1,19 @@
+---
+- name: TB uninstallation
+ hosts: tb
+ vars_files:
+ - ../../../../playbooks/roles/vars_files/connection.yml
+ gather_facts: true
+ tasks:
+ - name: "Uninstall powerflex TB"
+ register: powerflex_tb_uninstall_outputs
+ ansible.builtin.import_role:
+ name: "powerflex_tb"
+ vars:
+ powerflex_tb_state: 'absent'
+
+ - name: "Verifying remove the TB"
+ ansible.builtin.assert:
+ that:
+ - powerflex_tb_remove_primary_tb_output.stdout == "Successfully removed the standby MDM."
+ when: not ansible_check_mode and powerflex_tb_remove_primary_tb_output.changed
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/molecule.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/molecule.yml
new file mode 100644
index 000000000..ed97d539c
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/tb_uninstallation/molecule.yml
@@ -0,0 +1 @@
+---
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/var_values.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/var_values.yml
new file mode 100644
index 000000000..01397a639
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/var_values.yml
@@ -0,0 +1,7 @@
+---
+powerflex_tb_primary_name: primary_tb
+powerflex_tb_secondary_name: secondary_tb
+powerflex_tb_cluster_mode: "ThreeNodes"
+powerflex_protection_domain_name: "tb_protection_domain"
+powerflex_fault_sets: ['fs1', 'fs2', 'fs3']
+powerflex_storage_pool_name: "tb_storage_pool"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/converge.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/converge.yml
new file mode 100644
index 000000000..c9322f319
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/converge.yml
@@ -0,0 +1,20 @@
+---
+- name: Providing incorrect credentials for TB node
+ hosts: tb
+ vars_files:
+ - ../../../../playbooks/roles/vars_files/connection.yml
+ gather_facts: false
+ tasks:
+ - name: "Install and configure powerflex tb with wrong credentials"
+ ansible.builtin.import_role:
+ name: "powerflex_tb"
+ vars:
+ powerflex_tb_state: present
+ ignore_unreachable: true
+ ignore_errors: true
+ register: powerflex_tb_wrong_credentials_output
+
+ - name: "Verifying failure of install package with wrong credentials"
+ ansible.builtin.assert:
+ that:
+ - " 'Communication error' in powerflex_tb_primary_output.msg"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/inventory b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/inventory
new file mode 100644
index 000000000..391105e2b
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/inventory
@@ -0,0 +1,4 @@
+node0 ansible_host=10.2.2.2 ansible_port=22 ansible_ssh_pass=wrongpassword ansible_user=root
+
+[tb]
+node0
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/molecule.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/molecule.yml
new file mode 100644
index 000000000..805f92879
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/molecule/wrong_tb_credentials/molecule.yml
@@ -0,0 +1,11 @@
+---
+provisioner:
+ name: ansible
+ inventory:
+ links:
+ hosts: inventory
+ group_vars: ../../../../playbooks/roles/group_vars/
+ host_vars: ../../../../playbooks/roles/host_vars/
+scenario:
+ test_sequence:
+ - converge
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb.yml
new file mode 100644
index 000000000..504b3e920
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb.yml
@@ -0,0 +1,8 @@
+---
+- name: Install TB for PowerFlex below 4.x
+ ansible.builtin.include_tasks: install_tb3x.yml
+ when: powerflex_tb_scli_version[0] == '3'
+
+- name: Install TB for PowerFlex 4.x
+ ansible.builtin.include_tasks: install_tb4x.yml
+ when: powerflex_tb_scli_version[0] >= '4'
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb3x.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb3x.yml
new file mode 100644
index 000000000..e602351da
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb3x.yml
@@ -0,0 +1,81 @@
+---
+- name: Get configured MDM IP addresses
+ dellemc.powerflex.mdm_cluster:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ validate_certs: "{{ validate_certs }}"
+ state: "present"
+ register: powerflex_tb_mdm_ip_result
+ delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}"
+
+- name: Set fact - powerflex_mdm_ips
+ ansible.builtin.set_fact:
+ powerflex_tb_mdm_ips: "{{ powerflex_tb_mdm_ip_result.mdm_cluster_details.mdmAddresses | join(',') }}"
+
+- name: Include install_powerflex.yml
+ ansible.builtin.include_tasks: ../../powerflex_common/tasks/install_powerflex.yml
+
+- name: Login with password
+ ansible.builtin.command: scli --login --username {{ username }} --password "{{ password }}"
+ run_once: true
+ register: powerflex_tb_login_output
+ changed_when: powerflex_tb_login_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+
+- name: Add primary TB
+ dellemc.powerflex.mdm_cluster:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ validate_certs: "{{ validate_certs }}"
+ port: "{{ port }}"
+ mdm_name: "{{ powerflex_tb_primary_name }}"
+ standby_mdm:
+ mdm_ips:
+ - "{{ powerflex_tb_primary_ip }}"
+ role: "TieBreaker"
+ management_ips:
+ - "{{ powerflex_tb_primary_ip }}"
+ state: "present"
+ register: powerflex_tb_primary_output
+ delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}"
+
+- name: Add secondary TB
+ dellemc.powerflex.mdm_cluster:
+ hostname: "{{ hostname }}"
+ username: "{{ username }}"
+ password: "{{ password }}"
+ validate_certs: "{{ validate_certs }}"
+ port: "{{ port }}"
+ mdm_name: "{{ powerflex_tb_secondary_name }}"
+ standby_mdm:
+ mdm_ips:
+ - "{{ powerflex_tb_secondary_ip }}"
+ role: "TieBreaker"
+ management_ips:
+ - "{{ powerflex_tb_secondary_ip }}"
+ state: "present"
+ register: powerflex_tb_secondary_output
+ delegate_to: "{{ lookup('ansible.builtin.env', 'RUNON', default='localhost') }}"
+ when: powerflex_tb_secondary_ip is defined
+
+- name: Switch to cluster three node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "3_node" --add_slave_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}" --add_tb_ip "{{ powerflex_tb_primary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_to_three_output
+ changed_when: powerflex_tb_cluster_to_three_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_primary_output.mdm_cluster_details.clusterMode != "ThreeNodes" and powerflex_tb_cluster_mode == "ThreeNodes"
+
+- name: Switch to cluster five node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "5_node" --add_slave_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}","{{ powerflex_tb_mdm_tertiary_ip }}" --add_tb_ip "{{ powerflex_tb_primary_ip }}","{{ powerflex_tb_secondary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_to_five_output
+ changed_when: powerflex_tb_cluster_to_five_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_primary_output.mdm_cluster_details.clusterMode != "FiveNodes" and powerflex_tb_cluster_mode == "FiveNodes"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb4x.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb4x.yml
new file mode 100644
index 000000000..d34857ba4
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/install_tb4x.yml
@@ -0,0 +1,69 @@
+---
+- name: Set fact - powerflex_mdm_ips
+ ansible.builtin.set_fact:
+ powerflex_tb_mdm_ips: "{{ powerflex_tb_mdm_primary_ip }},{{ powerflex_tb_mdm_secondary_ip }}"
+ when: powerflex_tb_mdm_count | int == 2
+
+- name: Set fact - powerflex_mdm_ips
+ ansible.builtin.set_fact:
+ powerflex_tb_mdm_ips: "{{ powerflex_tb_mdm_primary_ip }},{{ powerflex_tb_mdm_secondary_ip }},{{ powerflex_tb_mdm_tertiary_ip }}"
+ when: powerflex_tb_mdm_count | int > 2
+
+- name: Include install_powerflex.yml
+ ansible.builtin.include_tasks: ../../powerflex_common/tasks/install_powerflex.yml
+
+- name: Login to primary MDM node
+ ansible.builtin.command: >
+ scli --login --p12_path /opt/emc/scaleio/mdm/cfg/cli_certificate.p12 --p12_password {{ powerflex_tb_cert_password }}
+ run_once: true
+ register: powerflex_tb_login_output
+ changed_when: powerflex_tb_login_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+
+- name: Add primary TB
+ ansible.builtin.command: >
+ scli --add_standby_mdm
+ --new_mdm_ip {{ powerflex_tb_primary_ip }}
+ --mdm_role tb
+ --new_mdm_name {{ powerflex_tb_primary_name }}
+ --new_mdm_management_ip {{ powerflex_tb_primary_ip }}
+ run_once: true
+ register: powerflex_tb_primary_output
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_primary_ip is defined
+ ignore_errors: true
+ changed_when: powerflex_tb_primary_output.rc == 0
+
+- name: Add secondary TB
+ ansible.builtin.command: >
+ scli --add_standby_mdm
+ --new_mdm_ip {{ powerflex_tb_secondary_ip }}
+ --mdm_role tb
+ --new_mdm_name {{ powerflex_tb_secondary_name }}
+ --new_mdm_management_ip {{ powerflex_tb_secondary_ip }}
+ register: powerflex_tb_secondary_output
+ run_once: true
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_secondary_ip is defined
+ ignore_errors: true
+ changed_when: powerflex_tb_secondary_output.rc == 0
+
+- name: Switch to cluster three node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "3_node" --add_secondary_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}" --add_tb_ip "{{ powerflex_tb_primary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_to_three_output
+ changed_when: powerflex_tb_cluster_to_three_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_mdm_cluster_mode[0] != "3_node" and powerflex_tb_cluster_mode == "ThreeNodes"
+
+- name: Switch to cluster five node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "5_node" --add_secondary_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}","{{ powerflex_tb_mdm_tertiary_ip }}" --add_tb_ip "{{ powerflex_tb_primary_ip }}","{{ powerflex_tb_secondary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_to_five_output
+ changed_when: powerflex_tb_cluster_to_five_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_mdm_cluster_mode[0] != "5_node" and powerflex_tb_cluster_mode == "FiveNodes"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/main.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/main.yml
new file mode 100644
index 000000000..f98c09ff1
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/main.yml
@@ -0,0 +1,31 @@
+---
+- name: Include set_tb_ips.yml
+ ansible.builtin.include_tasks: set_tb_ips.yml
+
+- name: Get SCli version
+ ansible.builtin.command: >
+ scli --query_cluster
+ register: powerflex_tb_scli_cluster_details
+ tags: register
+ changed_when: powerflex_tb_scli_cluster_details.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+
+- name: Extract the scli version
+ ansible.builtin.set_fact:
+ powerflex_tb_scli_version: "{{ input_query | ansible.builtin.regex_search('Version: (\\d+)\\.(\\d+)', '\\1\\2') }}"
+ vars:
+ input_query: "{{ powerflex_tb_scli_cluster_details.stdout }}"
+
+- name: Extract the cluster mode
+ ansible.builtin.set_fact:
+ powerflex_tb_mdm_cluster_mode: "{{ input_query | ansible.builtin.regex_search('Mode: (\\w+)', '\\1') }}"
+ vars:
+ input_query: "{{ powerflex_tb_scli_cluster_details.stdout }}"
+
+- name: Install TB
+ ansible.builtin.include_tasks: install_tb.yml
+ when: powerflex_tb_state == 'present'
+
+- name: Uninstall TB
+ ansible.builtin.include_tasks: uninstall_tb.yml
+ when: powerflex_tb_state == 'absent'
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/set_tb_ips.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/set_tb_ips.yml
new file mode 100644
index 000000000..34c0144d5
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/set_tb_ips.yml
@@ -0,0 +1,29 @@
+---
+- name: Set TB count
+ ansible.builtin.set_fact:
+ powerflex_tb_count: "{{ groups['tb'] | length }}"
+ powerflex_tb_mdm_count: "{{ groups['mdm'] | length }}"
+
+- name: Set fact - powerflex_tb_mdm_primary_ip and powerflex_tb_mdm_secondary_ip
+ ansible.builtin.set_fact:
+ powerflex_tb_mdm_primary_ip: "{{ hostvars[groups['mdm'][0]]['ansible_host'] }}"
+ powerflex_tb_mdm_primary_hostname: "{{ hostvars[groups['mdm'][0]]['inventory_hostname'] }}"
+ powerflex_tb_mdm_secondary_ip: "{{ hostvars[groups['mdm'][1]]['ansible_host'] }}"
+ powerflex_tb_mdm_secondary_hostname: "{{ hostvars[groups['mdm'][1]]['inventory_hostname'] }}"
+
+- name: Set fact - powerflex_tb_mdm_tertiary_ip
+ ansible.builtin.set_fact:
+ powerflex_tb_mdm_tertiary_ip: "{{ hostvars[groups['tb'][2]]['ansible_host'] }}"
+ powerflex_tb_mdm_tertiary_hostname: "{{ hostvars[groups['tb'][2]]['inventory_hostname'] }}"
+ when: "powerflex_tb_mdm_count | int > 2"
+
+- name: Set fact - powerflex_tb_primary
+ ansible.builtin.set_fact:
+ powerflex_tb_primary_ip: "{{ hostvars[groups['tb'][0]]['ansible_host'] }}"
+ powerflex_tb_primary_hostname: "{{ hostvars[groups['tb'][0]]['inventory_hostname'] }}"
+
+- name: Set fact - powerflex_tb_primary
+ ansible.builtin.set_fact:
+ powerflex_tb_secondary_ip: "{{ hostvars[groups['tb'][1]]['ansible_host'] }}"
+ powerflex_tb_secondary_hostname: "{{ hostvars[groups['tb'][1]]['inventory_hostname'] }}"
+ when: "powerflex_tb_count | int > 1"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/uninstall_tb.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/uninstall_tb.yml
new file mode 100644
index 000000000..b08bffed8
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/tasks/uninstall_tb.yml
@@ -0,0 +1,97 @@
+---
+# Switch from three or five to cluster one node for PowerFlex version 3.6
+- name: Login to primary MDM node of PowerFlex version 3.x
+ ansible.builtin.command: scli --login --username {{ username }} --password "{{ password }}"
+ run_once: true
+ register: powerflex_tb_login_output
+ changed_when: powerflex_tb_login_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_scli_version[0] == '3'
+
+- name: Switch cluster mode from three nodes to one node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "1_node" --remove_slave_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}" --remove_tb_ip "{{ powerflex_tb_primary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_to_one_output
+ changed_when: powerflex_tb_cluster_to_one_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_mdm_cluster_mode[0] == "3_node" and powerflex_tb_scli_version[0] == '3'
+
+- name: Switch cluster mode from five nodes to one node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "1_node" --remove_slave_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}","{{ powerflex_tb_mdm_tertiary_ip }}" --remove_tb_ip "{{ powerflex_tb_primary_ip }}","{{ powerflex_tb_secondary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_to_one_output
+ changed_when: powerflex_tb_cluster_to_one_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_mdm_cluster_mode[0] == "5_node" and powerflex_tb_scli_version[0] == '3'
+
+# Switch from three or five to cluster one node for PowerFlex version 4.5
+- name: Login to primary MDM node of PowerFlex version 4.5
+ ansible.builtin.command: >
+ scli --login --management_system_ip {{ hostname }} --username {{ username }} --password {{ password }}
+ run_once: true
+ register: powerflex_tb_login_output
+ changed_when: powerflex_tb_login_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_scli_version[0] >= '4'
+
+- name: Switch cluster mode from three nodes to one node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "1_node" --remove_secondary_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}" --remove_tb_ip "{{ powerflex_tb_primary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_three_to_one_output
+ changed_when: powerflex_tb_cluster_three_to_one_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_mdm_cluster_mode[0] == "3_node" and powerflex_tb_scli_version[0] >= '4'
+
+- name: Switch cluster mode from five nodes to one node
+ ansible.builtin.command: |
+ scli --switch_cluster_mode --cluster_mode "1_node" --remove_secondary_mdm_ip
+ "{{ powerflex_tb_mdm_secondary_ip }}","{{ powerflex_tb_mdm_tertiary_ip }}" --remove_tb_ip "{{ powerflex_tb_primary_ip }}","{{ powerflex_tb_secondary_ip }}"
+ run_once: true
+ register: powerflex_tb_cluster_five_to_one_output
+ changed_when: powerflex_tb_cluster_five_to_one_output.rc == 0
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_mdm_cluster_mode[0] == "5_node" and powerflex_tb_scli_version[0] >= '4'
+
+# Remove the standby MDMs
+- name: Remove primary tb from standby mdm
+ ansible.builtin.command: scli --remove_standby_mdm --remove_mdm_ip "{{ powerflex_tb_primary_ip }}"
+ run_once: true
+ register: powerflex_tb_remove_primary_tb_output
+ changed_when: powerflex_tb_remove_primary_tb_output.rc == 0
+ ignore_errors: true
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+
+- name: Remove secondary tb from standby mdm
+ ansible.builtin.command: scli --remove_standby_mdm --remove_mdm_ip "{{ powerflex_tb_secondary_ip }}"
+ run_once: true
+ register: powerflex_tb_remove_secondary_tb_output
+ changed_when: powerflex_tb_remove_secondary_tb_output.rc == 0
+ ignore_errors: true
+ delegate_to: "{{ powerflex_tb_mdm_primary_hostname }}"
+ when: powerflex_tb_secondary_ip is defined
+
+- name: Uninstall package
+ register: powerflex_tb_uninstall_output
+ environment:
+ I_AM_SURE: "{{ i_am_sure | int }}"
+ ansible.builtin.package:
+ name: "{{ item }}"
+ state: "absent"
+ with_items:
+ - EMC-ScaleIO-mdm
+ when: ansible_distribution in ("RedHat", "CentOS", "SLES")
+
+- name: Uninstall deb package
+ register: powerflex_tb_uninstall_output
+ ansible.builtin.apt:
+ name: "{{ item }}"
+ state: absent
+ with_items:
+ - EMC-ScaleIO-mdm
+ when: ansible_distribution == "Ubuntu"
diff --git a/ansible_collections/dellemc/powerflex/roles/powerflex_tb/vars/main.yml b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/vars/main.yml
new file mode 100644
index 000000000..aa01f740c
--- /dev/null
+++ b/ansible_collections/dellemc/powerflex/roles/powerflex_tb/vars/main.yml
@@ -0,0 +1,6 @@
+---
+# vars file for powerflex_tb
+file_glob_name: mdm
+file_gpg_name: RPM-GPG-KEY-ScaleIO
+powerflex_role_environment:
+ MDM_IP: "{{ powerflex_tb_mdm_ips }}"