Skip to content

Commit

Permalink
New restore role
Browse files Browse the repository at this point in the history
There is a new restore role in the roles folder:

    roles/iparestore

This role allows to restore an IPA server locally and from the controller
and also to copy a backup from the controller to the server.

Here is the documentation for the role:

    roles/ipabackup/README.md

New example playbooks have been added:

    playbooks/restore-server.yml
    playbooks/restore-server-from-controller.yml
    playbooks/copy-backup-to-server.yml

The vars are copied form the ipaserver role to be able to install the
needed packages. The vars should be moved into a common role to be consumed
by ipaserver, ipareplica and iparestore roles later on.
  • Loading branch information
t-woerner committed Oct 29, 2020
1 parent 698bd81 commit 788bcec
Show file tree
Hide file tree
Showing 22 changed files with 521 additions and 0 deletions.
11 changes: 11 additions & 0 deletions playbooks/copy-backup-to-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
- name: Playbook to copy a backup from controller to the IPA server
hosts: ipaserver
become: true

vars:
iparestore_name: ipaserver.test.local_ipa-full-2020-10-22-11-11-44

roles:
- role: iparestore
state: copied
13 changes: 13 additions & 0 deletions playbooks/restore-server-from-controller.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
- name: Playbook to restore IPA server from controller
hosts: ipaserver
become: true

vars:
iparestore_name: ipaserver.el83.local_ipa-full-2020-10-22-11-11-44
iparestore_from_controller: yes
iparestore_password: SomeDMpassword

roles:
- role: iparestore
state: present
12 changes: 12 additions & 0 deletions playbooks/restore-server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
- name: Playbook to restore an IPA server
hosts: ipaserver
become: true

vars:
iparestore_name: ipa-full-2020-10-22-11-11-44
iparestore_password: SomeDMpassword

roles:
- role: iparestore
state: present
154 changes: 154 additions & 0 deletions roles/iparestore/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
iparestore role
==============

Description
-----------

This role allows to restore an IPA server locally and from the controller and also to copy a backup from the controller to the server.

**Note**: The ansible playbooks and role require a configured ansible environment where the ansible nodes are reachable and are properly set up to have an IP address and a working package manager.


Features
--------
* Server restore from local backup and from controller.
* Copy a backup from the controller to the server.


Supported FreeIPA Versions
--------------------------

FreeIPA versions 4.5 and up are supported by the restore role.


Supported Distributions
-----------------------

* RHEL/CentOS 7.6+
* Fedora 26+
* Ubuntu


Requirements
------------

**Controller**
* Ansible version: 2.8+

**Node**
* Supported FreeIPA version (see above)
* Supported distribution (needed for package installation only, see above)


Usage
=====

Example inventory file with fixed domain and realm, setting up of the DNS server and using forwarders from /etc/resolv.conf:

```ini
[ipaserver]
ipaserver.example.com
```

Example playbook to restore an IPA server locally:

```yaml
---
- name: Playbook to restore an IPA server
hosts: ipaserver
become: true

vars:
iparestore_name: ipa-full-2020-10-22-11-11-44
iparestore_password: SomeDMpassword

roles:
- role: iparestore
state: present
```
Example playbook to restore IPA server from controller:
```yaml
---
- name: Playbook to restore IPA server from controller
hosts: ipaserver
become: true

vars:
iparestore_name: ipaserver.test.local_ipa-full-2020-10-22-11-11-44
iparestore_from_controller: yes
iparestore_password: SomeDMpassword

roles:
- role: iparestore
state: present
```
Example playbook to copy a backup from controller to the IPA server:
```yaml
---
- name: Playbook to copy a backup from controller to the IPA server
hosts: ipaserver
become: true

vars:
iparestore_name: ipaserver.test.local_ipa-full-2020-10-22-11-11-44

roles:
- role: iparestore
state: copied
```
Playbooks
=========
The example playbooks to do the restore, copy a backup to the server are part of the repository in the playbooks folder.
```
restore-server.yml
restore-server-from-controller.yml
copy-backup-to-server.yml
```

Please remember to link or copy the playbooks to the base directory of ansible-freeipa if you want to use the roles within the source archive.


Variables
=========

Base Variables
--------------

Variable | Description | Required
-------- | ----------- | --------
iparestore_name | The backup to act on, str | yes
iparestore_password | The diretory manager password needed for restoring a backup with `state: present`, str | no
iparestore_data | Restore only the data, bool (default: `no`) | no
iparestore_online | Perform the LDAP restore online, for data only, bool (default: `no`) | no
iparestore_instance | The 389-ds instance to restore (defaults to all found), str | no
iparestore_backend | The backend to restore within the instance or instances, str | no
iparestore_no_logs | Do not restore log files from the backup, bool (default: `no`) | no
iparestore_log_file | Log to the given file on server, string | no
state | `present` to make a new restore, `copied` to copy a restore from the server to the controller. string (default: `present`) | yes

Special Variables
-----------------

Variable | Description | Required
-------- | ----------- | --------
iparestore_from_controller | Copy backup to controller, restore if `state: present`, copy backup to server if `state: copied`, bool (default: `no`) | no
iparestore_controller_path | Path on the controller to get the backup from. If this is not set, the current working dir is used. string | no
iparestore_install_packages | Install needed packages to be able to apply the backup, bool (default: `yes`) | no
iparestore_firewalld_zone | The value defines the firewall zone that will be used. This needs to be an existing runtime and permanent zone, bool (default: `no`) | no
iparestore_setup_firewalld | The value defines if the needed services will automatically be opened in the firewall managed by firewalld, bool (default: `yes`) | no


Authors
=======

Thomas Woerner
11 changes: 11 additions & 0 deletions roles/iparestore/defaults/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
---
# defaults file for iparestore

iparestore_data: no
iparestore_online: no
iparestore_no_logs: no

### special ###
iparestore_from_controller: no
iparestore_install_packages: yes
iparestore_setup_firewalld: yes
20 changes: 20 additions & 0 deletions roles/iparestore/meta/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
dependencies: []

galaxy_info:
author: Thomas Woerner
description: A role to backup an IPA server
company: Red Hat, Inc
license: GPLv3
min_ansible_version: 2.8
platforms:
- name: Fedora
versions:
- all
- name: EL
versions:
- 7
- 8
galaxy_tags:
- identity
- ipa
- freeipa
37 changes: 37 additions & 0 deletions roles/iparestore/tasks/apply_backup.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
- name: Fail on invalid ipabackup_item
fail: msg="ipabackup_item {{ ipabackup_item }} is not valid"
when: ipabackup_item is not defined or
ipabackup_item | length < 1 or
(ipabackup_item.find("ipa-full-") == -1 and
ipabackup_item.find("ipa-data-") == -1)

- name: Set controller destination directory
set_fact:
ipabackup_controller_dir:
"{{ ipabackup_controller_path | default(lookup('env','PWD')) }}/{{
ipabackup_controller_prefix | default(ansible_fqdn) }}_{{
ipabackup_item }}/"

- name: Get backup files to copy for "{{ ipabackup_item }}"
shell:
find . -type f | cut -d"/" -f 2
args:
chdir: "{{ ipabackup_dir }}/{{ ipabackup_item }}"
register: result_find_backup_files

- name: Copy server backup files to controller
fetch:
flat: yes
src: "{{ ipabackup_dir }}/{{ ipabackup_item }}/{{ item }}"
dest: "{{ ipabackup_controller_dir }}"
with_items:
- "{{ result_find_backup_files.stdout_lines }}"

- name: Fix file modes for backup on controller
file:
dest: "{{ ipabackup_controller_dir }}"
mode: u=rwX,go=
recurse: yes
delegate_to: localhost
become: no
26 changes: 26 additions & 0 deletions roles/iparestore/tasks/copy_backup_to_server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
---
- name: Fail on invalid iparestore_name
fail: msg="iparestore_name {{ iparestore_name }} is not valid"
when: iparestore_name is not defined or
iparestore_name | length < 1 or
(iparestore_name.find("ipa-full-") == -1 and
iparestore_name.find("ipa-data-") == -1)

- name: Set controller source directory
set_fact:
iparestore_controller_dir:
"{{ iparestore_controller_path | default(lookup('env','PWD')) }}"

- name: Set iparestore_item
set_fact:
iparestore_item:
"{{ iparestore_name | regex_search('.*_(ipa-.+)','\\1') | first }}"

- name: Copy backup files to server for "{{ iparestore_item }}"
copy:
src: "{{ iparestore_controller_dir }}/{{ iparestore_name }}/"
dest: "{{ iparestore_dir }}/{{ iparestore_item }}"
owner: root
group: root
mode: u=rw,go=r
directory_mode: u=rwx,go=
12 changes: 12 additions & 0 deletions roles/iparestore/tasks/get_iparestore_dir.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
---
- name: Get IPA_BACKUP_DIR dir from ipaplatform
command: "{{ ansible_playbook_python }}"
args:
stdin: |
from ipaplatform.paths import paths
print(paths.IPA_BACKUP_DIR)
register: result_ipaplatform_backup_dir

- name: Set IPA restore dir
set_fact:
iparestore_dir: "{{ result_ipaplatform_backup_dir.stdout_lines | first }}"
31 changes: 31 additions & 0 deletions roles/iparestore/tasks/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
---
# tasks file for iparestore

- name: Fail on missing iparestore_name
fail: msg="iparestore_name is not set"
when: iparestore_name is not defined

- name: Fail on missing iparestore_password
fail: msg="iparestore_password is not set"
when: iparestore_password is not defined and
state|default("present") == "present"

- name: Get iparestore_dir from IPA installation
include_tasks: "{{ role_path }}/tasks/get_iparestore_dir.yml"

- block:
- name: Copy backup to server
include_tasks: "{{ role_path }}/tasks/copy_backup_to_server.yml"

- name: Restore IPA server after copy
include_tasks: "{{ role_path }}/tasks/restore.yml"
when: state|default("present") == "present"

when: iparestore_from_controller or state|default("present") == "copied"

- name: Restore IPA server
include_tasks: "{{ role_path }}/tasks/restore.yml"
vars:
iparestore_item: "{{ iparestore_name | basename }}"
when: not iparestore_from_controller and
state|default("present") == "present"
5 changes: 5 additions & 0 deletions roles/iparestore/tasks/remove_backup_from_server.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
- name: Remove backup "{{ ipabackup_item }}"
file:
path: "{{ ipabackup_dir }}/{{ ipabackup_item }}"
state: absent
Loading

0 comments on commit 788bcec

Please sign in to comment.