--- # Copyright Red Hat, Inc. # 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. # OADP Setup # # Installs and configures OADP (OpenShift API for Data Protection) # with an S3-compatible storage backend. - name: Verify S3 credentials are provided ansible.builtin.fail: msg: >- cifmw_openshift_adp_s3_access_key and cifmw_openshift_adp_s3_secret_key are required. Deploy an S3 backend first (e.g. deploy_minio role). when: >- cifmw_openshift_adp_s3_access_key is not defined or cifmw_openshift_adp_s3_secret_key is not defined - name: Print setup header ansible.builtin.debug: msg: - "========================================" - "OADP Setup" - "========================================" - "OADP Namespace: {{ cifmw_openshift_adp_namespace }}" - "OADP Channel: {{ cifmw_openshift_adp_channel }}" - "S3 Namespace: {{ cifmw_openshift_adp_s3_namespace }}" - "S3 Bucket: {{ cifmw_openshift_adp_s3_bucket }}" - "Node Agent (Kopia): {{ cifmw_openshift_adp_enable_node_agent }}" - name: Create OADP namespace kubernetes.core.k8s: api_version: v1 kind: Namespace name: "{{ cifmw_openshift_adp_namespace }}" state: present - name: Create OperatorGroup for OADP kubernetes.core.k8s: state: present definition: apiVersion: operators.coreos.com/v1 kind: OperatorGroup metadata: name: openshift-adp-operator-group namespace: "{{ cifmw_openshift_adp_namespace }}" spec: targetNamespaces: - "{{ cifmw_openshift_adp_namespace }}" - name: Create Subscription for OADP operator kubernetes.core.k8s: state: present definition: apiVersion: operators.coreos.com/v1alpha1 kind: Subscription metadata: name: redhat-oadp-operator namespace: "{{ cifmw_openshift_adp_namespace }}" spec: channel: "{{ cifmw_openshift_adp_channel }}" installPlanApproval: Automatic name: redhat-oadp-operator source: redhat-operators sourceNamespace: openshift-marketplace - name: Wait for OADP operator to be ready kubernetes.core.k8s_info: api_version: v1 kind: Pod namespace: "{{ cifmw_openshift_adp_namespace }}" label_selectors: - control-plane=controller-manager wait: true wait_timeout: 300 wait_condition: type: Ready status: "True" register: _operator_wait retries: 30 delay: 10 until: _operator_wait.resources | length > 0 - name: Create cloud credentials secret kubernetes.core.k8s: state: present definition: apiVersion: v1 kind: Secret metadata: name: cloud-credentials namespace: "{{ cifmw_openshift_adp_namespace }}" type: Opaque stringData: cloud: | [default] aws_access_key_id={{ cifmw_openshift_adp_s3_access_key }} aws_secret_access_key={{ cifmw_openshift_adp_s3_secret_key }} no_log: true - name: Get S3 API route kubernetes.core.k8s_info: api_version: route.openshift.io/v1 kind: Route name: minio-api namespace: "{{ cifmw_openshift_adp_s3_namespace }}" register: _s3_api_route - name: Create DataProtectionApplication kubernetes.core.k8s: state: present definition: apiVersion: oadp.openshift.io/v1alpha1 kind: DataProtectionApplication metadata: name: velero namespace: "{{ cifmw_openshift_adp_namespace }}" spec: configuration: velero: defaultPlugins: - openshift - aws - csi nodeAgent: enable: "{{ cifmw_openshift_adp_enable_node_agent | bool }}" uploaderType: kopia backupLocations: - velero: provider: aws default: true objectStorage: bucket: "{{ cifmw_openshift_adp_s3_bucket }}" prefix: "{{ cifmw_openshift_adp_s3_prefix }}" config: region: "{{ cifmw_openshift_adp_s3_region }}" s3ForcePathStyle: "{{ cifmw_openshift_adp_s3_force_path_style | lower }}" s3Url: "https://{{ _s3_api_route.resources[0].spec.host }}" insecureSkipTLSVerify: "{{ cifmw_openshift_adp_s3_insecure_skip_tls | lower }}" credential: name: cloud-credentials key: cloud - name: Wait for Velero pod to be ready kubernetes.core.k8s_info: api_version: v1 kind: Pod namespace: "{{ cifmw_openshift_adp_namespace }}" label_selectors: - app.kubernetes.io/name=velero wait: true wait_timeout: 300 wait_condition: type: Ready status: "True" register: _velero_wait retries: 30 delay: 10 until: _velero_wait.resources | length > 0 - name: Wait for node-agent pods to be ready kubernetes.core.k8s_info: api_version: v1 kind: Pod namespace: "{{ cifmw_openshift_adp_namespace }}" label_selectors: - app.kubernetes.io/name=node-agent wait: true wait_timeout: 300 wait_condition: type: Ready status: "True" when: cifmw_openshift_adp_enable_node_agent | bool - name: Get OADP pods kubernetes.core.k8s_info: api_version: v1 kind: Pod namespace: "{{ cifmw_openshift_adp_namespace }}" register: _oadp_pods - name: Display OADP pods ansible.builtin.debug: msg: "{{ item.metadata.name }} - {{ item.status.phase }}" loop: "{{ _oadp_pods.resources }}" loop_control: label: "{{ item.metadata.name }}" # ======================================== # VolumeSnapshotClass for CSI snapshots # ======================================== - name: Check for existing VolumeSnapshotClass kubernetes.core.k8s_info: api_version: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass register: _vsc_list - name: Create VolumeSnapshotClass for OADP (TopoLVM/LVMS) kubernetes.core.k8s: state: present definition: apiVersion: snapshot.storage.k8s.io/v1 kind: VolumeSnapshotClass metadata: name: lvms-velero labels: velero.io/csi-volumesnapshot-class: "true" annotations: snapshot.storage.kubernetes.io/is-default-class: "false" driver: topolvm.io deletionPolicy: Retain when: >- _vsc_list.resources | selectattr('driver', 'equalto', 'topolvm.io') | list | length > 0 - name: Print VolumeSnapshotClass status (TopoLVM found) ansible.builtin.debug: msg: "VolumeSnapshotClass 'lvms-velero' created for OADP CSI snapshots" when: >- _vsc_list.resources | selectattr('driver', 'equalto', 'topolvm.io') | list | length > 0 - name: Print VolumeSnapshotClass status (no TopoLVM) ansible.builtin.debug: msg: "No TopoLVM driver found. If using a different CSI driver, manually create a VolumeSnapshotClass with velero.io/csi-volumesnapshot-class=true label." when: >- _vsc_list.resources | selectattr('driver', 'equalto', 'topolvm.io') | list | length == 0 # ======================================== # Verify BackupStorageLocation # ======================================== - name: Wait for BackupStorageLocation to be available kubernetes.core.k8s_info: api_version: velero.io/v1 kind: BackupStorageLocation namespace: "{{ cifmw_openshift_adp_namespace }}" register: _bsl_status retries: 30 delay: 10 until: - _bsl_status.resources | length > 0 - (_bsl_status.resources[0].status.phase | default('')) == 'Available' ignore_errors: true - name: Get BackupStorageLocation details kubernetes.core.k8s_info: api_version: velero.io/v1 kind: BackupStorageLocation namespace: "{{ cifmw_openshift_adp_namespace }}" register: _bsl_output - name: Display BackupStorageLocation status ansible.builtin.debug: msg: >- {{ item.metadata.name }} - Phase: {{ item.status.phase | default('Unknown') }} loop: "{{ _bsl_output.resources }}" loop_control: label: "{{ item.metadata.name }}" - name: Get troubleshooting info if BSL not available ansible.builtin.shell: | echo "=== BackupStorageLocation ===" oc get backupstoragelocation -n {{ cifmw_openshift_adp_namespace }} -o yaml echo "" echo "=== Velero Logs (last 50 lines) ===" oc logs -n {{ cifmw_openshift_adp_namespace }} deployment/velero --tail=50 register: _bsl_debug changed_when: false when: _bsl_status is failed - name: Display troubleshooting info ansible.builtin.debug: msg: "{{ _bsl_debug.stdout_lines }}" when: _bsl_status is failed - name: Print success summary ansible.builtin.debug: msg: - "========================================" - "OADP Setup Complete" - "========================================" - "" - "OADP Namespace: {{ cifmw_openshift_adp_namespace }}" - "S3 API: https://{{ _s3_api_route.resources[0].spec.host }}" - "Bucket: {{ cifmw_openshift_adp_s3_bucket }}" - "BackupStorageLocation: Available" when: _bsl_status is not failed - name: Print warning summary ansible.builtin.debug: msg: - "========================================" - "OADP Setup Complete with Warnings" - "========================================" - "" - "BackupStorageLocation is not yet available." - "" - "Troubleshoot:" - " oc get backupstoragelocation -n {{ cifmw_openshift_adp_namespace }} -o yaml" - " oc logs -n {{ cifmw_openshift_adp_namespace }} deployment/velero" when: _bsl_status is failed