mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-28 14:23:06 +00:00
Compare commits
98 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
5dd5faccb0 | ||
|
|
040d95c519 | ||
|
|
dc8964134b | ||
|
|
ceb6f41407 | ||
|
|
d2e2fd6fdb | ||
|
|
91e69e3dcc | ||
|
|
743216b0db | ||
|
|
7e8145e43a | ||
|
|
fbf6f23590 | ||
|
|
82f8dae540 | ||
|
|
184f6f08da | ||
|
|
aff6d9005c | ||
|
|
830da6367e | ||
|
|
5d2736b144 | ||
|
|
2b2fe198c5 | ||
|
|
186d2373e6 | ||
|
|
c1b47ffe1b | ||
|
|
2ba2b3cfee | ||
|
|
bcd5c74f0d | ||
|
|
f53254fe3d | ||
|
|
5b2debfcea | ||
|
|
829ffdb225 | ||
|
|
696e9ff500 | ||
|
|
f9066fa55b | ||
|
|
03688da522 | ||
|
|
9d088983d9 | ||
|
|
b0da219bf5 | ||
|
|
8f8d65cab9 | ||
|
|
18a07e2294 | ||
|
|
14cb100a91 | ||
|
|
6378d9b1dc | ||
|
|
a3578de4b2 | ||
|
|
c045530cd4 | ||
|
|
419312c324 | ||
|
|
2d566825a3 | ||
|
|
de9d8b50cf | ||
|
|
3a4cb6a732 | ||
|
|
cb94c34503 | ||
|
|
a33c832bdf | ||
|
|
fae81d62d7 | ||
|
|
66449a7462 | ||
|
|
64775884b2 | ||
|
|
a5c43d3fed | ||
|
|
3ae4fe1cc5 | ||
|
|
1fa1468b85 | ||
|
|
8cd34b4d53 | ||
|
|
e63b5759b3 | ||
|
|
00862d9709 | ||
|
|
50611a042f | ||
|
|
cf01262b27 | ||
|
|
0c3d35a577 | ||
|
|
771b0ba029 | ||
|
|
364267f1ab | ||
|
|
2afb8c6a2f | ||
|
|
a36e8e0876 | ||
|
|
1cb0ac67a2 | ||
|
|
d2968b2611 | ||
|
|
03d904b7ea | ||
|
|
7a5fadfc8d | ||
|
|
45b2648af2 | ||
|
|
27fb3e1bb7 | ||
|
|
115f96d0be | ||
|
|
da2631d923 | ||
|
|
c708ef781e | ||
|
|
e7de098790 | ||
|
|
45d8008033 | ||
|
|
5f580b5152 | ||
|
|
7e42102aa5 | ||
|
|
3a3b4cb397 | ||
|
|
5afd889023 | ||
|
|
5d881a9bf3 | ||
|
|
2092220634 | ||
|
|
ca4518a623 | ||
|
|
158fdb1876 | ||
|
|
c905cdaf02 | ||
|
|
4378d161bc | ||
|
|
1009c889b3 | ||
|
|
56a8acedf0 | ||
|
|
8ac1a6e590 | ||
|
|
76d436ec0b | ||
|
|
438f09bad9 | ||
|
|
0f73362ef5 | ||
|
|
2372e5b98d | ||
|
|
50046a7348 | ||
|
|
79d0ac9d47 | ||
|
|
ca43b427a8 | ||
|
|
b89112cf81 | ||
|
|
215359e377 | ||
|
|
a79437d39a | ||
|
|
4829399ef3 | ||
|
|
e218441c39 | ||
|
|
8ffe818b7f | ||
|
|
100b7eabaf | ||
|
|
ac24f9c067 | ||
|
|
da14fa29bb | ||
|
|
813d5bbf97 | ||
|
|
3de056bc60 | ||
|
|
20e5338ad5 |
153
README-group.md
Normal file
153
README-group.md
Normal file
@@ -0,0 +1,153 @@
|
||||
Group module
|
||||
============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The group module allows to add, remove, enable, disable, unlock und undelete groups.
|
||||
|
||||
The group module is as compatible as possible to the Ansible upstream `ipa_group` module, but addtionally offers to add users to a group and also to remove users from a group.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Group management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipagroup module.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to add groups:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Create group ops with gid 1234
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
gidnumber: 1234
|
||||
|
||||
# Create group sysops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops
|
||||
user:
|
||||
- pinky
|
||||
|
||||
# Create group appops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: appops
|
||||
```
|
||||
|
||||
Example playbook to add users to a group:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Add user member brain to group sysops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops
|
||||
action: member
|
||||
user:
|
||||
- brain
|
||||
```
|
||||
`action` controls if a the group or member will be handled. To add or remove members, set `action` to `member`.
|
||||
|
||||
|
||||
Example playbook to add group members to a group:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Add group members sysops and appops to group sysops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
group:
|
||||
- sysops
|
||||
- appops
|
||||
```
|
||||
|
||||
Example playbook to remove groups:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Remove goups sysops, appops and ops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops,appops,ops
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipagroup
|
||||
-------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`name` \| `cn` | The list of group name strings. | no
|
||||
`description` | The group description string. | no
|
||||
`gid` \| `gidnumber` | The GID integer. | no
|
||||
`nonposix` | Create as a non-POSIX group. (bool) | no
|
||||
`external` | Allow adding external non-IPA members from trusted domains. (flag) | no
|
||||
`nomembers` | Suppress processing of membership attributes. (bool) | no
|
||||
`user` | List of user name strings assigned to this group. | no
|
||||
`group` | List of group name strings assigned to this group. | no
|
||||
`service` | List of service name strings assigned to this group | no
|
||||
`action` | Work on group or member level. It can be on of `member` or `group` and defaults to `group`. | no
|
||||
`state` | The state to ensure. It can be one of `present` or `absent`, defauilt: `present`. | yes
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
@@ -50,7 +50,7 @@ Example playbook to add a topology segment wiht default name (cn):
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
@@ -70,7 +70,7 @@ Example playbook to delete a topology segment:
|
||||
tasks:
|
||||
- name: Delete topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
@@ -90,7 +90,7 @@ Example playbook to reinitialize a topology segment:
|
||||
tasks:
|
||||
- name: Reinitialize topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
@@ -111,11 +111,43 @@ Example playbook to verify a topology suffix:
|
||||
tasks:
|
||||
- name: Verify topology suffix
|
||||
ipatopologysuffix:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
state: verified
|
||||
```
|
||||
|
||||
Example playbook to add or remove or check or reinitialize a list of topology segments:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Add topology segments
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
ipaadmin_password: password1
|
||||
ipatopology_segments:
|
||||
- {suffix: domain, left: replica1.test.local, right: replica2.test.local}
|
||||
- {suffix: domain, left: replica2.test.local, right: replica3.test.local}
|
||||
- {suffix: domain, left: replica3.test.local, right: replica4.test.local}
|
||||
- {suffix: domain+ca, left: replica4.test.local, right: replica1.test.local}
|
||||
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
ipaadmin_password: "{{ ipaadmin_password }}"
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
right: "{{ item.right }}"
|
||||
state: present
|
||||
#state: absent
|
||||
#state: checked
|
||||
#state: reinitialized
|
||||
loop: "{{ ipatopology_segments | default([]) }}"
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
@@ -125,14 +157,14 @@ ipatopologysegment
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`suffix` | The topology suffix to be used, this can either be `domain` or `ca` | yes
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`suffix` | The topology suffix to be used, this can either be `domain`, `ca` or `domain+ca` | yes
|
||||
`name` \| `cn` | The topology segment name (cn) is the unique identifier for a segment. | no
|
||||
`left` \| `leftnode` | The left replication node string - an IPA server | no
|
||||
`right` \| `rightnode` | The right replication node string - an IPA server | no
|
||||
`direction` | The direction a segment will be reinitialized. It can either be `left-to-right` or `right-to-left` and only used with `state: reinitialized` |
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled` or `reinitialized` | yes
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `checked` or `reinitialized` | yes
|
||||
|
||||
|
||||
ipatopologysuffix
|
||||
@@ -142,8 +174,8 @@ Verify FreeIPA topology suffix
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`suffix` | The topology suffix to be used, this can either be `domain` or `ca` | yes
|
||||
`state` | The state to ensure. It can only be `verified` | yes
|
||||
|
||||
|
||||
214
README-user.md
Normal file
214
README-user.md
Normal file
@@ -0,0 +1,214 @@
|
||||
User module
|
||||
===========
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The user module allows to add, remove, enable, disable, unlock und undelete users.
|
||||
|
||||
The user module is as compatible as possible to the Ansible upstream `ipa_user` module, but addtionally offers to preserve delete, enable, disable, unlock and undelete users.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* User management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipauser module.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to add users:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Create user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
first: pinky
|
||||
last: Acme
|
||||
uid: 10001
|
||||
gid: 100
|
||||
phone: "+555123457"
|
||||
email: pinky@acme.com
|
||||
passwordexpiration: "2023-01-19 23:59:59"
|
||||
password: "no-brain"
|
||||
update_password: on_create
|
||||
|
||||
# Create user brain
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: brain
|
||||
first: brain
|
||||
last: Acme
|
||||
```
|
||||
`update_password` controls if a password for a user will be set in present state only on creation or every time (always).
|
||||
|
||||
|
||||
Example playbook to delete a user, but preserve it:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Remove but preserve user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
preserve: yes
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Example playbook to undelete a preserved user.
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Undelete preserved user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
state: undeleted
|
||||
```
|
||||
|
||||
|
||||
Example playbook to disable a user:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Disable user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
state: disabled
|
||||
```
|
||||
|
||||
|
||||
Example playbook to enable users:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Enable user pinky and brain
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: enabled
|
||||
```
|
||||
|
||||
|
||||
Example playbook to unlock users:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Unlock user pinky and brain
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: unlocked
|
||||
```
|
||||
|
||||
|
||||
Example playbook to delete users:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
# Remove user pinky and brain
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: absent
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipauser
|
||||
-------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`name` | The list of user name strings. | no
|
||||
`first` \| `givenname` | The first name string. | no
|
||||
`last` | The last name | no
|
||||
`fullname` \| `cn` | The full name string. | no
|
||||
`displayname` | The display name string. | no
|
||||
`homedir` | The home directory string. | no
|
||||
`shell` \| `loginshell` | The login shell string. | no
|
||||
`email` | List of email address strings. | no
|
||||
`principalname` \| `krbprincipalname` | The kerberos principal sptring. | no
|
||||
`passwordexpiration` \| `krbpasswordexpiration` | The kerberos password expiration date. Possible formats: `YYYYMMddHHmmssZ`, `YYYY-MM-ddTHH:mm:ssZ`, `YYYY-MM-ddTHH:mmZ`, `YYYY-MM-ddZ`, `YYYY-MM-dd HH:mm:ssZ` or `YYYY-MM-dd HH:mmZ`. The trailing 'Z' can be skipped. | no
|
||||
`password` | The user password string. | no
|
||||
`uid` \| `uidnumber` | The UID integer. | no
|
||||
`gid` \| `gidnumber` | The GID integer. | no
|
||||
`phone` \| `telephonenumber` | List of telephone number strings, | no
|
||||
`title` | The job title string. | no
|
||||
~~`sshpubkey` \| `ipasshpubkey`~~ | ~~List of SSH public keys.~~ | ~~no~~
|
||||
`update_password` | Set password for a user in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no
|
||||
`preserve` | Delete a user, keeping the entry available for future use. (bool) | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled`, `unlocked` or `undeleted`, default: `present`. | yes
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
97
README.md
97
README.md
@@ -1,7 +1,7 @@
|
||||
FreeIPA Ansible roles
|
||||
=====================
|
||||
FreeIPA Ansible collection
|
||||
==========================
|
||||
|
||||
This repository contains [Ansible](https://www.ansible.com/) roles and playbooks to install and uninstall [FreeIPA](https://www.freeipa.org/) `servers`, `replicas` and `clients`.
|
||||
This repository contains [Ansible](https://www.ansible.com/) roles and playbooks to install and uninstall [FreeIPA](https://www.freeipa.org/) `servers`, `replicas` and `clients`. Also modules for group, topology and user management.
|
||||
|
||||
**Note**: The ansible playbooks and roles 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.
|
||||
|
||||
@@ -11,7 +11,9 @@ Features
|
||||
* Cluster deployments: Server, replicas and clients in one playbook
|
||||
* One-time-password (OTP) support for client installation
|
||||
* Repair mode for clients
|
||||
* Modules for group management
|
||||
* Modules for topology management
|
||||
* Modules for user management
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
@@ -32,6 +34,7 @@ Requirements
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+ (ansible-freeipa is an Ansible Collection)
|
||||
* /usr/bin/kinit is required on the controller if a one time password (OTP) is used
|
||||
* python3-gssapi is required on the controller if a one time password (OTP) is used with keytab to install the client.
|
||||
|
||||
**Node**
|
||||
@@ -41,11 +44,11 @@ Requirements
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
**External CA**
|
||||
**External signed CA**
|
||||
|
||||
External CA support is not supported or working. The currently needed two step process is an issue for the processing in the role. The configuration of the server is partly done already and needs to be continued after the CSR has been handled. This is for example breaking the deployment of a server with replicas or clients in one playbook.
|
||||
External signed CA is now supported. But the currently needed two step process is an issue for the processing in a simple playbook.
|
||||
|
||||
Work is planned to have a new method to handle CSR for external CAs in a separate step before starting the server installation.
|
||||
Work is planned to have a new method to handle CSR for external signed CAs in a separate step before starting the server installation.
|
||||
|
||||
|
||||
Usage
|
||||
@@ -54,19 +57,51 @@ Usage
|
||||
How to use ansible-freeipa
|
||||
--------------------------
|
||||
|
||||
**GIT repo**
|
||||
|
||||
The simplest method for now is to clone this repository on the contoller from github directly and to start the deployment from the ansible-freeipa directory:
|
||||
|
||||
```bash
|
||||
git clone https://github.com/freeipa/ansible-freeipa.git
|
||||
cd ansible-freeipa
|
||||
```
|
||||
You can use the roles directly within the top directory of the git repo, but to be able to use the management modules in the plugins subdirectory, you have to either adapt `anisble.cfg` or create links for the modules or directories.
|
||||
|
||||
You can either adapt ansible.cfg:
|
||||
|
||||
```
|
||||
library = /my/dir/ansible-freeipa/plugins/modules
|
||||
module_utils = /my/dir/ansible-freeipa/plugins/module_utils
|
||||
```
|
||||
|
||||
Or you can link the directories:
|
||||
|
||||
```
|
||||
ansible-freeipa/plugins/modules to ~/.ansible/plugins/
|
||||
ansible-freeipa/plugins/module_utils to ~/.ansible/plugins/
|
||||
```
|
||||
|
||||
**RPM package**
|
||||
|
||||
There are RPM packages available for Fedora 29+. These are installing the roles and modules into the global Ansible directories for `roles`, `plugins/modules` and `plugings/module_utils` in the `/usr/share/ansible` directory. Therefore is it possible to use the roles and modules without adapting the names like it is done in the example playbooks.
|
||||
|
||||
**Ansible galaxy**
|
||||
|
||||
This command will get the whole collection from galaxy:
|
||||
|
||||
```bash
|
||||
mazer install freeipa.ansible_freeipa
|
||||
```
|
||||
|
||||
Ansible galaxy does not support the use of dash ('-') in a name and is automatically replacing this with an underscore ('\_'). Therefore the name is `ansible_freeipa`. The ansible_freeipa collection will be placed in the directory `~/.ansible/collections/ansible_collections/freeipa/ansible_freeipa` where it will be automatically be found for this user.
|
||||
|
||||
The needed adaptions of collection prefixes for `modules` and `module_utils` will be done with ansible-freeipa release `0.1.6` for galaxy.
|
||||
|
||||
The roles provided by ansible-freeipa are not available in ansible galaxy so far.
|
||||
|
||||
Ansible inventory file
|
||||
----------------------
|
||||
|
||||
The most important parts of the inventory file is the definition of the nodes, settings and the topology. Please remember to use [Ansible vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html) for passwords. The examples here are not using vault for better readability.
|
||||
The most important parts of the inventory file is the definition of the nodes, settings and the management modules. Please remember to use [Ansible vault](https://docs.ansible.com/ansible/latest/user_guide/vault.html) for passwords. The examples here are not using vault for better readability.
|
||||
|
||||
**Master server**
|
||||
|
||||
@@ -101,7 +136,7 @@ ipaserver_setup_firewalld=no
|
||||
```
|
||||
The installation of packages and also the configuration of the firewall are by default enabled.
|
||||
|
||||
For more server settings, please have a look at the [server role documentation](SERVER.md).
|
||||
For more server settings, please have a look at the [server role documentation](roles/ipaserver/README.md).
|
||||
|
||||
**Replica**
|
||||
|
||||
@@ -176,7 +211,7 @@ ipareplica_setup_firewalld=no
|
||||
|
||||
The installation of packages and also the configuration of the firewall are by default enabled.
|
||||
|
||||
For more replica settings, please have a look at the [replica role documentation](REPLICA.md).
|
||||
For more replica settings, please have a look at the [replica role documentation](roles/ipareplica/README.md).
|
||||
|
||||
|
||||
**Client**
|
||||
@@ -215,7 +250,7 @@ To enable the generation of the one-time-password:
|
||||
ipaclient_use_otp=yes
|
||||
```
|
||||
|
||||
For more client settings, please have a look at the [client role documentation](CLIENT.md).
|
||||
For more client settings, please have a look at the [client role documentation](roles/ipaclient/README.md).
|
||||
|
||||
**Cluster**
|
||||
|
||||
@@ -234,6 +269,42 @@ ipaserver_realm=TEST.LOCAL
|
||||
```
|
||||
All these settings will be available in the ```[ipaserver]```, ```[ipareplicas]``` and ```[ipaclient]``` groups.
|
||||
|
||||
**Topology**
|
||||
|
||||
With this playbook it is possible to add a list of topology segments using the `ipatopologysegment` module.
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Add topology segments
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
ipaadmin_password: password1
|
||||
ipatopology_segments:
|
||||
- {suffix: domain, left: replica1.test.local, right: replica2.test.local}
|
||||
- {suffix: domain, left: replica2.test.local, right: replica3.test.local}
|
||||
- {suffix: domain, left: replica3.test.local, right: replica4.test.local}
|
||||
- {suffix: domain+ca, left: replica4.test.local, right: replica1.test.local}
|
||||
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
password: "{{ ipaadmin_password }}"
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
right: "{{ item.right }}"
|
||||
#state: present
|
||||
#state: absent
|
||||
#state: checked
|
||||
state: reinitialized
|
||||
loop: "{{ ipatopology_segments | default([]) }}"
|
||||
```
|
||||
|
||||
|
||||
|
||||
Playbooks
|
||||
=========
|
||||
|
||||
@@ -309,8 +380,10 @@ Roles
|
||||
* [Replica](roles/ipareplica/README.md)
|
||||
* [Client](roles/ipaclient/README.md)
|
||||
|
||||
Plugins in plugin/modules
|
||||
Modules in plugin/modules
|
||||
=========================
|
||||
|
||||
* [ipagroup](README-group.md)
|
||||
* [ipatopologysegment](README-topology.md)
|
||||
* [ipatopologysuffix](README-topology.md)
|
||||
* [ipauser](README-user.md)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
namespace: "freeipa"
|
||||
name: "ansible_freeipa"
|
||||
version: "0.1.1"
|
||||
version: "A.B.C"
|
||||
description: ""
|
||||
|
||||
authors:
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
|
||||
23
playbooks/topology/add-topologysegments.yml
Normal file
23
playbooks/topology/add-topologysegments.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Add topology segments
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
ipatopology_segments:
|
||||
- {suffix: domain, left: replica1.test.local, right: replica2.test.local}
|
||||
- {suffix: domain, left: replica2.test.local, right: replica3.test.local}
|
||||
- {suffix: domain, left: replica3.test.local, right: replica4.test.local}
|
||||
- {suffix: domain+ca, left: replica4.test.local, right: replica1.test.local}
|
||||
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
ipaadmin_password: "{{ ipaadmin_password }}"
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
right: "{{ item.right }}"
|
||||
state: present
|
||||
loop: "{{ ipatopology_segments | default([]) }}"
|
||||
23
playbooks/topology/check-topologysegments.yml
Normal file
23
playbooks/topology/check-topologysegments.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Add topology segments
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
ipatopology_segments:
|
||||
- {suffix: domain, left: replica1.test.local, right: replica2.test.local}
|
||||
- {suffix: domain, left: replica2.test.local, right: replica3.test.local}
|
||||
- {suffix: domain, left: replica3.test.local, right: replica4.test.local}
|
||||
- {suffix: domain+ca, left: replica4.test.local, right: replica1.test.local}
|
||||
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
ipaadmin_password: "{{ ipaadmin_password }}"
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
right: "{{ item.right }}"
|
||||
state: checked
|
||||
loop: "{{ ipatopology_segments | default([]) }}"
|
||||
@@ -6,7 +6,7 @@
|
||||
tasks:
|
||||
- name: Delete topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
|
||||
23
playbooks/topology/delete-topologysegments.yml
Normal file
23
playbooks/topology/delete-topologysegments.yml
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
- name: Add topology segments
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
gather_facts: false
|
||||
|
||||
vars:
|
||||
ipatopology_segments:
|
||||
- {suffix: domain, left: replica1.test.local, right: replica2.test.local}
|
||||
- {suffix: domain, left: replica2.test.local, right: replica3.test.local}
|
||||
- {suffix: domain, left: replica3.test.local, right: replica4.test.local}
|
||||
- {suffix: domain+ca, left: replica4.test.local, right: replica1.test.local}
|
||||
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
ipaadmin_password: "{{ ipaadmin_password }}"
|
||||
suffix: "{{ item.suffix }}"
|
||||
name: "{{ item.name | default(omit) }}"
|
||||
left: "{{ item.left }}"
|
||||
right: "{{ item.right }}"
|
||||
state: absent
|
||||
loop: "{{ ipatopology_segments | default([]) }}"
|
||||
@@ -6,7 +6,7 @@
|
||||
tasks:
|
||||
- name: Reinitialize topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
|
||||
@@ -6,6 +6,6 @@
|
||||
tasks:
|
||||
- name: Verify topology suffix
|
||||
ipatopologysuffix:
|
||||
password: MyPassword123
|
||||
ipaadmin_password: MyPassword123
|
||||
suffix: domain
|
||||
state: verified
|
||||
|
||||
24
playbooks/user/add-group.yml
Normal file
24
playbooks/user/add-group.yml
Normal file
@@ -0,0 +1,24 @@
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Create group ops with gid 1234
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
gidnumber: 1234
|
||||
|
||||
- name: Create group sysops
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops
|
||||
user:
|
||||
- pinky
|
||||
|
||||
- name: Create group appops
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: appops
|
||||
|
||||
13
playbooks/user/add-groups-to-group.yml
Normal file
13
playbooks/user/add-groups-to-group.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Add group members sysops and appops to group sysops
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
group:
|
||||
- sysops
|
||||
- appops
|
||||
13
playbooks/user/add-user-to-group.yml
Normal file
13
playbooks/user/add-user-to-group.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Add user member brain to group sysops
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops
|
||||
action: member
|
||||
user:
|
||||
- brain
|
||||
20
playbooks/user/add-user.yml
Normal file
20
playbooks/user/add-user.yml
Normal file
@@ -0,0 +1,20 @@
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Create user pinky
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
first: pinky
|
||||
last: Acme
|
||||
uid: 10001
|
||||
gid: 100
|
||||
phone: "+555123457"
|
||||
email: pinky@acme.com
|
||||
passwordexpiration: "2023-01-19 23:59:59"
|
||||
password: "no-brain"
|
||||
update_password: on_create
|
||||
|
||||
11
playbooks/user/delete-group.yml
Normal file
11
playbooks/user/delete-group.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle groups
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Remove goups sysops, appops and ops
|
||||
ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops,appops,ops
|
||||
state: absent
|
||||
12
playbooks/user/delete-preserve-user.yml
Normal file
12
playbooks/user/delete-preserve-user.yml
Normal file
@@ -0,0 +1,12 @@
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Delete and preserve user pinky
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
preserve: yes
|
||||
state: absent
|
||||
11
playbooks/user/delete-user.yml
Normal file
11
playbooks/user/delete-user.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Remove user pinky and brain
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
state: absent
|
||||
11
playbooks/user/disable-user.yml
Normal file
11
playbooks/user/disable-user.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Disable user pinky
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
state: disabled
|
||||
11
playbooks/user/enable-user.yml
Normal file
11
playbooks/user/enable-user.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Enable user pinky
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
state: enabled
|
||||
11
playbooks/user/undelete-user.yml
Normal file
11
playbooks/user/undelete-user.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Undelete preserved user pinky
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
state: undeleted
|
||||
11
playbooks/user/unlock-users.yml
Normal file
11
playbooks/user/unlock-users.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle users
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Unlock users pinky and brain
|
||||
ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: unlocked
|
||||
@@ -22,12 +22,12 @@
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import shutil
|
||||
from ipalib import api, errors
|
||||
from datetime import datetime
|
||||
from ipalib import api
|
||||
from ipalib.config import Env
|
||||
from ipalib.constants import DEFAULT_CONFIG
|
||||
from ipalib.constants import DEFAULT_CONFIG, LDAP_GENERALIZED_TIME_FORMAT
|
||||
try:
|
||||
from ipalib.install.kinit import kinit_password
|
||||
except ImportError:
|
||||
@@ -120,3 +120,40 @@ def execute_api_command(module, principal, password, command, name, args):
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
|
||||
def date_format(value):
|
||||
accepted_date_formats = [
|
||||
LDAP_GENERALIZED_TIME_FORMAT, # generalized time
|
||||
'%Y-%m-%dT%H:%M:%SZ', # ISO 8601, second precision
|
||||
'%Y-%m-%dT%H:%MZ', # ISO 8601, minute precision
|
||||
'%Y-%m-%dZ', # ISO 8601, date only
|
||||
'%Y-%m-%d %H:%M:%SZ', # non-ISO 8601, second precision
|
||||
'%Y-%m-%d %H:%MZ', # non-ISO 8601, minute precision
|
||||
]
|
||||
|
||||
for date_format in accepted_date_formats:
|
||||
try:
|
||||
return datetime.strptime(value, date_format)
|
||||
except ValueError:
|
||||
pass
|
||||
raise ValueError("Invalid date '%s'" % value)
|
||||
|
||||
|
||||
def compare_args_ipa(module, args, ipa):
|
||||
for key in args.keys():
|
||||
if key not in ipa:
|
||||
return False
|
||||
else:
|
||||
arg = args[key]
|
||||
ipa_arg = ipa[key]
|
||||
# If ipa_arg is a list and arg is not, replace arg
|
||||
# with list containing arg. Most args in a find result
|
||||
# are lists, but not all.
|
||||
if isinstance(ipa_arg, list) and not isinstance(arg, list):
|
||||
arg = [arg]
|
||||
# module.warn("%s <=> %s" % (arg, ipa_arg))
|
||||
if arg != ipa_arg:
|
||||
return False
|
||||
|
||||
return True
|
||||
|
||||
425
plugins/modules/ipagroup.py
Normal file
425
plugins/modules/ipagroup.py
Normal file
@@ -0,0 +1,425 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipagroup
|
||||
short description: Manage FreeIPA groups
|
||||
description: Manage FreeIPA groups
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The group name
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
description:
|
||||
description: The group description
|
||||
required: false
|
||||
gid:
|
||||
description: The GID
|
||||
required: false
|
||||
aliases: ["gidnumber"]
|
||||
nonposix:
|
||||
description: Create as a non-POSIX group
|
||||
required: false
|
||||
type: bool
|
||||
external:
|
||||
description: Allow adding external non-IPA members from trusted domains
|
||||
required: false
|
||||
type: bool
|
||||
nomembers:
|
||||
description: Suppress processing of membership attributes
|
||||
required: false
|
||||
type: bool
|
||||
user:
|
||||
description: List of user names assigned to this group.
|
||||
required: false
|
||||
type: list
|
||||
group:
|
||||
description: List of group names assigned to this group.
|
||||
required: false
|
||||
type: list
|
||||
service:
|
||||
description: List of service names assigned to this group.
|
||||
required: false
|
||||
type: list
|
||||
action:
|
||||
description: Work on group or member level
|
||||
default: group
|
||||
choices: ["member", "group"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Create group ops with gid 1234
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
gidnumber: 1234
|
||||
|
||||
# Create group sysops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops
|
||||
|
||||
# Create group appops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: appops
|
||||
|
||||
# Add user member pinky to group sysops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops
|
||||
action: member
|
||||
user:
|
||||
- pinky
|
||||
|
||||
# Add user member brain to group sysops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops
|
||||
action: member
|
||||
user:
|
||||
- brain
|
||||
|
||||
# Add group members sysops and appops to group sysops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: ops
|
||||
group:
|
||||
- sysops
|
||||
- appops
|
||||
|
||||
# Remove goups sysops, appops and ops
|
||||
- ipagroup:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: sysops,appops,ops
|
||||
state: absent
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa
|
||||
|
||||
|
||||
def find_group(module, name):
|
||||
_args = {
|
||||
"all": True,
|
||||
"cn": to_text(name),
|
||||
}
|
||||
|
||||
_result = api_command(module, "group_find", to_text(name), _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one group '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(description, gid, nonposix, external, nomembers):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
if gid is not None:
|
||||
_args["gidnumber"] = str(gid)
|
||||
if nonposix is not None:
|
||||
_args["nonposix"] = nonposix
|
||||
if external is not None:
|
||||
_args["external"] = external
|
||||
if nomembers is not None:
|
||||
_args["nomembers"] = nomembers
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def gen_member_args(user, group, service):
|
||||
_args = {}
|
||||
if user is not None:
|
||||
_args["member_user"] = user
|
||||
if group is not None:
|
||||
_args["member_group"] = group
|
||||
if service is not None:
|
||||
_args["member_service"] = service
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
ipaadmin_principal=dict(type="str", default="admin"),
|
||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||
|
||||
name=dict(type="list", aliases=["cn"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
description=dict(type="str", default=None),
|
||||
gid=dict(type="int", aliases=["gidnumber"], default=None),
|
||||
nonposix=dict(required=False, type='bool', default=None),
|
||||
external=dict(required=False, type='bool', default=None),
|
||||
nomembers=dict(required=False, type='bool', default=None),
|
||||
user=dict(required=False, type='list', default=None),
|
||||
group=dict(required=False, type='list', default=None),
|
||||
service=dict(required=False, type='list', default=None),
|
||||
action=dict(type="str", default="group",
|
||||
choices=["member", "group"]),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent",
|
||||
"member_present", "member_absent"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params.get("description")
|
||||
gid = ansible_module.params.get("gid")
|
||||
nonposix = ansible_module.params.get("nonposix")
|
||||
external = ansible_module.params.get("external")
|
||||
nomembers = ansible_module.params.get("nomembers")
|
||||
user = ansible_module.params.get("user")
|
||||
group = ansible_module.params.get("group")
|
||||
service = ansible_module.params.get("service")
|
||||
action = ansible_module.params.get("action")
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Onle one group can be added at a time.")
|
||||
if action == "member":
|
||||
invalid = ["description", "gid", "nonposix", "external",
|
||||
"nomembers"]
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with action "
|
||||
"'%s'" % (x, action))
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
invalid = ["description", "gid", "nonposix", "external", "nomembers"]
|
||||
if action == "group":
|
||||
invalid.extend(["user", "group", "service"])
|
||||
for x in invalid:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure group exists
|
||||
res_find = find_group(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(description, gid, nonposix, external,
|
||||
nomembers)
|
||||
|
||||
if action == "group":
|
||||
# Found the group
|
||||
if res_find is not None:
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args,
|
||||
res_find):
|
||||
commands.append([name, "group_mod", args])
|
||||
else:
|
||||
commands.append([name, "group_add", args])
|
||||
# Set res_find to empty dict for next step
|
||||
res_find = {}
|
||||
|
||||
member_args = gen_member_args(user, group, service)
|
||||
if not compare_args_ipa(ansible_module, member_args,
|
||||
res_find):
|
||||
# Generate addition and removal lists
|
||||
user_add = list(
|
||||
set(user or []) -
|
||||
set(res_find.get("member_user", [])))
|
||||
user_del = list(
|
||||
set(res_find.get("member_user", [])) -
|
||||
set(user or []))
|
||||
group_add = list(
|
||||
set(group or []) -
|
||||
set(res_find.get("member_group", [])))
|
||||
group_del = list(
|
||||
set(res_find.get("member_group", [])) -
|
||||
set(group or []))
|
||||
service_add = list(
|
||||
set(service or []) -
|
||||
set(res_find.get("member_service", [])))
|
||||
service_del = list(
|
||||
set(res_find.get("member_service", [])) -
|
||||
set(service or []))
|
||||
|
||||
# Add members
|
||||
if len(user_add) > 0 or len(group_add) > 0 or \
|
||||
len(service_add) > 0:
|
||||
commands.append([name, "group_add_member",
|
||||
{
|
||||
"user": user_add,
|
||||
"group": group_add,
|
||||
"service": service_add,
|
||||
}])
|
||||
# Remove members
|
||||
if len(user_del) > 0 or len(group_del) > 0 or \
|
||||
len(service_del) > 0:
|
||||
commands.append([name, "group_remove_member",
|
||||
{
|
||||
"user": user_del,
|
||||
"group": group_del,
|
||||
"service": service_del,
|
||||
}])
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No group '%s'" % name)
|
||||
|
||||
user_add = list(
|
||||
set(user or []) -
|
||||
set(res_find.get("member_user", [])))
|
||||
group_add = list(
|
||||
set(group or []) -
|
||||
set(res_find.get("member_group", [])))
|
||||
service_add = list(
|
||||
set(service or []) -
|
||||
set(res_find.get("member_service", [])))
|
||||
|
||||
# Add members
|
||||
if len(user_add) > 0 or len(group_add) > 0 or \
|
||||
len(service_add) > 0:
|
||||
commands.append([name, "group_add_member",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
"service": service,
|
||||
}])
|
||||
|
||||
elif state == "absent":
|
||||
if action == "group":
|
||||
if res_find is not None:
|
||||
commands.append([name, "group_del", {}])
|
||||
|
||||
elif action == "member":
|
||||
if res_find is None:
|
||||
ansible_module.fail_json(msg="No group '%s'" % name)
|
||||
|
||||
# Remove intersection member
|
||||
user_del = list(
|
||||
set(user or []) &
|
||||
set(res_find.get("member_user", [])))
|
||||
group_del = list(
|
||||
set(group or []) &
|
||||
set(res_find.get("member_group", [])))
|
||||
service_del = list(
|
||||
set(service or []) &
|
||||
set(res_find.get("member_service", [])))
|
||||
|
||||
# Remove members
|
||||
if len(user_del) > 0 or len(group_del) > 0 or \
|
||||
len(service_del) > 0:
|
||||
commands.append([name, "group_remove_member",
|
||||
{
|
||||
"user": user,
|
||||
"group": group,
|
||||
"service": service,
|
||||
}])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
api_command(ansible_module, command, to_text(name), args)
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -32,16 +32,16 @@ module: ipatopologysegment
|
||||
short description: Manage FreeIPA topology segments
|
||||
description: Manage FreeIPA topology segments
|
||||
options:
|
||||
principal:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
password:
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
suffix:
|
||||
description: Topology suffix
|
||||
required: true
|
||||
choices: ["domain", "ca"]
|
||||
choices: ["domain", "ca", "domain+ca"]
|
||||
name:
|
||||
description: Topology segment name, unique identifier.
|
||||
required: false
|
||||
@@ -59,7 +59,8 @@ options:
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled", "reinitialized"]
|
||||
choices: ["present", "absent", "enabled", "disabled", "reinitialized"
|
||||
"checked" ]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
@@ -87,16 +88,37 @@ EXAMPLES = """
|
||||
name: ipaserver.test.local-to-replica1.test.local
|
||||
direction: left-to-right
|
||||
state: reinitialized
|
||||
|
||||
- ipatopologysegment:
|
||||
suffix: domain+ca
|
||||
left: ipaserver.test.local
|
||||
right: ipareplica1.test.local
|
||||
state: absent
|
||||
|
||||
- ipatopologysegment:
|
||||
suffix: domain+ca
|
||||
left: ipaserver.test.local
|
||||
right: ipareplica1.test.local
|
||||
state: checked
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
found:
|
||||
description: List of found segments
|
||||
returned: if state is checked
|
||||
type: list
|
||||
not-found:
|
||||
description: List of not found segments
|
||||
returned: if state is checked
|
||||
type: list
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command
|
||||
|
||||
|
||||
def find_left_right(module, suffix, left, right):
|
||||
_args = {
|
||||
"iparepltoposegmentleftnode": to_text(left),
|
||||
@@ -129,12 +151,34 @@ def find_cn(module, suffix, name):
|
||||
return None
|
||||
|
||||
|
||||
def find_left_right_cn(module, suffix, left, right, name):
|
||||
if left is not None and right is not None:
|
||||
left_right = find_left_right(module, suffix, left, right)
|
||||
if left_right is not None:
|
||||
if name is not None and \
|
||||
left_right["cn"][0] != to_text(name):
|
||||
module.fail_json(
|
||||
msg="Left and right nodes do not match "
|
||||
"given name name (cn) '%s'" % name)
|
||||
return left_right
|
||||
# else: Nothing to change
|
||||
elif name is not None:
|
||||
cn = find_cn(module, suffix, name)
|
||||
if cn is not None:
|
||||
return cn
|
||||
# else: Nothing to change
|
||||
else:
|
||||
module.fail_json(
|
||||
msg="Either left and right or name need to be set.")
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
principal=dict(type="str", default="admin"),
|
||||
password=dict(type="str", required=False, no_log=True),
|
||||
suffix=dict(choices=["domain", "ca"], required=True),
|
||||
ipaadmin_principal=dict(type="str", default="admin"),
|
||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||
suffix=dict(choices=["domain", "ca", "domain+ca"], required=True),
|
||||
name=dict(type="str", aliases=["cn"], default=None),
|
||||
left=dict(type="str", aliases=["leftnode"], default=None),
|
||||
right=dict(type="str", aliases=["rightnode"], default=None),
|
||||
@@ -142,7 +186,7 @@ def main():
|
||||
choices=["left-to-right", "right-to-left"]),
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent", "enabled", "disabled",
|
||||
"reinitialized"]),
|
||||
"reinitialized", "checked"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -151,9 +195,9 @@ def main():
|
||||
|
||||
# Get parameters
|
||||
|
||||
principal = ansible_module.params.get("principal")
|
||||
password = ansible_module.params.get("password")
|
||||
suffix = ansible_module.params.get("suffix")
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
suffixes = ansible_module.params.get("suffix")
|
||||
name = ansible_module.params.get("name")
|
||||
left = ansible_module.params.get("left")
|
||||
right = ansible_module.params.get("right")
|
||||
@@ -169,109 +213,110 @@ def main():
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(principal):
|
||||
ccache_dir, ccache_name = temp_kinit(principal, password)
|
||||
if not valid_creds(ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
command = None
|
||||
commands = []
|
||||
|
||||
# Get name (cn) from left and right node if set for absent, disabled
|
||||
# or reinitialized.
|
||||
if state in ["absent", "disabled", "reinitialized"]:
|
||||
if left is not None and right is not None:
|
||||
left_right = find_left_right(ansible_module, suffix,
|
||||
left, right)
|
||||
if left_right is not None:
|
||||
if name is not None and \
|
||||
left_right["cn"][0] != to_text(name):
|
||||
ansible_module.fail_json(
|
||||
msg="Left and right nodes do not match "
|
||||
"given name name (cn) '%s'" % name)
|
||||
args = {
|
||||
"cn": left_right["cn"][0]
|
||||
}
|
||||
# else: Nothing to change
|
||||
elif name is not None:
|
||||
result = find_cn(ansible_module, suffix, name)
|
||||
if result is not None:
|
||||
args = {
|
||||
"cn": result["cn"][0]
|
||||
}
|
||||
# else: Nothing to change
|
||||
else:
|
||||
ansible_module.fail_json(
|
||||
msg="Either left and right or name need to be set.")
|
||||
for suffix in suffixes.split("+"):
|
||||
# Create command
|
||||
if state in ["present", "enabled"]:
|
||||
# Make sure topology segment exists
|
||||
|
||||
# Create command
|
||||
if state in ["present", "enabled"]:
|
||||
# Make sure topology segment exists
|
||||
|
||||
if left is None or right is None:
|
||||
ansible_module.fail_json(
|
||||
msg="Left and right need to be set.")
|
||||
args = {
|
||||
"iparepltoposegmentleftnode": to_text(left),
|
||||
"iparepltoposegmentrightnode": to_text(right),
|
||||
}
|
||||
if name is not None:
|
||||
args["cn"] = to_text(name)
|
||||
|
||||
res_left_right = find_left_right(ansible_module, suffix,
|
||||
left, right)
|
||||
if res_left_right is not None:
|
||||
if name is not None and \
|
||||
res_left_right["cn"][0] != to_text(name):
|
||||
if left is None or right is None:
|
||||
ansible_module.fail_json(
|
||||
msg="Left and right nodes already used with "
|
||||
"different name (cn) '%s'" % res_left_right["cn"])
|
||||
msg="Left and right need to be set.")
|
||||
args = {
|
||||
"iparepltoposegmentleftnode": to_text(left),
|
||||
"iparepltoposegmentrightnode": to_text(right),
|
||||
}
|
||||
if name is not None:
|
||||
args["cn"] = to_text(name)
|
||||
|
||||
# Left and right nodes and also the name can not be
|
||||
# changed
|
||||
for key in [ "iparepltoposegmentleftnode",
|
||||
"iparepltoposegmentrightnode" ]:
|
||||
if key in args:
|
||||
del args[key]
|
||||
if len(args) > 1:
|
||||
# cn needs to be in args always
|
||||
command = "topologysegment_mod"
|
||||
# else: Nothing to change
|
||||
else:
|
||||
if name is None:
|
||||
args["cn"] = to_text("%s-to-%s" % (left, right))
|
||||
command = "topologysegment_add"
|
||||
res_left_right = find_left_right(ansible_module, suffix,
|
||||
left, right)
|
||||
if res_left_right is not None:
|
||||
if name is not None and \
|
||||
res_left_right["cn"][0] != to_text(name):
|
||||
ansible_module.fail_json(
|
||||
msg="Left and right nodes already used with "
|
||||
"different name (cn) '%s'" % res_left_right["cn"])
|
||||
|
||||
elif state in ["absent", "disabled"]:
|
||||
# Make sure topology segment does not exist
|
||||
|
||||
if len(args) > 0:
|
||||
# Either name defined or found name from left and right node
|
||||
command = "topologysegment_del"
|
||||
|
||||
elif state == "reinitialized":
|
||||
# Reinitialize segment
|
||||
|
||||
if len(args) > 0:
|
||||
# Either name defined or found name from left and right node
|
||||
command = "topologysegment_reinitialize"
|
||||
|
||||
if direction == "left-to-right":
|
||||
args["left"] = True
|
||||
elif direction == "right-to-left":
|
||||
args["right"] = True
|
||||
# Left and right nodes and also the name can not be
|
||||
# changed
|
||||
for key in ["iparepltoposegmentleftnode",
|
||||
"iparepltoposegmentrightnode"]:
|
||||
if key in args:
|
||||
del args[key]
|
||||
if len(args) > 1:
|
||||
# cn needs to be in args always
|
||||
commands.append(["topologysegment_mod", args])
|
||||
# else: Nothing to change
|
||||
else:
|
||||
if name is None:
|
||||
args["cn"] = to_text("%s-to-%s" % (left, right))
|
||||
commands.append(["topologysegment_add", args])
|
||||
|
||||
elif state in ["absent", "disabled"]:
|
||||
# Make sure topology segment does not exist
|
||||
|
||||
res_find = find_left_right_cn(ansible_module, suffix,
|
||||
left, right, name)
|
||||
if res_find is not None:
|
||||
# Found either given name or found name from left and right
|
||||
# node
|
||||
args = {
|
||||
"cn": res_find["cn"][0]
|
||||
}
|
||||
commands.append(["topologysegment_del", args])
|
||||
|
||||
elif state == "checked":
|
||||
# Check if topology segment does exists
|
||||
|
||||
res_find = find_left_right_cn(ansible_module, suffix,
|
||||
left, right, name)
|
||||
if res_find is not None:
|
||||
# Found either given name or found name from left and right
|
||||
# node
|
||||
exit_args.setdefault("found", []).append(suffix)
|
||||
else:
|
||||
# Not found
|
||||
exit_args.setdefault("not-found", []).append(suffix)
|
||||
|
||||
elif state == "reinitialized":
|
||||
# Reinitialize segment
|
||||
|
||||
if direction not in ["left-to-right", "right-to-left"]:
|
||||
ansible_module.fail_json(msg="Unknown direction '%s'" %
|
||||
direction)
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
res_find = find_left_right_cn(ansible_module, suffix,
|
||||
left, right, name)
|
||||
if res_find is not None:
|
||||
# Found either given name or found name from left and right
|
||||
# node
|
||||
args = {
|
||||
"cn": res_find["cn"][0]
|
||||
}
|
||||
if direction == "left-to-right":
|
||||
args["left"] = True
|
||||
elif direction == "right-to-left":
|
||||
args["right"] = True
|
||||
|
||||
commands.append(["topologysegment_reinitialize", args])
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute command
|
||||
|
||||
if command is not None:
|
||||
result = api_command(ansible_module, command,
|
||||
to_text(suffix), args)
|
||||
for command, args in commands:
|
||||
api_command(ansible_module, command, to_text(suffix), args)
|
||||
changed = True
|
||||
|
||||
except Exception as e:
|
||||
@@ -282,7 +327,8 @@ def main():
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed)
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
@@ -32,10 +32,10 @@ module: ipatopologysuffix
|
||||
short description: Verify FreeIPA topology suffix
|
||||
description: Verify FreeIPA topology suffix
|
||||
options:
|
||||
principal:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
password:
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
suffix:
|
||||
@@ -60,14 +60,15 @@ RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import execute_api_command
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
principal=dict(type="str", default="admin"),
|
||||
password=dict(type="str", required=False, no_log=True),
|
||||
ipaadmin_principal=dict(type="str", default="admin"),
|
||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||
suffix=dict(choices=["domain", "ca"], required=True),
|
||||
state=dict(type="str", default="verified",
|
||||
choices=["verified"]),
|
||||
@@ -79,8 +80,8 @@ def main():
|
||||
|
||||
# Get parameters
|
||||
|
||||
principal = ansible_module.params.get("principal")
|
||||
password = ansible_module.params.get("password")
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
suffix = ansible_module.params.get("suffix")
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
@@ -98,12 +99,13 @@ def main():
|
||||
|
||||
# Execute command
|
||||
|
||||
execute_api_command(ansible_module, principal, password,
|
||||
execute_api_command(ansible_module, ipaadmin_principal, ipaadmin_password,
|
||||
command, to_text(suffix), args)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
457
plugins/modules/ipauser.py
Normal file
457
plugins/modules/ipauser.py
Normal file
@@ -0,0 +1,457 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipauser
|
||||
short description: Manage FreeIPA users
|
||||
description: Manage FreeIPA users
|
||||
options:
|
||||
ipaadmin_principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
ipaadmin_password:
|
||||
description: The admin password
|
||||
required: false
|
||||
name:
|
||||
description: The list of users (internally uid).
|
||||
required: false
|
||||
first:
|
||||
description: The first name
|
||||
required: false
|
||||
aliases: ["givenname"]
|
||||
last:
|
||||
description: The last name
|
||||
required: false
|
||||
fullname:
|
||||
description: The full name
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
displayname:
|
||||
description: The display name
|
||||
required: false
|
||||
homedir:
|
||||
description: The home directory
|
||||
required: false
|
||||
shell:
|
||||
description: The login shell
|
||||
required: false
|
||||
aliases: ["loginshell"]
|
||||
email:
|
||||
description: List of email addresses
|
||||
required: false
|
||||
principalname:
|
||||
description: The kerberos principal
|
||||
required: false
|
||||
aliases: ["krbprincipalname"]
|
||||
passwordexpiration:
|
||||
description:
|
||||
- The kerberos password expiration date
|
||||
- (possible formats: YYYYMMddHHmmssZ, YYYY-MM-ddTHH:mm:ssZ,
|
||||
- YYYY-MM-ddTHH:mmZ, YYYY-MM-ddZ, YYYY-MM-dd HH:mm:ssZ,
|
||||
- YYYY-MM-dd HH:mmZ) The trailing 'Z' can be skipped.
|
||||
required: false
|
||||
aliases: ["krbpasswordexpiration"]
|
||||
password:
|
||||
description: The user password
|
||||
required: false
|
||||
uid:
|
||||
description: The UID
|
||||
required: false
|
||||
aliases: ["uidnumber"]
|
||||
gid:
|
||||
description: The GID
|
||||
required: false
|
||||
aliases: ["gidnumber"]
|
||||
phone:
|
||||
description: List of telephone numbers
|
||||
required: false
|
||||
aliases: ["telephonenumber"]
|
||||
title:
|
||||
description: The job title
|
||||
required: false
|
||||
#sshpubkey:
|
||||
# description: List of SSH public keys
|
||||
# required: false
|
||||
# aliases: ["ipasshpubkey"]
|
||||
# ..
|
||||
update_password:
|
||||
description:
|
||||
Set password for a user in present state only on creation or always
|
||||
default: 'always'
|
||||
choices: ["always", "on_create"]
|
||||
preserve:
|
||||
description: Delete a user, keeping the entry available for future use
|
||||
required: false
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent",
|
||||
"enabled", "disabled",
|
||||
"unlocked", "undeleted"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Create user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
first: pinky
|
||||
last: Acme
|
||||
uid: 10001
|
||||
gid: 100
|
||||
phone: "+555123457"
|
||||
email: pinky@acme.com
|
||||
passwordexpiration: "2023-01-19 23:59:59"
|
||||
password: "no-brain"
|
||||
update_password: on_create
|
||||
|
||||
# Create user brain
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: brain
|
||||
first: brain
|
||||
last: Acme
|
||||
|
||||
# Delete user pinky, but preserved
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
preserve: yes
|
||||
state: absent
|
||||
|
||||
# Undelete user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky
|
||||
state: undeleted
|
||||
|
||||
# Disable user pinky
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: disabled
|
||||
|
||||
# Enable user pinky and brain
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: enabled
|
||||
|
||||
# Remove user pinky and brain
|
||||
- ipauser:
|
||||
ipaadmin_password: MyPassword123
|
||||
name: pinky,brain
|
||||
state: disabled
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command, date_format, \
|
||||
compare_args_ipa
|
||||
|
||||
|
||||
def find_user(module, name, preserved=False):
|
||||
_args = {
|
||||
"all": True,
|
||||
"uid": to_text(name),
|
||||
}
|
||||
if preserved:
|
||||
_args["preserved"] = preserved
|
||||
|
||||
_result = api_command(module, "user_find", to_text(name), _args)
|
||||
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="There is more than one user '%s'" % (name))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def gen_args(first, last, fullname, displayname, homedir, shell, emails,
|
||||
principalname, passwordexpiration, password, uid, gid,
|
||||
phones, title, sshpubkey):
|
||||
_args = {}
|
||||
if first is not None:
|
||||
_args["givenname"] = first
|
||||
if last is not None:
|
||||
_args["sn"] = last
|
||||
if fullname is not None:
|
||||
_args["cn"] = fullname
|
||||
if displayname is not None:
|
||||
_args["displayname"] = displayname
|
||||
if homedir is not None:
|
||||
_args["homedirectory"] = homedir
|
||||
if shell is not None:
|
||||
_args["loginshell"] = shell
|
||||
if emails is not None and len(emails) > 0:
|
||||
_args["mail"] = emails
|
||||
if principalname is not None:
|
||||
_args["krbprincipalname"] = principalname
|
||||
if passwordexpiration is not None:
|
||||
_args["krbpasswordexpiration"] = passwordexpiration
|
||||
if password is not None:
|
||||
_args["userpassword"] = password
|
||||
if uid is not None:
|
||||
_args["uidnumber"] = str(uid)
|
||||
if gid is not None:
|
||||
_args["gidnumber"] = str(gid)
|
||||
if phones is not None and len(phones) > 0:
|
||||
_args["telephonenumber"] = phones
|
||||
if title is not None:
|
||||
_args["title"] = title
|
||||
if sshpubkey is not None:
|
||||
_args["ipasshpubkey"] = sshpubkey
|
||||
|
||||
return _args
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
ipaadmin_principal=dict(type="str", default="admin"),
|
||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||
|
||||
name=dict(type="list", aliases=["login"], default=None,
|
||||
required=True),
|
||||
# present
|
||||
first=dict(type="str", aliases=["givenname"], default=None),
|
||||
last=dict(type="str", default=None),
|
||||
fullname=dict(type="str", aliases=["cn"], default=None),
|
||||
displayname=dict(type="str", default=None),
|
||||
homedir=dict(type="str", default=None),
|
||||
shell=dict(type="str", aliases=["loginshell"], default=None),
|
||||
email=dict(type="list", default=None),
|
||||
principalname=dict(type="str", aliases=["krbprincipalname"],
|
||||
default=None),
|
||||
passwordexpiration=dict(type="str",
|
||||
aliases=["krbpasswordexpiration"],
|
||||
default=None),
|
||||
password=dict(type="str", default=None, no_log=True),
|
||||
uid=dict(type="int", aliases=["uidnumber"], default=None),
|
||||
gid=dict(type="int", aliases=["gidnumber"], default=None),
|
||||
phone=dict(type="list", aliases=["telephonenumber"], default=None),
|
||||
title=dict(type="str", default=None),
|
||||
# sshpubkey=dict(type="list", aliases=["ipasshpubkey"],
|
||||
# default=None),
|
||||
update_password=dict(type='str', default=None,
|
||||
choices=['always', 'on_create']),
|
||||
# deleted
|
||||
preserve=dict(required=False, type='bool', default=None),
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent", "enabled", "disabled",
|
||||
"unlocked", "undeleted"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
ipaadmin_principal = ansible_module.params.get("ipaadmin_principal")
|
||||
ipaadmin_password = ansible_module.params.get("ipaadmin_password")
|
||||
names = ansible_module.params.get("name")
|
||||
|
||||
# present
|
||||
first = ansible_module.params.get("first")
|
||||
last = ansible_module.params.get("last")
|
||||
fullname = ansible_module.params.get("fullname")
|
||||
displayname = ansible_module.params.get("displayname")
|
||||
homedir = ansible_module.params.get("homedir")
|
||||
shell = ansible_module.params.get("shell")
|
||||
emails = ansible_module.params.get("email")
|
||||
principalname = ansible_module.params.get("principalname")
|
||||
passwordexpiration = ansible_module.params.get("passwordexpiration")
|
||||
if passwordexpiration is not None:
|
||||
if passwordexpiration[:-1] != "Z":
|
||||
passwordexpiration = "%sZ" % passwordexpiration
|
||||
passwordexpiration = date_format(passwordexpiration)
|
||||
password = ansible_module.params.get("password")
|
||||
uid = ansible_module.params.get("uid")
|
||||
gid = ansible_module.params.get("gid")
|
||||
phones = ansible_module.params.get("phone")
|
||||
title = ansible_module.params.get("title")
|
||||
sshpubkey = ansible_module.params.get("sshpubkey")
|
||||
update_password = ansible_module.params.get("update_password")
|
||||
# deleted
|
||||
preserve = ansible_module.params.get("preserve")
|
||||
# state
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state == "present":
|
||||
if len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Onle one user can be added at a time.")
|
||||
if first is None:
|
||||
ansible_module.fail_json(msg="First name is needed")
|
||||
if last is None:
|
||||
ansible_module.fail_json(msg="Last name is needed")
|
||||
|
||||
if state == "absent":
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(
|
||||
msg="No name given.")
|
||||
for x in ["first", "last", "fullname", "displayname", "homedir",
|
||||
"shell", "emails", "principalname", "passwordexpiration",
|
||||
"password", "uid", "gid", "phones", "title", "sshpubkey",
|
||||
"update_password"]:
|
||||
if vars()[x] is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Argument '%s' can not be used with state '%s'" %
|
||||
(x, state))
|
||||
else:
|
||||
if preserve is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Preserve is only possible for state=absent")
|
||||
|
||||
if update_password is None:
|
||||
update_password = "always"
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(ipaadmin_principal):
|
||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
||||
ipaadmin_password)
|
||||
api_connect()
|
||||
|
||||
commands = []
|
||||
|
||||
for name in names:
|
||||
# Make sure user exists
|
||||
res_find = find_user(ansible_module, name)
|
||||
# Also search for preserved user
|
||||
res_find_preserved = find_user(ansible_module, name,
|
||||
preserved=True)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
# Generate args
|
||||
args = gen_args(
|
||||
first, last, fullname, displayname, homedir, shell, emails,
|
||||
principalname, passwordexpiration, password, uid, gid,
|
||||
phones, title, sshpubkey)
|
||||
|
||||
# Also check preserved users
|
||||
if res_find is None and res_find_preserved is not None:
|
||||
res_find = res_find_preserved
|
||||
|
||||
# Found the user
|
||||
if res_find is not None:
|
||||
# Ignore password with update_password == on_create
|
||||
if update_password == "on_create" and \
|
||||
"userpassword" in args:
|
||||
del args["userpassword"]
|
||||
|
||||
# For all settings is args, check if there are
|
||||
# different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args, res_find):
|
||||
commands.append([name, "user_mod", args])
|
||||
else:
|
||||
commands.append([name, "user_add", args])
|
||||
|
||||
elif state == "absent":
|
||||
# Also check preserved users
|
||||
if res_find is None and res_find_preserved is not None:
|
||||
res_find = res_find_preserved
|
||||
|
||||
if res_find is not None:
|
||||
args = {}
|
||||
if preserve is not None:
|
||||
args["preserve"] = preserve
|
||||
commands.append([name, "user_del", args])
|
||||
|
||||
elif state == "undeleted":
|
||||
if res_find_preserved is not None:
|
||||
commands.append([name, "user_undel", {}])
|
||||
else:
|
||||
raise ValueError("No preserved user '%s'" % name)
|
||||
|
||||
elif state == "enabled":
|
||||
if res_find is not None:
|
||||
if res_find["nsaccountlock"]:
|
||||
commands.append([name, "user_enable", {}])
|
||||
else:
|
||||
raise ValueError("No disabled user '%s'" % name)
|
||||
|
||||
elif state == "disabled":
|
||||
if res_find is not None:
|
||||
if not res_find["nsaccountlock"]:
|
||||
commands.append([name, "user_disable", {}])
|
||||
else:
|
||||
raise ValueError("No user '%s'" % name)
|
||||
|
||||
elif state == "unlocked":
|
||||
if res_find is not None:
|
||||
commands.append([name, "user_unlock", {}])
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
for name, command, args in commands:
|
||||
try:
|
||||
api_command(ansible_module, command, to_text(name), args)
|
||||
changed = True
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="%s: %s: %s" % (command, name,
|
||||
str(e)))
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,13 +1,47 @@
|
||||
ipaclient role
|
||||
==============
|
||||
|
||||
Description
|
||||
-----------
|
||||
This [Ansible](https://www.ansible.com/) role allows to join hosts as clients to an IPA domain. This can be done in differnt ways using auto-discovery of the servers, domain and other settings or by specifying them.
|
||||
|
||||
**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
|
||||
--------
|
||||
* Client deployment
|
||||
* One-time-password (OTP) support
|
||||
* Repair mode
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.5 and up are supported by the client role. There is also limited support for verison 4.4.
|
||||
|
||||
|
||||
Supported Distributions
|
||||
-----------------------
|
||||
|
||||
* RHEL/CentOS 7.4+
|
||||
* Fedora 26+
|
||||
* Ubuntu
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
* /usr/bin/kinit is required on the controller if a one time password (OTP) is used
|
||||
* python3-gssapi is required on the controller if a one time password (OTP) is used to install the client.
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
* Supported distribution (needed for package installation only, see above)
|
||||
|
||||
This role allows to join hosts as clients to an IPA domain. This can be done in differnt ways using auto-discovery of the servers, domain and other settings or by specifying them.
|
||||
|
||||
Usage
|
||||
-----
|
||||
=====
|
||||
|
||||
Example inventory file with fixed principal using auto-discovery with DNS records:
|
||||
|
||||
@@ -74,78 +108,74 @@ Example playbook to setup the IPA client(s) using principal and password from in
|
||||
state: present
|
||||
```
|
||||
|
||||
|
||||
Playbooks
|
||||
=========
|
||||
|
||||
The playbooks needed to deploy or undeploy a client are part of the repository in the playbooks folder. There are also playbooks to deploy and undeploy clusters.
|
||||
```
|
||||
install-client.yml
|
||||
uninstall-client.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.
|
||||
|
||||
|
||||
How to setup a client
|
||||
---------------------
|
||||
|
||||
```bash
|
||||
ansible-playbook -v -i inventory/hosts install-client.yml
|
||||
```
|
||||
This will deploy the clients defined in the inventory file.
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
=========
|
||||
|
||||
### `ipaclients`
|
||||
Base Variables
|
||||
--------------
|
||||
|
||||
The mandatory `ipaclients` group is a list of the names of the IPA clients in FQDN form. All these clients will be installed or configured using the playbook.
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaclients` | This group is a list of the names of the IPA clients in FQDN form. All these clients will be installed or configured using the playbook. | yes
|
||||
`ipaclient_domain` | This string value sets the DNS domain that will be used for client installation. Usually the DNS domain is a lower-cased name of the Kerberos realm. If the role is for example used in a cluster inventory and `ipaserver_domain` is set, then it will be used. | no
|
||||
`ipaclient_realm` | This string value sets the Kerberos realm that will be used for client installation. Usually the Kerberos realm is an upper-cased name of the DNS domain. If the role is for example used in a cluster inventory and `ipaserver_realm` is set, then it will be used. If `ipaclient_realm` is not set, then it will be generated from `ipaclient_domain` if this is set. | no
|
||||
`ipaclient_mkhomedir` | This bool value defines if PAM will be configured to create a users home directory if it does not exist. `ipaclient_mkhomedir` defaults to `no`. | no
|
||||
`ipaclient_force_join` | This bool value defines if an already enrolled host can join again. `ipaclient_force_join` defaults to `no`. | no
|
||||
`ipaclient_kinit_attempts` | The int value defines the number of tries to repeat the request for a failed host Kerberos ticket. `ipaclient_kinit_attempts` defaults to 5.| no
|
||||
`ipaclient_ntp_servers` | The list defines the NTP servers to be used. | no
|
||||
`ipaclient_ntp_pool` | The string value defines the ntp server pool to be used. | no
|
||||
`ipaclient_no_ntp` | The bool value defines if NTP will not be configured and enabled. `ipaclient_no_ntp` defaults to `no`. | no
|
||||
`ipaclient_ssh_trust_dns` | The bool value defines if OpenSSH client will be configured to trust DNS SSHFP records. `ipaclient_ssh_trust_dns` defaults to `no`. | no
|
||||
`ipaclient_no_ssh` | The bool value defines if OpenSSH client will be configured. `ipaclient_no_ssh` defaults to `no`. | no
|
||||
`ipaclient_no_sshd` | The bool value defines if OpenSSH server will be configured. `ipaclient_no_sshd` defaults to `no`. | no
|
||||
`ipaclient_no_sudo` | The bool value defines if SSSD will be configured as a data source for sudo. `ipaclient_no_sudo` defaults to `no`. | no
|
||||
`ipaclient_no_dns_sshfp` | The bool value defines if DNS SSHFP records will not be created automatically. `ipaclient_no_dns_sshfp` defaults to `no`. | no
|
||||
`ipaclient_force` | The bool value defines if settings will be forced even in the error case. `ipaclient_force` defaults to `no`. | no
|
||||
`ipaclient_force_ntpd` | The bool value defines if ntpd usage will be forced. This is not supported anymore and leads to a warning. `ipaclient_force_ntpd` defaults to `no`. | no
|
||||
`ipaclient_nisdomain` | This string value defines the NIS domain name. | no
|
||||
`ipaclient_no_nisdomain` | The bool value defines if the NIS domain name will not be configured. `ipaclient_no_nisdomain` defaults to `no`. | no
|
||||
`ipaclient_configure_firefox` | The bool value defines if Firefox will be configured to use IPA domain credentials. `ipaclient_configure_firefox` defaults to `no`. | no
|
||||
`ipaclient_firefox_dir` | The string value defines the Firefox installation directory. For example: '/usr/lib/firefox'. | no
|
||||
`ipaclient_all_ip_addresses` | The bool value defines if DNS A/AAAA records for each IP address on the client will be created. `ipaclient_all_ip_addresses` defaults to `no`. | no
|
||||
`ipasssd_fixed_primary` | The bool value defines if SSSD will be configured to use a fixed server as the primary IPA server. `ipasssd_fixed_primary` defaults to `no`. | no
|
||||
`ipasssd_permit` | The bool value defines if SSSD will be configured to permit all access. Otherwise the machine will be controlled by the Host-based Access Controls (HBAC) on the IPA server. `ipasssd_permit` defaults to `no`. | no
|
||||
`ipasssd_enable_dns_updates` | The bool value tells SSSD to automatically update DNS with the IP address of this client. `ipasssd_enable_dns_updates` defaults to `no`. | no
|
||||
`ipasssd_no_krb5_offline_passwords` | The bool value defines if SSSD will be configured not to store user password when the server is offline . `ipasssd_no_krb5_offline_passwords` defaults to `no`. | no
|
||||
`ipasssd_preserve_sssd` | The bool value defines if the old SSSD configuration will be preserved if it is not possible to merge it with a new one. `ipasssd_preserve_sssd` defaults to `no`. | no
|
||||
`ipaclient_request_cert` | The bool value defines if the certificate for the machine wil be requested. The certificate will be stored in /etc/ipa/nssdb under the nickname "Local IPA host". . `ipaclient_request_cert` defaults to `no`. The option is deprecated and will be removed in a future release. | no
|
||||
`ipaclient_keytab` | The string value contains the path on the node of a backup host keytab from a previous enrollment. | no
|
||||
|
||||
### `ipaclient_domain`
|
||||
|
||||
The optional `ipaclient_domain` variable sets the DNS domain that will be used for client installation. Usually the DNS domain is a lower-cased name of the Kerberos realm.
|
||||
|
||||
If `ipaclient_domain` is not set, then it will be generated from the domain part of the first entry from the `ipaservers` FQDN group if the group is defined and contains at least one entry. If `ipaservers` is not defined, then the domain will be tried to gather using DNS autodiscovery. `ipaclient_domain` needs to be set if the primary DNS domain is different from domain part of the server FQDN.
|
||||
|
||||
### `ipaclient_realm`
|
||||
|
||||
The optional `ipaclient_realm` sets the Kerberos realm that will be used for client installation. Usually the Kerberos realm is an upper-cased name of the DNS domain.
|
||||
|
||||
If `ipaclient_realm` is not set, then it will be generated from `ipaclient_domain` if this is set. If both are not set, then this
|
||||
|
||||
|
||||
### `ipaclient_keytab`
|
||||
|
||||
The optional `ipaclient_keytab` contains the path of a backup host keytab from a previous enrollment.
|
||||
|
||||
### `ipaclient_force_join`
|
||||
|
||||
The `ipaclient_force_join` bool value defines if an already enrolled host can join again. `ipaclient_force_join` defaults to `no`.
|
||||
|
||||
### `ipaclient_use_otp`
|
||||
|
||||
The `ipaclient_use_otp` bool value defines if a one-time password will be generated to join a new or existing host. `ipaclient_use_otp` defaults to `no`.
|
||||
|
||||
The enforcement on an existing host is not done if there is a working krb5.keytab on the host. If the generation of an otp is enforced for an existing host entry, then the host gets diabled and the containing keytab gets removed.
|
||||
|
||||
### `ipaclient_allow_repair`
|
||||
|
||||
The `ipaclient_allow_repair` bool value defines if an already joined or partly set-up client can be repaired. `ipaclient_allow_repair` defaults to `no`.
|
||||
|
||||
Contrary to `ipaclient_force_join=yes` the host entry will not be changed on the server.
|
||||
|
||||
### `ipaclient_kinit_attempts`
|
||||
|
||||
The optional `ipaclient_kinit_attempts` defines the number of tries to repeat the request for a failed host Kerberos ticket. `ipaclient_kinit_attempts` defaults to 3.
|
||||
|
||||
### `ipaclient_no_ntp`
|
||||
|
||||
The `ipaclient_no_ntp` bool value defines if NTP will not be configured and enabled. `ipaclient_no_ntp` defaults to `no`.
|
||||
|
||||
### `ipaclient_mkhomedir`
|
||||
|
||||
The `ipaclient_mkhomedir` bool value defines if PAM will be configured to create a users home directory if it does not exist. `ipaclient_mkhomedir` defaults to `no`.
|
||||
|
||||
Server Variables
|
||||
----------------
|
||||
|
||||
### `ipaservers`
|
||||
|
||||
The optional `ipaservers` group is a list of the IPA server full qualified host names. In a topology with a chain of servers and replicas, it is important to use the right server or replica as the server for the client. If there is a need to overwrite the setting for a client in the `ipaclients` group, please use the list `ipaclient_servers` explained below.
|
||||
|
||||
If no `ipaservers` group is defined than the installation preparation step will try to use DNS autodiscovery to identify the the IPA server using DNS txt records.
|
||||
|
||||
### `ipaadmin_keytab`
|
||||
|
||||
The `ipaadmin_keytab` variable enables the use of an admin keytab as an alternativce authentication method. The variable needs to contain the local path to the keytab file. If `ipaadmin_keytab` is used, then `ipaadmin_password` does not need to be set.
|
||||
|
||||
### `ipaadmin_principal`
|
||||
|
||||
The optional `ipaadmin_principal` variable only needs to be set if the name of the Kerberos admin principal is not "admin". If `ipaadmin_principal` is not set it will be set internally to "admin".
|
||||
|
||||
### `ipaadmin_password`
|
||||
|
||||
The `ipaadmin_password` variable contains the Kerberos password of the Kerberos admin principal. If `ipaadmin_keytab` is used, then `ipaadmin_password` does not need to be set.
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaservers` | This group is a list of the IPA server full qualified host names. In a topology with a chain of servers and replicas, it is important to use the right server or replica as the server for the client. If there is a need to overwrite the setting for a client in the `ipaclients` group, please use the list `ipaclient_servers` explained below. If no `ipaservers` group is defined than the installation preparation step will try to use DNS autodiscovery to identify the the IPA server using DNS txt records. | mostly
|
||||
`ipaadmin_keytab` | The string variable enables the use of an admin keytab as an alternativce authentication method. The variable needs to contain the local path to the keytab file. If `ipaadmin_keytab` is used, then `ipaadmin_password` does not need to be set. If `ipaadmin_keytab` is used with `ipaclient_use_otp: yes` then the keytab needs to be available on the contoller, else on the client node. The use of full path names is recommended. | no
|
||||
`ipaadmin_principal` | The string variable only needs to be set if the name of the Kerberos admin principal is not "admin". If `ipaadmin_principal` is not set it will be set internally to "admin". | no
|
||||
`ipaadmin_password` | The string variable contains the Kerberos password of the Kerberos admin principal. If `ipaadmin_keytab` is used, then `ipaadmin_password` does not need to be set. | mostly
|
||||
|
||||
|
||||
Topology Variables
|
||||
@@ -153,21 +183,25 @@ Topology Variables
|
||||
|
||||
These variables can be used to define or change how clients are arranged within a cluster for example.
|
||||
|
||||
### `ipaclient_no_dns_lookup`
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaclient_no_dns_lookup` | The bool value defines if the `ipaservers` group will be used as servers for the clients automatically. If enabled this deactivates DNS lookup in Kerberos in client installations. `ipaclient_no_dns_lookup` defauults to `no`. | no
|
||||
`ipaclient_servers` | The optional list can be used to manually override list of servers on a per client basis. The list of servers is normally taken from from `ipaservers` group. | no
|
||||
|
||||
The `ipaclient_no_dns_lookup` bool value defines if the `ipaservers` group will be used as servers for the clients automatically. If enabled this deactivates DNS lookup in Kerberos in client installations. `ipaclient_no_dns_lookup` defauults to `no`.
|
||||
|
||||
### `ipaclient_servers`
|
||||
Special Variables
|
||||
-----------------
|
||||
|
||||
The optional `ipaclient_servers` varaible can be used to manually override list of servers on a per client basis. The list of servers is normally taken from from `ipaservers` group.
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaclient_use_otp` | The bool value defines if a one-time password will be generated to join a new or existing host. `ipaclient_use_otp` defaults to `no`. The enforcement on an existing host is not done if there is a working krb5.keytab on the host. If the generation of an otp is enforced for an existing host entry, then the host gets diabled and the containing keytab gets removed. | no
|
||||
`ipaclient_allow_repair` | The bool value defines if an already joined or partly set-up client can be repaired. `ipaclient_allow_repair` defaults to `no`. Contrary to `ipaclient_force_join=yes` the host entry will not be changed on the server. | no
|
||||
`ipaclient_install_packages` | The bool value defines if the needed packages are installed on the node. `ipaclient_install_packages` defaults to `yes`. | no
|
||||
`ipaclient_on_master` | The bool value is only used in the server and replica installation process to install the client part. It should not be set otherwise. `ipaclient_on_master` defaults to `no`. | no
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
freeipa-client v4.4 or later
|
||||
|
||||
Authors
|
||||
-------
|
||||
=======
|
||||
|
||||
Florence Blanc-Renaud
|
||||
|
||||
|
||||
@@ -31,11 +31,6 @@ from ansible.errors import AnsibleError
|
||||
from ansible.module_utils._text import to_native
|
||||
from ansible.plugins.action import ActionBase
|
||||
|
||||
try:
|
||||
from __main__ import display
|
||||
except ImportError:
|
||||
from ansible.utils.display import Display
|
||||
display = Display()
|
||||
|
||||
def run_cmd(args, stdin=None):
|
||||
"""
|
||||
@@ -50,9 +45,10 @@ def run_cmd(args, stdin=None):
|
||||
|
||||
p = subprocess.Popen(args, stdin=p_in, stdout=p_out, stderr=p_err,
|
||||
close_fds=True)
|
||||
stdout, stderr = p.communicate(stdin)
|
||||
__temp, stderr = p.communicate(stdin)
|
||||
|
||||
return p.returncode
|
||||
if p.returncode != 0:
|
||||
raise RuntimeError(stderr)
|
||||
|
||||
|
||||
def kinit_password(principal, password, ccache_name, config):
|
||||
@@ -60,13 +56,12 @@ def kinit_password(principal, password, ccache_name, config):
|
||||
Perform kinit using principal/password, with the specified config file
|
||||
and store the TGT in ccache_name.
|
||||
"""
|
||||
args = [ "/usr/bin/kinit", principal, '-c', ccache_name]
|
||||
args = ["/usr/bin/kinit", principal, '-c', ccache_name]
|
||||
old_config = os.environ.get('KRB5_CONFIG')
|
||||
os.environ['KRB5_CONFIG'] = config
|
||||
|
||||
try:
|
||||
result = run_cmd(args, stdin=password.encode())
|
||||
return result
|
||||
return run_cmd(args, stdin=password.encode())
|
||||
finally:
|
||||
if old_config is not None:
|
||||
os.environ['KRB5_CONFIG'] = old_config
|
||||
@@ -126,6 +121,7 @@ KRB5CONF_TEMPLATE = """
|
||||
{{ ipa_domain }} = {{ ipa_realm }}
|
||||
"""
|
||||
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
|
||||
def run(self, tmp=None, task_vars=None):
|
||||
@@ -155,8 +151,6 @@ class ActionModule(ActionBase):
|
||||
keytab = self._task.args.get('keytab', None)
|
||||
password = self._task.args.get('password', None)
|
||||
lifetime = self._task.args.get('lifetime', '1h')
|
||||
ansible_python_interpreter = self._task.args.get('ansible_python_interpreter', None)
|
||||
task_vars["ansible_python_interpreter"] = ansible_python_interpreter
|
||||
|
||||
if (not keytab and not password):
|
||||
result['failed'] = True
|
||||
@@ -168,8 +162,8 @@ class ActionModule(ActionBase):
|
||||
result['msg'] = "principal is required"
|
||||
return result
|
||||
|
||||
data = self._execute_module(module_name='ipaclient_get_facts', module_args=dict(),
|
||||
task_vars={ "ansible_python_interpreter": ansible_python_interpreter })
|
||||
data = self._execute_module(module_name='ipaclient_get_facts',
|
||||
module_args=dict(), task_vars=None)
|
||||
try:
|
||||
domain = data['ansible_facts']['ipa']['domain']
|
||||
realm = data['ansible_facts']['ipa']['realm']
|
||||
@@ -199,12 +193,14 @@ class ActionModule(ActionBase):
|
||||
f.write(content)
|
||||
|
||||
if password:
|
||||
# perform kinit -c ccache_name -l 1h principal
|
||||
res = kinit_password(principal, password, ccache_name,
|
||||
krb5conf_name)
|
||||
if res:
|
||||
try:
|
||||
# perform kinit -c ccache_name -l 1h principal
|
||||
kinit_password(principal, password, ccache_name,
|
||||
krb5conf_name)
|
||||
except Exception as e:
|
||||
result['failed'] = True
|
||||
result['msg'] = 'kinit %s with password failed' % principal
|
||||
result['msg'] = 'kinit %s with password failed: %s' % \
|
||||
(principal, to_native(e))
|
||||
return result
|
||||
|
||||
else:
|
||||
@@ -221,7 +217,8 @@ class ActionModule(ActionBase):
|
||||
kinit_keytab(principal, keytab, ccache_name, krb5conf_name)
|
||||
except Exception as e:
|
||||
result['failed'] = True
|
||||
result['msg'] = 'kinit %s with keytab %s failed' % (principal, keytab)
|
||||
result['msg'] = 'kinit %s with keytab %s failed: %s' % \
|
||||
(principal, keytab, str(e))
|
||||
return result
|
||||
|
||||
try:
|
||||
|
||||
@@ -29,21 +29,23 @@ ANSIBLE_METADATA = {'metadata_version': '1.0',
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_api
|
||||
short description: Create temporary NSS database, call IPA API for remaining enrollment parts
|
||||
short description:
|
||||
Create temporary NSS database, call IPA API for remaining enrollment parts
|
||||
description:
|
||||
Create temporary NSS database, call IPA API for remaining enrollment parts
|
||||
Create temporary NSS database, call IPA API for remaining enrollment parts
|
||||
options:
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: true
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
debug:
|
||||
description: Turn on extra debugging
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -70,23 +72,26 @@ subject_base:
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
import time
|
||||
import tempfile
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
paths, x509, NUM_VERSION, serialization, certdb, api,
|
||||
delete_persistent_client_session_data, write_tmp_file,
|
||||
ipa_generate_password, CalledProcessError, errors, disable_ra, DN,
|
||||
CLIENT_INSTALL_ERROR, logger
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
debug=dict(required=False, type='bool', default="false")
|
||||
debug=dict(required=False, type='bool', default="false"),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -97,13 +102,13 @@ def main():
|
||||
|
||||
host_principal = 'host/%s@%s' % (hostname, realm)
|
||||
os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
|
||||
|
||||
ca_certs = x509.load_certificate_list_from_file(paths.IPA_CA_CRT)
|
||||
if NUM_VERSION >= 40500 and NUM_VERSION < 40590:
|
||||
ca_certs = [ cert.public_bytes(serialization.Encoding.DER)
|
||||
for cert in ca_certs ]
|
||||
if 40500 <= NUM_VERSION < 40590:
|
||||
ca_certs = [cert.public_bytes(serialization.Encoding.DER)
|
||||
for cert in ca_certs]
|
||||
elif NUM_VERSION < 40500:
|
||||
ca_certs = [ cert.der_data for cert in ca_certs ]
|
||||
ca_certs = [cert.der_data for cert in ca_certs]
|
||||
|
||||
with certdb.NSSDatabase() as tmp_db:
|
||||
api.bootstrap(context='cli_installer',
|
||||
@@ -137,7 +142,7 @@ def main():
|
||||
else:
|
||||
tmp_db.add_cert(cert, 'CA certificate %d' % (i + 1),
|
||||
'C,,')
|
||||
except CalledProcessError as e:
|
||||
except CalledProcessError:
|
||||
module.fail_json(msg="Failed to add CA to temporary NSS database.")
|
||||
|
||||
api.finalize()
|
||||
@@ -173,10 +178,12 @@ def main():
|
||||
"may not be available")
|
||||
except errors.PublicError as e2:
|
||||
module.fail_json(
|
||||
msg="Cannot connect to the IPA server RPC interface: %s" % e2)
|
||||
msg="Cannot connect to the IPA server RPC interface: "
|
||||
"%s" % e2)
|
||||
except errors.PublicError as e:
|
||||
module.fail_json(
|
||||
msg="Cannot connect to the server due to generic error: %s" % e)
|
||||
msg="Cannot connect to the server due to generic error: "
|
||||
"%s" % e)
|
||||
# Use the RPC directly so older servers are supported
|
||||
try:
|
||||
result = api.Backend.rpcclient.forward(
|
||||
@@ -198,7 +205,7 @@ def main():
|
||||
try:
|
||||
config = api.Command['config_show']()['result']
|
||||
subject_base = str(DN(config['ipacertificatesubjectbase'][0]))
|
||||
except errors.PublicError as e:
|
||||
except errors.PublicError:
|
||||
try:
|
||||
config = api.Backend.rpcclient.forward(
|
||||
'config_show',
|
||||
@@ -217,5 +224,6 @@ def main():
|
||||
ca_enabled=ca_enabled,
|
||||
subject_base=subject_base)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -34,20 +34,19 @@ description:
|
||||
Repair Fix IPA ca certificate
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: true
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
basedn:
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com).
|
||||
required: true
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
allow_repair:
|
||||
description: Allow repair of already joined hosts. Contrary to ipaclient_force_join the host entry will not be changed on the server.
|
||||
required: true
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
Allow repair of already joined hosts. Contrary to ipaclient_force_join
|
||||
the host entry will not be changed on the server
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -67,11 +66,15 @@ RETURN = '''
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
SECURE_PATH, paths, sysrestore, options, NUM_VERSION, get_ca_cert,
|
||||
get_ca_certs, errors
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
realm=dict(required=True),
|
||||
basedn=dict(required=True),
|
||||
@@ -90,7 +93,6 @@ def main():
|
||||
os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
|
||||
options.ca_cert_file = None
|
||||
options.unattended = True
|
||||
options.principal = None
|
||||
options.force = False
|
||||
options.password = None
|
||||
@@ -99,7 +101,7 @@ def main():
|
||||
if not os.path.exists(paths.IPA_CA_CRT):
|
||||
if not allow_repair:
|
||||
module.fail_json(
|
||||
msg="%s missing, enable allow_repair to fix it." % \
|
||||
msg="%s missing, enable allow_repair to fix it." %
|
||||
paths.IPA_CA_CRT)
|
||||
|
||||
# Repair missing ca.crt file
|
||||
@@ -119,5 +121,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -37,7 +37,7 @@ Backup files using IPA client sysrestore
|
||||
options:
|
||||
backup:
|
||||
description: File to backup
|
||||
required: true
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -52,11 +52,14 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
paths, sysrestore
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
backup=dict(required=True),
|
||||
),
|
||||
)
|
||||
@@ -71,5 +74,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -4,10 +4,14 @@
|
||||
import os
|
||||
import re
|
||||
import six
|
||||
from six.moves.configparser import RawConfigParser
|
||||
try:
|
||||
from six.moves.configparser import RawConfigParser
|
||||
except ImportError:
|
||||
from ConfigParser import RawConfigParser
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
|
||||
# pylint: disable=unused-import
|
||||
try:
|
||||
from ipalib import api
|
||||
except ImportError:
|
||||
@@ -48,6 +52,7 @@ def is_ntpd_configured():
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
|
||||
def is_dns_configured():
|
||||
# dns is configured when /etc/named.conf contains the line
|
||||
# dyndb "ipa" "/usr/lib64/bind/ldap.so" {
|
||||
@@ -62,20 +67,24 @@ def is_dns_configured():
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
|
||||
def is_dogtag_configured(subsystem):
|
||||
# ca / kra is configured when the directory /var/lib/pki/pki-tomcat/[ca|kra]
|
||||
# exists
|
||||
available_subsystems = { 'ca', 'kra' }
|
||||
# ca / kra is configured when the directory
|
||||
# /var/lib/pki/pki-tomcat/[ca|kra] # exists
|
||||
available_subsystems = {'ca', 'kra'}
|
||||
assert subsystem in available_subsystems
|
||||
|
||||
return os.path.isdir(os.path.join(VAR_LIB_PKI_TOMCAT, subsystem))
|
||||
|
||||
|
||||
def is_ca_configured():
|
||||
return is_dogtag_configured('ca')
|
||||
|
||||
|
||||
def is_kra_configured():
|
||||
return is_dogtag_configured('kra')
|
||||
|
||||
|
||||
def is_client_configured():
|
||||
# IPA Client is configured when /etc/ipa/default.conf exists
|
||||
# and /var/lib/ipa-client/sysrestore/sysrestore.state exists
|
||||
@@ -83,12 +92,14 @@ def is_client_configured():
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
return (os.path.isfile(paths.IPA_DEFAULT_CONF) and fstore.has_files())
|
||||
|
||||
|
||||
def is_server_configured():
|
||||
# IPA server is configured when /etc/ipa/default.conf exists
|
||||
# and /var/lib/ipa/sysrestore/sysrestore.state exists
|
||||
return (os.path.isfile(paths.IPA_DEFAULT_CONF) and
|
||||
os.path.isfile(SERVER_SYSRESTORE_STATE))
|
||||
|
||||
|
||||
def get_ipa_conf():
|
||||
# Extract basedn, realm and domain from /etc/ipa/default.conf
|
||||
parser = RawConfigParser()
|
||||
@@ -102,6 +113,7 @@ def get_ipa_conf():
|
||||
domain=domain
|
||||
)
|
||||
|
||||
|
||||
def get_ipa_version():
|
||||
try:
|
||||
from ipapython import version
|
||||
@@ -114,7 +126,8 @@ def get_ipa_version():
|
||||
# 4.4.90.201610191151GITd852c00
|
||||
# 4.4.90.dev201701071308+git2e43db1
|
||||
# 4.6.90.pre2
|
||||
if part.startswith('dev') or part.startswith('pre') or 'GIT' in part:
|
||||
if part.startswith('dev') or part.startswith('pre') or \
|
||||
'GIT' in part:
|
||||
version_info.append(part)
|
||||
else:
|
||||
version_info.append(int(part))
|
||||
@@ -126,10 +139,11 @@ def get_ipa_version():
|
||||
version=version.VERSION,
|
||||
version_info=version_info
|
||||
)
|
||||
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(),
|
||||
argument_spec=dict(),
|
||||
supports_check_mode=True
|
||||
)
|
||||
|
||||
@@ -137,7 +151,7 @@ def main():
|
||||
# check mode is supported
|
||||
|
||||
facts = dict(
|
||||
packages= dict(
|
||||
packages=dict(
|
||||
ipalib=HAS_IPALIB,
|
||||
ipaserver=HAS_IPASERVER,
|
||||
),
|
||||
@@ -156,7 +170,7 @@ def main():
|
||||
facts['configured']['client'] = True
|
||||
|
||||
facts['version'] = get_ipa_version()
|
||||
for key,value in six.iteritems(get_ipa_conf()):
|
||||
for key, value in six.iteritems(get_ipa_conf()):
|
||||
facts[key] = value
|
||||
|
||||
if HAS_IPASERVER:
|
||||
@@ -172,5 +186,6 @@ def main():
|
||||
ansible_facts=dict(ipa=facts)
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -35,48 +35,31 @@ description:
|
||||
host operations.
|
||||
options:
|
||||
principal:
|
||||
description: Kerberos principal used to manage the host
|
||||
required: true
|
||||
default: admin
|
||||
password:
|
||||
description: Password for the kerberos principal
|
||||
required: false
|
||||
keytab:
|
||||
description: Keytab file containing the Kerberos principal and encrypted key
|
||||
required: false
|
||||
lifetime:
|
||||
description: Sets the default lifetime for initial ticket requests
|
||||
required: false
|
||||
default: 1h
|
||||
description:
|
||||
User Principal allowed to promote replicas and join IPA realm
|
||||
required: yes
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: yes
|
||||
fqdn:
|
||||
description: the fully-qualified hostname of the host to add/modify/remove
|
||||
required: true
|
||||
random:
|
||||
description: generate a random password to be used in bulk enrollment
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
state:
|
||||
description: the host state
|
||||
required: false
|
||||
default: present
|
||||
choices: [ "present", "absent" ]
|
||||
description:
|
||||
The fully-qualified hostname of the host to add/modify/remove
|
||||
required: no
|
||||
certificates:
|
||||
description: a list of host certificates
|
||||
required: false
|
||||
type: list
|
||||
description: A list of host certificates
|
||||
required: yes
|
||||
sshpubkey:
|
||||
description: the SSH public key for the host
|
||||
required: false
|
||||
description: The SSH public key for the host
|
||||
required: yes
|
||||
ipaddress:
|
||||
description: the IP address for the host
|
||||
required: false
|
||||
ansible_python_interpreter:
|
||||
desciption: The ansible python interpreter used in the action plugin part, ignored here
|
||||
required: false
|
||||
|
||||
requirements:
|
||||
- gssapi on the Ansible controller
|
||||
description: The IP address for the host
|
||||
required: yes
|
||||
random:
|
||||
description: Generate a random password to be used in bulk enrollment
|
||||
required: yes
|
||||
state:
|
||||
description: The desired host state
|
||||
required: yes
|
||||
author:
|
||||
- "Florence Blanc-Renaud"
|
||||
'''
|
||||
@@ -91,26 +74,6 @@ EXAMPLES = '''
|
||||
ipaddress: 192.168.100.23
|
||||
random: True
|
||||
register: result_ipaclient_get_otp
|
||||
|
||||
# Add a new host, authenticate with a keytab stored on the controller node
|
||||
- ipaclient_get_otp:
|
||||
keytab: admin.keytab
|
||||
fqdn: ipaclient.ipa.domain.com
|
||||
|
||||
# Remove a host, authenticate using principal/password
|
||||
- ipaclient_get_otp:
|
||||
principal: admin
|
||||
password: MySecretPassword
|
||||
fqdn: ipaclient.ipa.domain.com
|
||||
state: absent
|
||||
|
||||
# Modify a host, add ssh public key:
|
||||
- ipaclient_get_otp:
|
||||
principal: admin
|
||||
password: MySecretPassword
|
||||
fqdn: ipaclient.ipa.domain.com
|
||||
sshpubkey: ssh-rsa AAAA...
|
||||
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
@@ -169,6 +132,7 @@ from ipapython.ipautil import run
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def get_host_diff(ipa_host, module_host):
|
||||
"""
|
||||
Compares two dictionaries containing host attributes and builds a dict
|
||||
@@ -194,7 +158,7 @@ def get_host_diff(ipa_host, module_host):
|
||||
ipa_value = sorted(ipa_value)
|
||||
module_value = sorted(module_value)
|
||||
if ipa_value != module_value:
|
||||
data[key]=unicode(module_value)
|
||||
data[key] = unicode(module_value)
|
||||
return data
|
||||
|
||||
|
||||
@@ -249,7 +213,7 @@ def ensure_host_present(module, api, ipahost):
|
||||
# If we want to create a random password, and the host
|
||||
# already has Keytab: true, then we need first to run
|
||||
# ipa host-disable in order to remove OTP and keytab
|
||||
if module.params.get('random') and ipahost['has_keytab'] == True:
|
||||
if module.params.get('random') and ipahost['has_keytab'] is True:
|
||||
api.Command.host_disable(fqdn)
|
||||
|
||||
result = api.Command.host_mod(fqdn, **diffs)
|
||||
@@ -268,6 +232,8 @@ def ensure_host_present(module, api, ipahost):
|
||||
|
||||
# Must add the user
|
||||
module_host = get_module_host(module)
|
||||
# force creation of host even if there is no DNS record
|
||||
module_host["force"] = True
|
||||
result = api.Command.host_add(fqdn, **module_host)
|
||||
# Save random password as it is not displayed by host-show
|
||||
if module.params.get('random'):
|
||||
@@ -310,15 +276,14 @@ def main():
|
||||
"""
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
principal = dict(default='admin'),
|
||||
ccache = dict(required=False, type='path'),
|
||||
fqdn = dict(required=True),
|
||||
certificates = dict(required=False, type='list'),
|
||||
sshpubkey= dict(required=False),
|
||||
ipaddress = dict(required=False),
|
||||
random = dict(default=False, type='bool'),
|
||||
state = dict(default='present', choices=[ 'present', 'absent' ]),
|
||||
ansible_python_interpreter = dict(required=False),
|
||||
principal=dict(default='admin'),
|
||||
ccache=dict(required=False, type='path'),
|
||||
fqdn=dict(required=True),
|
||||
certificates=dict(required=False, type='list'),
|
||||
sshpubkey=dict(required=False),
|
||||
ipaddress=dict(required=False),
|
||||
random=dict(default=False, type='bool'),
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
@@ -329,7 +294,7 @@ def main():
|
||||
state = module.params.get('state')
|
||||
|
||||
try:
|
||||
os.environ['KRB5CCNAME']=ccache
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
|
||||
cfg = dict(
|
||||
context='ansible_module',
|
||||
@@ -342,24 +307,24 @@ def main():
|
||||
api.finalize()
|
||||
api.Backend.rpcclient.connect()
|
||||
|
||||
changed = False
|
||||
try:
|
||||
result = api.Command.host_show(fqdn, all=True)
|
||||
host = result['result']
|
||||
except errors.NotFound:
|
||||
host = None
|
||||
|
||||
if state == 'present' or state == 'disabled':
|
||||
changed = ensure_host_present(module, api, host)
|
||||
if state in ['present', 'disabled']:
|
||||
ensure_host_present(module, api, host)
|
||||
elif state == 'absent':
|
||||
changed = ensure_host_absent(module, api, host)
|
||||
ensure_host_absent(module, api, host)
|
||||
|
||||
except Exception as e:
|
||||
module.fail_json(msg="ipaclient_get_otp module failed : %s" % str(e))
|
||||
finally:
|
||||
run([paths.KDESTROY], raiseonerr=False, env=os.environ)
|
||||
|
||||
module.exit_json(changed=changed, host=host)
|
||||
module.exit_json(changed=False, host=host)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -35,24 +35,21 @@ short description: Configure ipa.conf
|
||||
description:
|
||||
Configure ipa.conf
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: false
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: false
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
basedn:
|
||||
description: The basedn of the detected IPA server.
|
||||
returned: always
|
||||
type: string
|
||||
sample: dc=example,dc=com
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -71,22 +68,22 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
paths, sysrestore, configure_ipa_conf
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=True, default=None),
|
||||
servers=dict(required=True, type='list', default=None),
|
||||
realm=dict(required=True, default=None),
|
||||
hostname=dict(required=True, default=None),
|
||||
basedn=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -102,5 +99,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -31,56 +31,58 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_join
|
||||
short description: Join a machine to an IPA realm and get a keytab for the host service principal
|
||||
short description:
|
||||
Join a machine to an IPA realm and get a keytab for the host service
|
||||
principal
|
||||
description:
|
||||
Join a machine to an IPA realm and get a keytab for the host service principal
|
||||
Join a machine to an IPA realm and get a keytab for the host service
|
||||
principal
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: true
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: true
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
kdc:
|
||||
description: The name or address of the host running the KDC.
|
||||
required: true
|
||||
description: The name or address of the host running the KDC
|
||||
required: no
|
||||
basedn:
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com).
|
||||
required: true
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
principal:
|
||||
description: The authorized kerberos principal used to join the IPA realm.
|
||||
required: false
|
||||
description:
|
||||
User Principal allowed to promote replicas and join IPA realm
|
||||
required: yes
|
||||
password:
|
||||
description: The password to use if not using Kerberos to authenticate.
|
||||
required: false
|
||||
description: Admin user kerberos password
|
||||
required: yes
|
||||
keytab:
|
||||
description: The path to a backed-up host keytab from previous enrollment.
|
||||
required: false
|
||||
description: Path to backed up keytab from previous enrollment
|
||||
required: yes
|
||||
admin_keytab:
|
||||
description: The path to a local admin keytab
|
||||
required: yes
|
||||
ca_cert_file:
|
||||
description: A CA certificate to use. Do not acquire the IPA CA certificate via automated means.
|
||||
required: false
|
||||
description:
|
||||
A CA certificate to use. Do not acquire the IPA CA certificate via
|
||||
automated means
|
||||
required: yes
|
||||
force_join:
|
||||
description: Force enrolling the host even if host entry exists.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Force client enrollment even if already enrolled
|
||||
required: yes
|
||||
kinit_attempts:
|
||||
description: Repeat the request for host Kerberos ticket X times.
|
||||
required: false
|
||||
type: int
|
||||
default: 5
|
||||
description: Repeat the request for host Kerberos ticket X times
|
||||
required: yes
|
||||
debug:
|
||||
description: Enable debug mode.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Turn on extra debugging
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -124,26 +126,32 @@ import os
|
||||
import tempfile
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
SECURE_PATH, sysrestore, paths, options, configure_krb5_conf,
|
||||
realm_to_suffix, kinit_keytab, GSSError, kinit_password, NUM_VERSION,
|
||||
get_ca_cert, get_ca_certs, errors, run
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
kdc=dict(required=True),
|
||||
basedn=dict(required=True),
|
||||
basedn=dict(required=True),
|
||||
principal=dict(required=False),
|
||||
password=dict(required=False, no_log=True),
|
||||
keytab=dict(required=False),
|
||||
admin_keytab=dict(required=False),
|
||||
ca_cert_file=dict(required=False),
|
||||
force_join=dict(required=False, type='bool'),
|
||||
kinit_attempts=dict(required=False, type='int', default=5),
|
||||
debug=dict(required=False, type='bool'),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -157,14 +165,17 @@ def main():
|
||||
principal = module.params.get('principal')
|
||||
password = module.params.get('password')
|
||||
keytab = module.params.get('keytab')
|
||||
admin_keytab = module.params.get('admin_keytab')
|
||||
ca_cert_file = module.params.get('ca_cert_file')
|
||||
kinit_attempts = module.params.get('kinit_attempts')
|
||||
debug = module.params.get('debug')
|
||||
|
||||
if password is not None and password != "" and \
|
||||
keytab is not None and keytab != "":
|
||||
if password is not None and keytab is not None:
|
||||
module.fail_json(msg="Password and keytab cannot be used together")
|
||||
|
||||
if password is None and admin_keytab is None:
|
||||
module.fail_json(msg="Password or admin_keytab is needed")
|
||||
|
||||
client_domain = hostname[hostname.find(".")+1:]
|
||||
nolog = tuple()
|
||||
env = {'PATH': SECURE_PATH}
|
||||
@@ -173,8 +184,7 @@ def main():
|
||||
sssd = True
|
||||
|
||||
options.ca_cert_file = ca_cert_file
|
||||
options.unattended = True
|
||||
options.principal = principal if principal != "" else None
|
||||
options.principal = principal
|
||||
options.force = False
|
||||
options.password = password
|
||||
|
||||
@@ -207,15 +217,32 @@ def main():
|
||||
env['XMLRPC_TRACE_CURL'] = 'yes'
|
||||
if force_join:
|
||||
join_args.append("-f")
|
||||
if principal:
|
||||
if principal is not None:
|
||||
if principal.find('@') == -1:
|
||||
principal = '%s@%s' % (principal, realm)
|
||||
try:
|
||||
kinit_password(principal, password, ccache_name,
|
||||
config=krb_name)
|
||||
except RuntimeError as e:
|
||||
module.fail_json(
|
||||
msg="Kerberos authentication failed: {}".format(e))
|
||||
if admin_keytab:
|
||||
join_args.append("-f")
|
||||
if not os.path.exists(admin_keytab):
|
||||
module.fail_json(
|
||||
msg="Keytab file could not be found: %s" %
|
||||
admin_keytab)
|
||||
try:
|
||||
kinit_keytab(principal,
|
||||
admin_keytab,
|
||||
ccache_name,
|
||||
config=krb_name,
|
||||
attempts=kinit_attempts)
|
||||
except GSSError as e:
|
||||
module.fail_json(
|
||||
msg="Kerberos authentication failed: %s" % str(e))
|
||||
else:
|
||||
try:
|
||||
kinit_password(principal, password, ccache_name,
|
||||
config=krb_name)
|
||||
except RuntimeError as e:
|
||||
module.fail_json(
|
||||
msg="Kerberos authentication failed: {}".format(e))
|
||||
|
||||
elif keytab:
|
||||
join_args.append("-f")
|
||||
if os.path.exists(keytab):
|
||||
@@ -271,7 +298,8 @@ def main():
|
||||
|
||||
# Fail for missing krb5.keytab on already joined host
|
||||
if already_joined and not os.path.exists(paths.KRB5_KEYTAB):
|
||||
module.fail_json(msg="krb5.keytab missing! Retry with ipaclient_force_join=yes to generate a new one.")
|
||||
module.fail_json(msg="krb5.keytab missing! Retry with "
|
||||
"ipaclient_force_join=yes to generate a new one.")
|
||||
|
||||
if principal:
|
||||
run([paths.KDESTROY], raiseonerr=False, env=env)
|
||||
@@ -310,5 +338,6 @@ def main():
|
||||
module.exit_json(changed=changed,
|
||||
already_joined=already_joined)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -36,8 +36,8 @@ description:
|
||||
Backup and set hostname
|
||||
options:
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -52,18 +52,18 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
sysrestore, paths, tasks
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
hostname=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -77,5 +77,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -36,12 +36,14 @@ description:
|
||||
Setup automount for IPA client
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
sssd:
|
||||
description: The installer sssd setting
|
||||
required: yes
|
||||
automount_location:
|
||||
description: Automount location
|
||||
required: false
|
||||
description: The automount location
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -55,22 +57,24 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
options, configure_automount
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
sssd=dict(required=False, type='bool', default='yes'),
|
||||
automount_location=dict(required=False, default=None),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
#os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
# os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
|
||||
module._ansible_debug = True
|
||||
options.servers = module.params.get('servers')
|
||||
@@ -84,5 +88,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -36,11 +36,13 @@ description:
|
||||
Setup firefox for IPA client
|
||||
options:
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: true
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
firefox_dir:
|
||||
description: Specify directory where Firefox is installed (for example: '/usr/lib/firefox')
|
||||
required: false
|
||||
description:
|
||||
Specify directory where Firefox is installed (for example
|
||||
'/usr/lib/firefox')
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -57,15 +59,18 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
sysrestore, paths, options, configure_firefox
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=True),
|
||||
firefox_dir=dict(required=False),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -78,5 +83,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -35,12 +35,33 @@ short description: Setup krb5 for IPA client
|
||||
description:
|
||||
Setup krb5 for IPA client
|
||||
options:
|
||||
server:
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: yes
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
kdc:
|
||||
description: The name or address of the host running the KDC
|
||||
required: yes
|
||||
dnsok:
|
||||
description: The installer dnsok setting
|
||||
required: yes
|
||||
client_domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
sssd:
|
||||
description: The installer sssd setting
|
||||
required: yes
|
||||
force:
|
||||
description: Installer force parameter
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -58,14 +79,15 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
sysrestore, paths, configure_krb5_conf, logger
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=False, default=None),
|
||||
servers=dict(required=False, type='list', default=None),
|
||||
realm=dict(required=False, default=None),
|
||||
@@ -75,9 +97,9 @@ def main():
|
||||
client_domain=dict(required=False, default=None),
|
||||
sssd=dict(required=False, type='bool', default=False),
|
||||
force=dict(required=False, type='bool', default=False),
|
||||
#on_master=dict(required=False, type='bool', default=False),
|
||||
# on_master=dict(required=False, type='bool', default=False),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -90,21 +112,21 @@ def main():
|
||||
client_domain = module.params.get('client_domain')
|
||||
sssd = module.params.get('sssd')
|
||||
force = module.params.get('force')
|
||||
#on_master = module.params.get('on_master')
|
||||
# on_master = module.params.get('on_master')
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
|
||||
#if options.on_master:
|
||||
# # If on master assume kerberos is already configured properly.
|
||||
# # Get the host TGT.
|
||||
# try:
|
||||
# kinit_keytab(host_principal, paths.KRB5_KEYTAB, CCACHE_FILE,
|
||||
# attempts=options.kinit_attempts)
|
||||
# os.environ['KRB5CCNAME'] = CCACHE_FILE
|
||||
# except gssapi.exceptions.GSSError as e:
|
||||
# logger.error("Failed to obtain host TGT: %s", e)
|
||||
# raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
||||
#else:
|
||||
# if options.on_master:
|
||||
# # If on master assume kerberos is already configured properly.
|
||||
# # Get the host TGT.
|
||||
# try:
|
||||
# kinit_keytab(host_principal, paths.KRB5_KEYTAB, CCACHE_FILE,
|
||||
# attempts=options.kinit_attempts)
|
||||
# os.environ['KRB5CCNAME'] = CCACHE_FILE
|
||||
# except gssapi.exceptions.GSSError as e:
|
||||
# logger.error("Failed to obtain host TGT: %s", e)
|
||||
# raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
||||
# else:
|
||||
|
||||
# Configure krb5.conf
|
||||
fstore.backup_file(paths.KRB5_CONF)
|
||||
@@ -125,5 +147,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -36,11 +36,11 @@ description:
|
||||
Setup NIS for IPA client
|
||||
options:
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: true
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
nisdomain:
|
||||
description: NIS domain name
|
||||
required: false
|
||||
description: The NIS domain name
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -54,18 +54,21 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
options, sysrestore, paths, configure_nisdomain
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
domain=dict(required=True),
|
||||
nisdomain=dict(required=False),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -75,7 +78,7 @@ def main():
|
||||
statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)
|
||||
|
||||
argspec = inspect.getargspec(configure_nisdomain)
|
||||
if not "statestore" in argspec.args:
|
||||
if "statestore" not in argspec.args:
|
||||
# NUM_VERSION < 40500:
|
||||
configure_nisdomain(options=options, domain=domain)
|
||||
else:
|
||||
@@ -84,5 +87,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -36,103 +36,82 @@ description:
|
||||
Create IPA NSS database
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: true
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: true
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
basedn:
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com).
|
||||
required: true
|
||||
description: The basedn of the IPA server (of the form dc=example,dc=com)
|
||||
required: no
|
||||
principal:
|
||||
description: The authorized kerberos principal used to join the IPA realm.
|
||||
required: false
|
||||
description:
|
||||
User Principal allowed to promote replicas and join IPA realm
|
||||
required: yes
|
||||
subject_base:
|
||||
description: The subject base, needed for certmonger
|
||||
required: true
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
ca_enabled:
|
||||
description: Whether the Certificate Authority is enabled or not.
|
||||
required: true
|
||||
type: bool
|
||||
default: no
|
||||
description: Whether the Certificate Authority is enabled or not
|
||||
required: no
|
||||
mkhomedir:
|
||||
description: Whether to create home directories for users on their first login.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Create home directories for users on their first login
|
||||
required: yes
|
||||
on_master:
|
||||
description: Whether the configuration is done on the master or not.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
dnsok:
|
||||
description: The installer dnsok setting
|
||||
required: yes
|
||||
enable_dns_updates:
|
||||
description: Configures the machine to attempt dns updates when the ip address changes.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
changes
|
||||
required: yes
|
||||
all_ip_addresses:
|
||||
description: All routable IP addresses configured on any interface will be added to DNS
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
All routable IP addresses configured on any interface will be added
|
||||
to DNS
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: Specify IP addresses that should be added to DNS.
|
||||
required: false
|
||||
type: list
|
||||
default: None
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
request_cert:
|
||||
description: request certificate for the machine
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Request certificate for the machine
|
||||
required: yes
|
||||
preserve_sssd:
|
||||
description: Preserve old SSSD configuration if possible
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
no_ssh:
|
||||
description: Do not configure OpenSSH client
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
no_sshd:
|
||||
description: Do not configure OpenSSH server
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
no_sudo:
|
||||
description: Do not configure SSSD as data source for sudo
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
fixed_primary:
|
||||
description: Configure sssd to use fixed server as primary IPA server
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
permit:
|
||||
description: Disable access rules by default, permit all access.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Disable access rules by default, permit all access
|
||||
required: yes
|
||||
no_krb5_offline_passwords:
|
||||
description: Configure SSSD not to store user password when the server is offline
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
Configure SSSD not to store user password when the server is offline
|
||||
required: yes
|
||||
no_dns_sshfp:
|
||||
description: Do not automatically create DNS SSHFP records
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -155,13 +134,22 @@ RETURN = '''
|
||||
|
||||
import os
|
||||
import time
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
options, sysrestore, paths, ansible_module_get_parsed_ip_addresses,
|
||||
api, errors, create_ipa_nssdb, ipautil, ScriptError, CLIENT_INSTALL_ERROR,
|
||||
get_certs_from_ldap, DN, certstore, x509, logger, certdb,
|
||||
CalledProcessError, tasks, client_dns, configure_certmonger, services,
|
||||
update_ssh_keys, save_state, configure_ldap_conf, configure_nslcd_conf,
|
||||
nosssd_files, configure_openldap_conf, hardcode_ldap_server
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
@@ -172,6 +160,7 @@ def main():
|
||||
ca_enabled=dict(required=True, type='bool'),
|
||||
mkhomedir=dict(required=False, type='bool'),
|
||||
on_master=dict(required=False, type='bool'),
|
||||
dnsok=dict(required=False, type='bool', default=False),
|
||||
|
||||
enable_dns_updates=dict(required=False, type='bool'),
|
||||
all_ip_addresses=dict(required=False, type='bool', default=False),
|
||||
@@ -186,7 +175,7 @@ def main():
|
||||
no_krb5_offline_passwords=dict(required=False, type='bool'),
|
||||
no_dns_sshfp=dict(required=False, type='bool', default=False),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -200,6 +189,7 @@ def main():
|
||||
ca_enabled = module.params.get('ca_enabled')
|
||||
options.mkhomedir = module.params.get('mkhomedir')
|
||||
options.on_master = module.params.get('on_master')
|
||||
dnsok = module.params.get('dnsok')
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)
|
||||
@@ -241,7 +231,7 @@ def main():
|
||||
api.Backend.rpcclient.connect()
|
||||
try:
|
||||
api.Backend.rpcclient.forward('ping')
|
||||
except errors.KerberosError as e:
|
||||
except errors.KerberosError:
|
||||
# Cannot connect to the server due to Kerberos error, trying with
|
||||
# delegate=True
|
||||
api.Backend.rpcclient.disconnect()
|
||||
@@ -262,8 +252,8 @@ def main():
|
||||
|
||||
# Get CA certificates from the certificate store
|
||||
try:
|
||||
ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn, cli_realm,
|
||||
ca_enabled)
|
||||
ca_certs = get_certs_from_ldap(cli_server[0], cli_basedn,
|
||||
cli_realm, ca_enabled)
|
||||
except errors.NoCertificateError:
|
||||
if ca_enabled:
|
||||
ca_subject = DN(('CN', 'Certificate Authority'), subject_base)
|
||||
@@ -271,7 +261,8 @@ def main():
|
||||
ca_subject = None
|
||||
ca_certs = certstore.make_compat_ca_certs(ca_certs, cli_realm,
|
||||
ca_subject)
|
||||
ca_certs_trust = [(c, n, certstore.key_policy_to_trust_flags(t, True, u))
|
||||
ca_certs_trust = [(c, n,
|
||||
certstore.key_policy_to_trust_flags(t, True, u))
|
||||
for (c, n, t, u) in ca_certs]
|
||||
|
||||
if hasattr(paths, "KDC_CA_BUNDLE_PEM"):
|
||||
@@ -293,12 +284,13 @@ def main():
|
||||
for cert, nickname, trust_flags in ca_certs_trust:
|
||||
try:
|
||||
ipa_db.add_cert(cert, nickname, trust_flags)
|
||||
except CalledProcessError as e:
|
||||
except CalledProcessError:
|
||||
raise ScriptError(
|
||||
"Failed to add %s to the IPA NSS database." % nickname,
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
# Add the CA certificates to the platform-dependant systemwide CA store
|
||||
# Add the CA certificates to the platform-dependant systemwide CA
|
||||
# store
|
||||
tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)
|
||||
|
||||
if not options.on_master:
|
||||
@@ -351,7 +343,8 @@ def main():
|
||||
except Exception:
|
||||
if not options.sssd:
|
||||
logger.warning(
|
||||
"Failed to configure automatic startup of the %s daemon",
|
||||
"Failed to configure automatic startup of the %s "
|
||||
"daemon",
|
||||
nscd.service_name)
|
||||
logger.info(
|
||||
"Caching of users/groups will not be "
|
||||
@@ -424,15 +417,15 @@ def main():
|
||||
sssd.enable()
|
||||
except CalledProcessError as e:
|
||||
logger.warning(
|
||||
"Failed to enable automatic startup of the SSSD daemon: "
|
||||
"%s", e)
|
||||
"Failed to enable automatic startup of the SSSD "
|
||||
"daemon: %s", e)
|
||||
|
||||
if not options.sssd:
|
||||
tasks.modify_pam_to_use_krb5(statestore)
|
||||
logger.info("Kerberos 5 enabled")
|
||||
|
||||
# Update non-SSSD LDAP configuration after authconfig calls as it would
|
||||
# change its configuration otherways
|
||||
# Update non-SSSD LDAP configuration after authconfig calls as it
|
||||
# would change its configuration otherways
|
||||
if not options.sssd:
|
||||
for configurer in [configure_ldap_conf, configure_nslcd_conf]:
|
||||
(retcode, conf, filenames) = configurer(
|
||||
@@ -467,11 +460,15 @@ def main():
|
||||
# It can sometimes take a few seconds to connect to the remote
|
||||
# provider.
|
||||
# Particulary, SSSD might take longer than 6-8 seconds.
|
||||
if hasattr(paths, "GETENT"):
|
||||
getent_cmd = paths.GETENT
|
||||
else:
|
||||
getent_cmd = '/usr/bin/getent'
|
||||
while n < 10 and not found:
|
||||
try:
|
||||
ipautil.run([paths.GETENT, "passwd", user])
|
||||
ipautil.run([getent_cmd, "passwd", user])
|
||||
found = True
|
||||
except Exception as e:
|
||||
except Exception:
|
||||
time.sleep(1)
|
||||
n = n + 1
|
||||
|
||||
@@ -500,5 +497,6 @@ def main():
|
||||
module.exit_json(changed=True,
|
||||
ca_enabled_ra=ca_enabled)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -35,44 +35,24 @@ short description: Setup NTP for IPA client
|
||||
description:
|
||||
Setup NTP for IPA client
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: false
|
||||
type: list
|
||||
default: []
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: false
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: false
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: false
|
||||
ca_cert_file:
|
||||
description: A CA certificate to use.
|
||||
required: false
|
||||
on_master:
|
||||
description: IPA client installation on IPA server
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
default: no
|
||||
ntp_servers:
|
||||
description: List of NTP servers to use
|
||||
required: false
|
||||
type: list
|
||||
default: []
|
||||
description: ntp servers to use
|
||||
required: yes
|
||||
ntp_pool:
|
||||
description: ntp server pool to use
|
||||
required: false
|
||||
required: yes
|
||||
no_ntp:
|
||||
description: Do not sync time and do not detect time servers
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
default: no
|
||||
|
||||
description: Do not configure ntp
|
||||
required: yes
|
||||
on_master:
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -83,33 +63,36 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import socket
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
options, sysrestore, paths, sync_time, logger, ipadiscovery,
|
||||
timeconf
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
ntp_servers=dict(required=False, type='list', default=None),
|
||||
ntp_pool=dict(required=False, default=None),
|
||||
no_ntp=dict(required=False, type='bool', default=False),
|
||||
#force_ntpd=dict(required=False, type='bool', default=False),
|
||||
# force_ntpd=dict(required=False, type='bool', default=False),
|
||||
on_master=dict(required=False, type='bool', default=False),
|
||||
### additional ###
|
||||
# additional
|
||||
servers=dict(required=False, type='list', default=None),
|
||||
domain=dict(required=False, default=None),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
#module._ansible_debug = True
|
||||
# module._ansible_debug = True
|
||||
options.ntp_servers = module.params.get('ntp_servers')
|
||||
options.ntp_pool = module.params.get('ntp_pool')
|
||||
options.no_ntp = module.params.get('no_ntp')
|
||||
#options.force_ntpd = module.params.get('force_ntpd')
|
||||
# options.force_ntpd = module.params.get('force_ntpd')
|
||||
options.on_master = module.params.get('on_master')
|
||||
cli_server = module.params.get('servers')
|
||||
cli_domain = module.params.get('domain')
|
||||
@@ -124,20 +107,27 @@ def main():
|
||||
if sync_time is not None:
|
||||
if options.conf_ntp:
|
||||
# Attempt to configure and sync time with NTP server (chrony).
|
||||
synced_ntp = sync_time(options, fstore, statestore)
|
||||
argspec = inspect.getargspec(sync_time)
|
||||
if "options" not in argspec.args:
|
||||
synced_ntp = sync_time(options.ntp_servers, options.ntp_pool,
|
||||
fstore, statestore)
|
||||
else:
|
||||
synced_ntp = sync_time(options, fstore, statestore)
|
||||
elif options.on_master:
|
||||
# If we're on master skipping the time sync here because it was done
|
||||
# in ipa-server-install
|
||||
logger.info("Skipping attempt to configure and synchronize time with"
|
||||
" chrony server as it has been already done on master.")
|
||||
# If we're on master skipping the time sync here because it was
|
||||
# done in ipa-server-install
|
||||
logger.info(
|
||||
"Skipping attempt to configure and synchronize time with"
|
||||
" chrony server as it has been already done on master.")
|
||||
else:
|
||||
logger.info("Skipping chrony configuration")
|
||||
|
||||
else:
|
||||
ntp_srv_servers = [ ]
|
||||
ntp_srv_servers = []
|
||||
if not options.on_master and options.conf_ntp:
|
||||
# Attempt to sync time with IPA server.
|
||||
# If we're skipping NTP configuration, we also skip the time sync here.
|
||||
# If we're skipping NTP configuration, we also skip the time sync
|
||||
# here.
|
||||
# We assume that NTP servers are discoverable through SRV records
|
||||
# in the DNS.
|
||||
# If that fails, we try to sync directly with IPA server,
|
||||
@@ -159,7 +149,8 @@ def main():
|
||||
break
|
||||
|
||||
if not synced_ntp and not options.ntp_servers:
|
||||
synced_ntp = timeconf.synconce_ntp(cli_server[0], options.debug)
|
||||
synced_ntp = timeconf.synconce_ntp(cli_server[0],
|
||||
options.debug)
|
||||
if not synced_ntp:
|
||||
module.warn(
|
||||
"Unable to sync time with NTP "
|
||||
@@ -171,5 +162,6 @@ def main():
|
||||
# Done
|
||||
module.exit_json(changed=synced_ntp)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -36,29 +36,20 @@ description:
|
||||
Configure ssh and sshd for IPA client
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
ssh:
|
||||
description: Configure OpenSSH client
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
trust_sshfp:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
no_ssh:
|
||||
description: Do not configure OpenSSH client
|
||||
required: yes
|
||||
ssh_trust_dns:
|
||||
description: Configure OpenSSH client to trust DNS SSHFP records
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
sshd:
|
||||
description: Configure OpenSSH server
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
no_sshd:
|
||||
description: Do not configure OpenSSH server
|
||||
required: yes
|
||||
sssd:
|
||||
description: Configure SSSD server
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: The installer sssd setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -75,21 +66,22 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
options, sysrestore, paths, configure_ssh_config, configure_sshd_config
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
no_ssh=dict(required=False, type='bool', default='no'),
|
||||
ssh_trust_dns=dict(required=False, type='bool', default='no'),
|
||||
no_sshd=dict(required=False, type='bool', default='no'),
|
||||
sssd=dict(required=False, type='bool', default='no'),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -104,7 +96,7 @@ def main():
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
|
||||
#os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
# os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
|
||||
changed = False
|
||||
if options.conf_ssh:
|
||||
@@ -117,5 +109,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -36,68 +36,52 @@ description:
|
||||
Setup sssd for IPA client
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: true
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: true
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
on_master:
|
||||
description: Whether the configuration is done on the master or not.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
no_ssh:
|
||||
description: Do not configure OpenSSH client
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
no_sshd:
|
||||
description: Do not configure OpenSSH server
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
no_sudo:
|
||||
description: Do not configure SSSD as data source for sudo
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
all_ip_addresses:
|
||||
description: All routable IP addresses configured on any interface will be added to DNS.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
All routable IP addresses configured on any interface will be added
|
||||
to DNS
|
||||
required: yes
|
||||
fixed_primary:
|
||||
description: Whether to use fixed server as primary IPA server.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Configure sssd to use fixed server as primary IPA server
|
||||
required: yes
|
||||
permit:
|
||||
description: Disable access rules by default, permit all access.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Disable access rules by default, permit all access
|
||||
required: yes
|
||||
enable_dns_updates:
|
||||
description: Configures the machine to attempt dns updates when the ip address changes.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
changes
|
||||
required: yes
|
||||
preserve_sssd:
|
||||
description: Preserve old SSSD configuration if possible.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Preserve old SSSD configuration if possible
|
||||
required: yes
|
||||
no_krb5_offline_passwords:
|
||||
description: Whether user passwords are stored when the server is offline.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
Configure SSSD not to store user password when the server is offline
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -116,11 +100,14 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
options, sysrestore, paths, configure_sssd_conf, logger
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
@@ -137,10 +124,10 @@ def main():
|
||||
preserve_sssd=dict(required=False, type='bool'),
|
||||
no_krb5_offline_passwords=dict(required=False, type='bool'),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
#ansible_log = AnsibleModuleLog(module, logger)
|
||||
#options.set_logger(ansible_log)
|
||||
# ansible_log = AnsibleModuleLog(module, logger)
|
||||
# options.set_logger(ansible_log)
|
||||
|
||||
module._ansible_debug = True
|
||||
cli_server = module.params.get('servers')
|
||||
@@ -176,5 +163,6 @@ def main():
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -35,84 +35,70 @@ short description: Tries to discover IPA server
|
||||
description:
|
||||
Tries to discover IPA server using DNS or host name
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: false
|
||||
type: list
|
||||
default: []
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: false
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: yes
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: false
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: yes
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: false
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ntp_servers:
|
||||
description: List of NTP servers to use
|
||||
required: false
|
||||
type: list
|
||||
default: []
|
||||
description: ntp servers to use
|
||||
required: yes
|
||||
ntp_pool:
|
||||
description: ntp server pool to use
|
||||
required: false
|
||||
required: yes
|
||||
no_ntp:
|
||||
description: Do not sync time and do not detect time servers
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Do not configure ntp
|
||||
required: yes
|
||||
force_ntpd:
|
||||
description: Stop and disable any time&date synchronization services besides ntpd. Deprecated since 4.7.
|
||||
requried: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
Stop and disable any time&date synchronization services besides ntpd
|
||||
Deprecated since 4.7
|
||||
required: yes
|
||||
nisdomain:
|
||||
description: NIS domain name
|
||||
required: false
|
||||
description: The NIS domain name
|
||||
required: yes
|
||||
no_nisdomain:
|
||||
description: Do not configure NIS domain name
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
kinit_attempts:
|
||||
description: Repeat the request for host Kerberos ticket X times.
|
||||
required: false
|
||||
type: int
|
||||
default: 5
|
||||
description: Repeat the request for host Kerberos ticket X times
|
||||
required: yes
|
||||
ca_cert_files:
|
||||
description: CA certificates to use.
|
||||
required: false
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
configure_firefox:
|
||||
description: Configure Firefox to use IPA domain credentials
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
required: yes
|
||||
firefox_dir:
|
||||
description: Specify directory where Firefox is installed (for example: '/usr/lib/firefox')
|
||||
required: false
|
||||
description:
|
||||
Specify directory where Firefox is installed (for example
|
||||
'/usr/lib/firefox')
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: All routable IP addresses configured on any interface will be added to DNS.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
all_ip_addresses:
|
||||
description: All routable IP addresses configured on any interface will be added to DNS.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
All routable IP addresses configured on any interface will be added
|
||||
to DNS
|
||||
required: yes
|
||||
on_master:
|
||||
description: IPA client installation on IPA server
|
||||
required: false
|
||||
default: false
|
||||
type: bool
|
||||
default: no
|
||||
description: Whether the configuration is done on the master or not
|
||||
required: yes
|
||||
enable_dns_updates:
|
||||
description: Configures the machine to attempt dns updates when the ip address changes.
|
||||
required: false
|
||||
type: bool
|
||||
default: no
|
||||
description:
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
changes
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -194,7 +180,9 @@ ntp_servers:
|
||||
type: list
|
||||
sample: ["ntp.example.com"]
|
||||
ipa_python_version:
|
||||
description: The IPA python version as a number: <major version>*10000+<minor version>*100+<release>
|
||||
description:
|
||||
- The IPA python version as a number:
|
||||
- <major version>*10000+<minor version>*100+<release>
|
||||
returned: always
|
||||
type: int
|
||||
sample: 040400
|
||||
@@ -202,10 +190,23 @@ ipa_python_version:
|
||||
|
||||
import os
|
||||
import socket
|
||||
import inspect
|
||||
|
||||
try:
|
||||
from six.moves.configparser import RawConfigParser
|
||||
except ImportError:
|
||||
from ConfigParser import RawConfigParser
|
||||
|
||||
from six.moves.configparser import RawConfigParser
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
paths, sysrestore, options, CheckedIPAddress, validate_domain_name,
|
||||
logger, x509, normalize_hostname, installer, version, ScriptError,
|
||||
CLIENT_INSTALL_ERROR, tasks, check_ldap_conf, timeconf, constants,
|
||||
validate_hostname, nssldap_exists, gssapi, remove_file,
|
||||
check_ip_addresses, ipadiscovery, print_port_conf_info,
|
||||
IPA_PYTHON_VERSION
|
||||
)
|
||||
|
||||
|
||||
def get_cert_path(cert_path):
|
||||
"""
|
||||
@@ -223,6 +224,7 @@ def get_cert_path(cert_path):
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def is_client_configured():
|
||||
"""
|
||||
Check if ipa client is configured.
|
||||
@@ -237,6 +239,7 @@ def is_client_configured():
|
||||
os.path.isfile(os.path.join(paths.IPA_CLIENT_SYSRESTORE,
|
||||
sysrestore.SYSRESTORE_STATEFILE)))
|
||||
|
||||
|
||||
def get_ipa_conf():
|
||||
"""
|
||||
Return IPA configuration read from /etc/ipa/default.conf
|
||||
@@ -257,10 +260,11 @@ def get_ipa_conf():
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
domain=dict(required=False, default=None),
|
||||
servers=dict(required=False, type='list', default=None),
|
||||
realm=dict(required=False, default=None),
|
||||
@@ -278,13 +282,14 @@ def main():
|
||||
ip_addresses=dict(required=False, type='list', default=None),
|
||||
all_ip_addresses=dict(required=False, type='bool', default=False),
|
||||
on_master=dict(required=False, type='bool', default=False),
|
||||
### sssd ###
|
||||
enable_dns_updates=dict(required=False, type='bool', default=False),
|
||||
# sssd
|
||||
enable_dns_updates=dict(required=False, type='bool',
|
||||
default=False),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
#module._ansible_debug = True
|
||||
# module._ansible_debug = True
|
||||
options.domain_name = module.params.get('domain')
|
||||
options.servers = module.params.get('servers')
|
||||
options.realm_name = module.params.get('realm')
|
||||
@@ -308,12 +313,13 @@ def main():
|
||||
# servers
|
||||
if options.domain_name is None and options.servers is not None:
|
||||
if len(options.servers) > 0:
|
||||
options.domain_name = options.servers[0][options.servers[0].find(".")+1:]
|
||||
options.domain_name = options.servers[0][
|
||||
options.servers[0].find(".")+1:]
|
||||
|
||||
try:
|
||||
self = options
|
||||
|
||||
### HostNameInstallInterface ###
|
||||
# HostNameInstallInterface
|
||||
|
||||
if options.ip_addresses is not None:
|
||||
for value in options.ip_addresses:
|
||||
@@ -323,7 +329,7 @@ def main():
|
||||
raise ValueError("invalid IP address {0}: {1}".format(
|
||||
value, e))
|
||||
|
||||
### ServiceInstallInterface ###
|
||||
# ServiceInstallInterface
|
||||
|
||||
if options.domain_name:
|
||||
validate_domain_name(options.domain_name)
|
||||
@@ -334,12 +340,12 @@ def main():
|
||||
# NUM_VERSION >= 40690:
|
||||
validate_domain_name(options.realm_name, entity="realm")
|
||||
|
||||
### ClientInstallInterface ###
|
||||
# ClientInstallInterface
|
||||
|
||||
if options.kinit_attempts < 1:
|
||||
raise ValueError("expects an integer greater than 0.")
|
||||
|
||||
### ClientInstallInterface.__init__ ###
|
||||
# ClientInstallInterface.__init__
|
||||
|
||||
if self.servers and not self.domain_name:
|
||||
raise RuntimeError(
|
||||
@@ -364,18 +370,18 @@ def main():
|
||||
if self.enable_dns_updates:
|
||||
raise RuntimeError(
|
||||
"--ip-address cannot be used together with"
|
||||
" --enable-dns-updates")
|
||||
" --enable-dns-updates")
|
||||
|
||||
if self.all_ip_addresses:
|
||||
raise RuntimeError(
|
||||
"--ip-address cannot be used together with"
|
||||
"--all-ip-addresses")
|
||||
|
||||
### SSSDInstallInterface ###
|
||||
# SSSDInstallInterface
|
||||
|
||||
self.no_sssd = False
|
||||
|
||||
### ClientInstall ###
|
||||
# ClientInstall
|
||||
|
||||
if options.ca_cert_files is not None:
|
||||
for value in options.ca_cert_files:
|
||||
@@ -388,18 +394,20 @@ def main():
|
||||
if not os.path.isfile(value):
|
||||
raise ValueError("'%s' is not a file" % value)
|
||||
if not os.path.isabs(value):
|
||||
raise ValueError("'%s' is not an absolute file path" % value)
|
||||
raise ValueError("'%s' is not an absolute file path" %
|
||||
value)
|
||||
|
||||
try:
|
||||
x509.load_certificate_from_file(value)
|
||||
except Exception:
|
||||
raise ValueError("'%s' is not a valid certificate file" % value)
|
||||
raise ValueError("'%s' is not a valid certificate file" %
|
||||
value)
|
||||
|
||||
#self.prompt_password = self.interactive
|
||||
# self.prompt_password = self.interactive
|
||||
|
||||
self.no_ac = False
|
||||
|
||||
### ClientInstall.__init__ ###
|
||||
# ClientInstall.__init__
|
||||
|
||||
if self.firefox_dir and not self.configure_firefox:
|
||||
raise RuntimeError(
|
||||
@@ -409,41 +417,41 @@ def main():
|
||||
except (RuntimeError, ValueError) as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
### ipaclient.install.client.init ###
|
||||
# ipaclient.install.client.init
|
||||
|
||||
# root_logger
|
||||
options.debug = False
|
||||
options.unattended = not installer.interactive
|
||||
if options.domain_name:
|
||||
options.domain = normalize_hostname(installer.domain_name)
|
||||
else:
|
||||
options.domain = None
|
||||
options.server = options.servers
|
||||
options.realm = options.realm_name
|
||||
#installer.primary = installer.fixed_primary
|
||||
#if installer.principal:
|
||||
# installer.password = installer.admin_password
|
||||
#else:
|
||||
# installer.password = installer.host_password
|
||||
# installer.primary = installer.fixed_primary
|
||||
# if installer.principal:
|
||||
# installer.password = installer.admin_password
|
||||
# else:
|
||||
# installer.password = installer.host_password
|
||||
installer.hostname = installer.host_name
|
||||
options.conf_ntp = not options.no_ntp
|
||||
#installer.trust_sshfp = installer.ssh_trust_dns
|
||||
#installer.conf_ssh = not installer.no_ssh
|
||||
#installer.conf_sshd = not installer.no_sshd
|
||||
#installer.conf_sudo = not installer.no_sudo
|
||||
#installer.create_sshfp = not installer.no_dns_sshfp
|
||||
# installer.trust_sshfp = installer.ssh_trust_dns
|
||||
# installer.conf_ssh = not installer.no_ssh
|
||||
# installer.conf_sshd = not installer.no_sshd
|
||||
# installer.conf_sudo = not installer.no_sudo
|
||||
# installer.create_sshfp = not installer.no_dns_sshfp
|
||||
if installer.ca_cert_files:
|
||||
installer.ca_cert_file = installer.ca_cert_files[-1]
|
||||
else:
|
||||
installer.ca_cert_file = None
|
||||
#installer.location = installer.automount_location
|
||||
# installer.location = installer.automount_location
|
||||
installer.dns_updates = installer.enable_dns_updates
|
||||
#installer.krb5_offline_passwords = not installer.no_krb5_offline_passwords
|
||||
# installer.krb5_offline_passwords = \
|
||||
# not installer.no_krb5_offline_passwords
|
||||
installer.sssd = not installer.no_sssd
|
||||
|
||||
try:
|
||||
|
||||
### client ###
|
||||
# client
|
||||
|
||||
# global variables
|
||||
hostname = None
|
||||
@@ -452,23 +460,23 @@ def main():
|
||||
dnsok = False
|
||||
cli_domain = None
|
||||
cli_server = None
|
||||
subject_base = None
|
||||
# subject_base = None
|
||||
cli_realm = None
|
||||
cli_kdc = None
|
||||
client_domain = None
|
||||
cli_basedn = None
|
||||
# end of global variables
|
||||
|
||||
### client.install_check ###
|
||||
# client.install_check
|
||||
|
||||
logger.info("This program will set up FreeIPA client.")
|
||||
logger.info("Version {}".format(version.VERSION))
|
||||
logger.info("Version %s", version.VERSION)
|
||||
logger.info("")
|
||||
|
||||
cli_domain_source = 'Unknown source'
|
||||
cli_server_source = 'Unknown source'
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
# fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
|
||||
if not os.getegid() == 0:
|
||||
raise ScriptError(
|
||||
@@ -477,14 +485,14 @@ def main():
|
||||
|
||||
tasks.check_selinux_status()
|
||||
|
||||
#if is_ipa_client_installed(fstore, on_master=options.on_master):
|
||||
# logger.error("IPA client is already configured on this system.")
|
||||
# logger.info(
|
||||
# "If you want to reinstall the IPA client, uninstall it first "
|
||||
# "using 'ipa-client-install --uninstall'.")
|
||||
# raise ScriptError(
|
||||
# "IPA client is already configured on this system.",
|
||||
# rval=CLIENT_ALREADY_CONFIGURED)
|
||||
# if is_ipa_client_installed(fstore, on_master=options.on_master):
|
||||
# logger.error("IPA client is already configured on this system.")
|
||||
# logger.info(
|
||||
# "If you want to reinstall the IPA client, uninstall it first "
|
||||
# "using 'ipa-client-install --uninstall'.")
|
||||
# raise ScriptError(
|
||||
# "IPA client is already configured on this system.",
|
||||
# rval=CLIENT_ALREADY_CONFIGURED)
|
||||
|
||||
if check_ldap_conf is not None:
|
||||
check_ldap_conf()
|
||||
@@ -493,24 +501,25 @@ def main():
|
||||
try:
|
||||
timeconf.check_timedate_services()
|
||||
except timeconf.NTPConflictingService as e:
|
||||
logger.info("WARNING: conflicting time&date synchronization service '{}'"
|
||||
" will be disabled".format(e.conflicting_service))
|
||||
logger.info("in favor of chronyd")
|
||||
logger.info(
|
||||
"WARNING: conflicting time&date synchronization service "
|
||||
"'%s' will be disabled in favor of chronyd",
|
||||
e.conflicting_service)
|
||||
logger.info("")
|
||||
except timeconf.NTPConfigurationError:
|
||||
pass
|
||||
|
||||
# password, principal and keytab are checked in tasks/install.yml
|
||||
#if options.unattended and (
|
||||
# options.password is None and
|
||||
# options.principal is None and
|
||||
# options.keytab is None and
|
||||
# options.prompt_password is False and
|
||||
# not options.on_master
|
||||
#):
|
||||
# raise ScriptError(
|
||||
# "One of password / principal / keytab is required.",
|
||||
# rval=CLIENT_INSTALL_ERROR)
|
||||
# if options.unattended and (
|
||||
# options.password is None and
|
||||
# options.principal is None and
|
||||
# options.keytab is None and
|
||||
# options.prompt_password is False and
|
||||
# not options.on_master
|
||||
# ):
|
||||
# raise ScriptError(
|
||||
# "One of password / principal / keytab is required.",
|
||||
# rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
if options.hostname:
|
||||
hostname = options.hostname
|
||||
@@ -541,17 +550,17 @@ def main():
|
||||
# --no-sssd is not supported any more for rhel-based distros
|
||||
if not tasks.is_nosssd_supported() and not options.sssd:
|
||||
raise ScriptError(
|
||||
"Option '--no-sssd' is incompatible with the 'authselect' tool "
|
||||
"provided by this distribution for configuring system "
|
||||
"authentication resources",
|
||||
"Option '--no-sssd' is incompatible with the 'authselect' "
|
||||
"tool provided by this distribution for configuring "
|
||||
"system authentication resources",
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
# --noac is not supported any more for rhel-based distros
|
||||
if not tasks.is_nosssd_supported() and options.no_ac:
|
||||
raise ScriptError(
|
||||
"Option '--noac' is incompatible with the 'authselect' tool "
|
||||
"provided by this distribution for configuring system "
|
||||
"authentication resources",
|
||||
"Option '--noac' is incompatible with the 'authselect' "
|
||||
"tool provided by this distribution for configuring "
|
||||
"system authentication resources",
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
# when installing with '--no-sssd' option, check whether nss-ldap is
|
||||
@@ -563,6 +572,7 @@ def main():
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
(nssldap_installed, nosssd_files) = nssldap_exists()
|
||||
(nssldap_installed, __temp) = nssldap_exists()
|
||||
if not nssldap_installed:
|
||||
raise ScriptError(
|
||||
"One of these packages must be installed: nss_ldap or "
|
||||
@@ -570,15 +580,15 @@ def main():
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
# principal and keytab are checked in tasks/install.yml
|
||||
#if options.keytab and options.principal:
|
||||
# raise ScriptError(
|
||||
# "Options 'principal' and 'keytab' cannot be used together.",
|
||||
# rval=CLIENT_INSTALL_ERROR)
|
||||
# if options.keytab and options.principal:
|
||||
# raise ScriptError(
|
||||
# "Options 'principal' and 'keytab' cannot be used together.",
|
||||
# rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
# keytab and force_join are checked in tasks/install.yml
|
||||
#if options.keytab and options.force_join:
|
||||
# logger.warning("Option 'force-join' has no additional effect "
|
||||
# "when used with together with option 'keytab'.")
|
||||
# if options.keytab and options.force_join:
|
||||
# logger.warning("Option 'force-join' has no additional effect "
|
||||
# "when used with together with option 'keytab'.")
|
||||
|
||||
# Added with freeipa-4.7.1 >>>
|
||||
# Remove invalid keytab file
|
||||
@@ -597,7 +607,8 @@ def main():
|
||||
not options.ca_cert_file and
|
||||
get_cert_path(options.ca_cert_file) == paths.IPA_CA_CRT
|
||||
):
|
||||
logger.warning("Using existing certificate '%s'.", paths.IPA_CA_CRT)
|
||||
logger.warning("Using existing certificate '%s'.",
|
||||
paths.IPA_CA_CRT)
|
||||
|
||||
if not check_ip_addresses(options):
|
||||
raise ScriptError(
|
||||
@@ -616,9 +627,9 @@ def main():
|
||||
)
|
||||
|
||||
if options.server and ret != 0:
|
||||
# There is no point to continue with installation as server list was
|
||||
# passed as a fixed list of server and thus we cannot discover any
|
||||
# better result
|
||||
# There is no point to continue with installation as server list
|
||||
# was passed as a fixed list of server and thus we cannot discover
|
||||
# any better result
|
||||
logger.error(
|
||||
"Failed to verify that %s is an IPA Server.",
|
||||
', '.join(options.server))
|
||||
@@ -666,7 +677,8 @@ def main():
|
||||
# logger.info(
|
||||
# "DNS discovery failed to determine your DNS domain")
|
||||
# cli_domain = user_input(
|
||||
# "Provide the domain name of your IPA server (ex: example.com)",
|
||||
# "Provide the domain name of your IPA server "
|
||||
# "(ex: example.com)",
|
||||
# allow_empty=False)
|
||||
# cli_domain_source = 'Provided interactively'
|
||||
# logger.debug(
|
||||
@@ -705,7 +717,7 @@ def main():
|
||||
# ]
|
||||
# cli_server_source = 'Provided interactively'
|
||||
# logger.debug(
|
||||
# "will use interactively provided server: %s", cli_server[0])
|
||||
# "will use interactively provided server: %s", cli_server[0])
|
||||
ret = ds.search(
|
||||
domain=cli_domain,
|
||||
servers=cli_server,
|
||||
@@ -713,8 +725,8 @@ def main():
|
||||
ca_cert_path=get_cert_path(options.ca_cert_file))
|
||||
|
||||
else:
|
||||
# Only set dnsok to True if we were not passed in one or more servers
|
||||
# and if DNS discovery actually worked.
|
||||
# Only set dnsok to True if we were not passed in one or more
|
||||
# servers and if DNS discovery actually worked.
|
||||
if not options.server:
|
||||
(server, domain) = ds.check_domain(
|
||||
ds.domain, set(), "Validating DNS Discovery")
|
||||
@@ -784,22 +796,29 @@ def main():
|
||||
logger.info("Discovery was successful!")
|
||||
elif not options.unattended:
|
||||
raise ScriptError("No interactive installation")
|
||||
# if not options.server:
|
||||
# logger.warning(
|
||||
# "The failure to use DNS to find your IPA "
|
||||
# "server indicates that your resolv.conf file is not properly "
|
||||
# "configured.")
|
||||
# logger.info(
|
||||
# "Autodiscovery of servers for failover cannot work "
|
||||
# "with this configuration.")
|
||||
# logger.info(
|
||||
# "If you proceed with the installation, services "
|
||||
# "will be configured to always access the discovered server for "
|
||||
# "all operations and will not fail over to other servers in case "
|
||||
# "of failure.")
|
||||
# if not user_input(
|
||||
# "Proceed with fixed values and no DNS discovery?", False):
|
||||
# raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
||||
# if not options.server:
|
||||
# logger.warning(
|
||||
# "The failure to use DNS to find your IPA "
|
||||
# "server indicates that your resolv.conf file is not properly "
|
||||
# "configured.")
|
||||
# logger.info(
|
||||
# "Autodiscovery of servers for failover cannot work "
|
||||
# "with this configuration.")
|
||||
# logger.info(
|
||||
# "If you proceed with the installation, services "
|
||||
# "will be configured to always access the discovered server for "
|
||||
# "all operations and will not fail over to other servers in case "
|
||||
# "of failure.")
|
||||
# if not user_input(
|
||||
# "Proceed with fixed values and no DNS discovery?", False):
|
||||
# raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
# Do not ask for time source
|
||||
# if options.conf_ntp:
|
||||
# if not options.on_master and not options.unattended and not (
|
||||
# options.ntp_servers or options.ntp_pool):
|
||||
# options.ntp_servers, options.ntp_pool = \
|
||||
# timeconf.get_time_source()
|
||||
|
||||
cli_realm = ds.realm
|
||||
cli_realm_source = ds.realm_source
|
||||
@@ -807,17 +826,19 @@ def main():
|
||||
|
||||
if options.realm_name and options.realm_name != cli_realm:
|
||||
logger.error(
|
||||
"The provided realm name [%s] does not match discovered one [%s]",
|
||||
"The provided realm name [%s] does not match discovered "
|
||||
"one [%s]",
|
||||
options.realm_name, cli_realm)
|
||||
logger.debug("(%s: %s)", cli_realm, cli_realm_source)
|
||||
raise ScriptError(
|
||||
"The provided realm name [%s] does not match discovered one [%s]" % (options.realm_name, cli_realm),
|
||||
"The provided realm name [%s] does not match discovered "
|
||||
"one [%s]" % (options.realm_name, cli_realm),
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
cli_basedn = ds.basedn
|
||||
cli_basedn_source = ds.basedn_source
|
||||
logger.debug("will use discovered basedn: %s", cli_basedn)
|
||||
subject_base = DN(('O', cli_realm))
|
||||
# subject_base = DN(('O', cli_realm))
|
||||
|
||||
logger.info("Client hostname: %s", hostname)
|
||||
logger.debug("Hostname source: %s", hostname_source)
|
||||
@@ -830,6 +851,14 @@ def main():
|
||||
logger.info("BaseDN: %s", cli_basedn)
|
||||
logger.debug("BaseDN source: %s", cli_basedn_source)
|
||||
|
||||
if not options.on_master:
|
||||
if options.ntp_servers:
|
||||
for server in options.ntp_servers:
|
||||
logger.info("NTP server: %s", server)
|
||||
|
||||
if options.ntp_pool:
|
||||
logger.info("NTP pool: %s", options.ntp_pool)
|
||||
|
||||
# ipa-join would fail with IP address instead of a FQDN
|
||||
for srv in cli_server:
|
||||
try:
|
||||
@@ -850,24 +879,22 @@ def main():
|
||||
"installation may fail.")
|
||||
break
|
||||
|
||||
#logger.info()
|
||||
#if not options.unattended and not user_input(
|
||||
# "Continue to configure the system with these values?", False):
|
||||
# raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
||||
# logger.info()
|
||||
# if not options.unattended and not user_input(
|
||||
# "Continue to configure the system with these values?", False):
|
||||
# raise ScriptError(rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
except ScriptError as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
#########################################################################
|
||||
|
||||
### client._install ###
|
||||
|
||||
statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)
|
||||
# client._install
|
||||
|
||||
# May not happen in here at this time
|
||||
#if not options.on_master:
|
||||
# # Try removing old principals from the keytab
|
||||
# purge_host_keytab(cli_realm)
|
||||
# if not options.on_master:
|
||||
# # Try removing old principals from the keytab
|
||||
# purge_host_keytab(cli_realm)
|
||||
|
||||
# Check if ipa client is already configured
|
||||
if is_client_configured():
|
||||
@@ -895,8 +922,11 @@ def main():
|
||||
client_domain=client_domain,
|
||||
dnsok=dnsok,
|
||||
sssd=options.sssd,
|
||||
ntp_servers=options.ntp_servers,
|
||||
ntp_pool=options.ntp_pool,
|
||||
client_already_configured=client_already_configured,
|
||||
ipa_python_version=IPA_PYTHON_VERSION)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -31,32 +31,30 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaclient_test_keytab
|
||||
short description: Test if the krb5.keytab on the machine is valid and can be used.
|
||||
short description:
|
||||
Test if the krb5.keytab on the machine is valid and can be used.
|
||||
description:
|
||||
Test if the krb5.keytab on the machine is valid and can be used.
|
||||
A temporary krb5.conf file will be generated to not fail on an invalid one.
|
||||
options:
|
||||
servers:
|
||||
description: The FQDN of the IPA servers to connect to.
|
||||
required: true
|
||||
type: list
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: no
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment.
|
||||
required: true
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment.
|
||||
required: true
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: The hostname of the machine to join (FQDN).
|
||||
required: true
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
kdc:
|
||||
description: The name or address of the host running the KDC.
|
||||
required: true
|
||||
description: The name or address of the host running the KDC
|
||||
required: no
|
||||
kinit_attempts:
|
||||
description: Repeat the request for host Kerberos ticket X times.
|
||||
required: false
|
||||
type: int
|
||||
default: 5
|
||||
description: Repeat the request for host Kerberos ticket X times
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -100,19 +98,18 @@ ping_test_ok:
|
||||
type: bool
|
||||
'''
|
||||
|
||||
class Object(object):
|
||||
pass
|
||||
options = Object()
|
||||
|
||||
import os
|
||||
import tempfile
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_client import *
|
||||
from ansible.module_utils.ansible_ipa_client import (
|
||||
SECURE_PATH, paths, kinit_keytab, run, GSSError, configure_krb5_conf
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
servers=dict(required=True, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
@@ -120,7 +117,7 @@ def main():
|
||||
kdc=dict(required=True),
|
||||
kinit_attempts=dict(required=False, type='int', default=5),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -163,52 +160,52 @@ def main():
|
||||
ping_test_ok = True
|
||||
except OSError:
|
||||
pass
|
||||
except GSSError as e:
|
||||
except GSSError:
|
||||
pass
|
||||
|
||||
# Second try: Validate krb5 keytab with temporary krb5
|
||||
# configuration
|
||||
if not krb5_conf_ok:
|
||||
try:
|
||||
(krb_fd, krb_name) = tempfile.mkstemp()
|
||||
os.close(krb_fd)
|
||||
configure_krb5_conf(
|
||||
cli_realm=realm,
|
||||
cli_domain=domain,
|
||||
cli_server=servers,
|
||||
cli_kdc=kdc,
|
||||
dnsok=False,
|
||||
filename=krb_name,
|
||||
client_domain=client_domain,
|
||||
client_hostname=hostname,
|
||||
configure_sssd=sssd,
|
||||
force=False)
|
||||
try:
|
||||
(krb_fd, krb_name) = tempfile.mkstemp()
|
||||
os.close(krb_fd)
|
||||
configure_krb5_conf(
|
||||
cli_realm=realm,
|
||||
cli_domain=domain,
|
||||
cli_server=servers,
|
||||
cli_kdc=kdc,
|
||||
dnsok=False,
|
||||
filename=krb_name,
|
||||
client_domain=client_domain,
|
||||
client_hostname=hostname,
|
||||
configure_sssd=sssd,
|
||||
force=False)
|
||||
|
||||
try:
|
||||
kinit_keytab(host_principal, paths.KRB5_KEYTAB,
|
||||
paths.IPA_DNS_CCACHE,
|
||||
config=krb_name,
|
||||
attempts=kinit_attempts)
|
||||
krb5_keytab_ok = True
|
||||
try:
|
||||
kinit_keytab(host_principal, paths.KRB5_KEYTAB,
|
||||
paths.IPA_DNS_CCACHE,
|
||||
config=krb_name,
|
||||
attempts=kinit_attempts)
|
||||
krb5_keytab_ok = True
|
||||
|
||||
# Test IPA
|
||||
env['KRB5_CONFIG'] = krb_name
|
||||
try:
|
||||
result = run(["/usr/bin/ipa", "ping"], raiseonerr=False,
|
||||
env=env)
|
||||
if result.returncode == 0:
|
||||
ping_test_ok = True
|
||||
except OSError:
|
||||
pass
|
||||
# Test IPA
|
||||
env['KRB5_CONFIG'] = krb_name
|
||||
try:
|
||||
result = run(["/usr/bin/ipa", "ping"], raiseonerr=False,
|
||||
env=env)
|
||||
if result.returncode == 0:
|
||||
ping_test_ok = True
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
except GSSError as e:
|
||||
pass
|
||||
except GSSError:
|
||||
pass
|
||||
|
||||
finally:
|
||||
try:
|
||||
os.remove(krb_name)
|
||||
except OSError:
|
||||
module.fail_json(msg="Could not remove %s" % krb_name)
|
||||
finally:
|
||||
try:
|
||||
os.remove(krb_name)
|
||||
except OSError:
|
||||
module.fail_json(msg="Could not remove %s" % krb_name)
|
||||
|
||||
module.exit_json(changed=False,
|
||||
krb5_keytab_ok=krb5_keytab_ok,
|
||||
@@ -216,5 +213,6 @@ def main():
|
||||
ca_crt_exists=ca_crt_exists,
|
||||
ping_test_ok=ping_test_ok)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -22,15 +22,39 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
__all__ = ["gssapi", "version", "ipadiscovery", "api", "errors", "x509",
|
||||
"constants", "sysrestore", "certmonger", "certstore",
|
||||
"delete_persistent_client_session_data", "ScriptError",
|
||||
"CheckedIPAddress", "validate_domain_name", "normalize_hostname",
|
||||
"validate_hostname", "services", "tasks", "CalledProcessError",
|
||||
"write_tmp_file", "ipa_generate_password", "DN", "kinit_keytab",
|
||||
"kinit_password", "GSSError", "CLIENT_INSTALL_ERROR",
|
||||
"is_ipa_client_installed", "CLIENT_ALREADY_CONFIGURED",
|
||||
"nssldap_exists", "remove_file", "check_ip_addresses",
|
||||
"print_port_conf_info", "configure_ipa_conf", "purge_host_keytab",
|
||||
"configure_sssd_conf", "realm_to_suffix", "run", "timeconf",
|
||||
"serialization", "configure_krb5_conf", "get_ca_certs",
|
||||
"SECURE_PATH", "get_server_connection_interface",
|
||||
"configure_nsswitch_database", "disable_ra", "client_dns",
|
||||
"configure_certmonger", "update_ssh_keys",
|
||||
"configure_openldap_conf", "hardcode_ldap_server",
|
||||
"get_certs_from_ldap", "save_state", "create_ipa_nssdb",
|
||||
"configure_nisdomain", "configure_ldap_conf",
|
||||
"configure_nslcd_conf", "nosssd_files", "configure_ssh_config",
|
||||
"configure_sshd_config", "configure_automount",
|
||||
"configure_firefox", "sync_time", "check_ldap_conf",
|
||||
"sssd_enable_ifp"]
|
||||
|
||||
from ipapython.version import NUM_VERSION, VERSION
|
||||
|
||||
if NUM_VERSION < 30201:
|
||||
# See ipapython/version.py
|
||||
IPA_MAJOR,IPA_MINOR,IPA_RELEASE = [ int(x) for x in VERSION.split(".", 2) ]
|
||||
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
||||
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
||||
else:
|
||||
IPA_PYTHON_VERSION = NUM_VERSION
|
||||
|
||||
|
||||
class installer_obj(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
@@ -38,20 +62,20 @@ class installer_obj(object):
|
||||
def set_logger(self, logger):
|
||||
self.logger = logger
|
||||
|
||||
#def __getattribute__(self, attr):
|
||||
# def __getattribute__(self, attr):
|
||||
# value = super(installer_obj, self).__getattribute__(attr)
|
||||
# if not attr.startswith("--") and not attr.endswith("--"):
|
||||
# logger.debug(
|
||||
# " <-- Accessing installer.%s (%s)" % (attr, repr(value)))
|
||||
# return value
|
||||
|
||||
#def __getattr__(self, attr):
|
||||
# #logger.info(" --> ADDING missing installer.%s" % attr)
|
||||
# def __getattr__(self, attr):
|
||||
# # logger.info(" --> ADDING missing installer.%s" % attr)
|
||||
# self.logger.warn(" --> ADDING missing installer.%s" % attr)
|
||||
# setattr(self, attr, None)
|
||||
# return getattr(self, attr)
|
||||
|
||||
#def __setattr__(self, attr, value):
|
||||
# def __setattr__(self, attr, value):
|
||||
# logger.debug(" --> Setting installer.%s to %s" % (attr, repr(value)))
|
||||
# return super(installer_obj, self).__setattr__(attr, value)
|
||||
|
||||
@@ -59,11 +83,13 @@ class installer_obj(object):
|
||||
for name in self.__dict__:
|
||||
yield self, name
|
||||
|
||||
|
||||
# Initialize installer settings
|
||||
installer = installer_obj()
|
||||
# Create options
|
||||
options = installer
|
||||
options.interactive = False
|
||||
options.unattended = not options.interactive
|
||||
|
||||
if NUM_VERSION >= 40400:
|
||||
# IPA version >= 4.4
|
||||
@@ -73,8 +99,6 @@ if NUM_VERSION >= 40400:
|
||||
import gssapi
|
||||
import logging
|
||||
|
||||
import six
|
||||
|
||||
from ipapython import version
|
||||
try:
|
||||
from ipaclient.install import ipadiscovery
|
||||
@@ -103,8 +127,10 @@ if NUM_VERSION >= 40400:
|
||||
from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform.tasks import tasks
|
||||
if NUM_VERSION >= 40500 and NUM_VERSION < 40590:
|
||||
try:
|
||||
from cryptography.hazmat.primitives import serialization
|
||||
except ImportError:
|
||||
serialization = None
|
||||
from ipapython.ipautil import CalledProcessError, write_tmp_file, \
|
||||
ipa_generate_password
|
||||
from ipapython.dn import DN
|
||||
@@ -125,7 +151,9 @@ if NUM_VERSION >= 40400:
|
||||
CLIENT_INSTALL_ERROR, is_ipa_client_installed, \
|
||||
CLIENT_ALREADY_CONFIGURED, nssldap_exists, remove_file, \
|
||||
check_ip_addresses, print_port_conf_info, configure_ipa_conf, \
|
||||
purge_host_keytab, configure_sssd_conf
|
||||
purge_host_keytab, configure_sssd_conf, configure_ldap_conf, \
|
||||
configure_nslcd_conf, nosssd_files
|
||||
get_ca_cert = None
|
||||
except ImportError:
|
||||
# Create temporary copy of ipa-client-install script (as
|
||||
# ipa_client_install.py) to be able to import the script easily
|
||||
@@ -134,7 +162,8 @@ if NUM_VERSION >= 40400:
|
||||
# needed in the next step.
|
||||
# This is done in a temporary directory that gets removed right
|
||||
# after ipa_client_install has been imported.
|
||||
import shutil, tempfile
|
||||
import shutil
|
||||
import tempfile
|
||||
temp_dir = tempfile.mkdtemp(dir="/tmp")
|
||||
sys.path.append(temp_dir)
|
||||
temp_file = "%s/ipa_client_install.py" % temp_dir
|
||||
@@ -168,11 +197,15 @@ if NUM_VERSION >= 40400:
|
||||
get_ca_cert = ipa_client_install.get_ca_cert
|
||||
get_ca_certs = None
|
||||
else:
|
||||
get_ca_cert = None
|
||||
get_ca_certs = ipa_client_install.get_ca_certs
|
||||
SECURE_PATH = ("/bin:/sbin:/usr/kerberos/bin:/usr/kerberos/sbin:/usr/bin:/usr/sbin")
|
||||
SECURE_PATH = ("/bin:/sbin:/usr/kerberos/bin:/usr/kerberos/sbin:"
|
||||
"/usr/bin:/usr/sbin")
|
||||
|
||||
get_server_connection_interface = ipa_client_install.get_server_connection_interface
|
||||
configure_nsswitch_database = ipa_client_install.configure_nsswitch_database
|
||||
get_server_connection_interface = \
|
||||
ipa_client_install.get_server_connection_interface
|
||||
configure_nsswitch_database = \
|
||||
ipa_client_install.configure_nsswitch_database
|
||||
disable_ra = ipa_client_install.disable_ra
|
||||
client_dns = ipa_client_install.client_dns
|
||||
configure_certmonger = ipa_client_install.configure_certmonger
|
||||
@@ -191,6 +224,10 @@ if NUM_VERSION >= 40400:
|
||||
def configure_nisdomain(options, domain, statestore=None):
|
||||
return ipa_client_install.configure_nisdomain(options, domain)
|
||||
|
||||
configure_ldap_conf = ipa_client_install.configure_ldap_conf
|
||||
configure_nslcd_conf = ipa_client_install.configure_nslcd_conf
|
||||
nosssd_files = ipa_client_install.nosssd_files
|
||||
|
||||
configure_ssh_config = ipa_client_install.configure_ssh_config
|
||||
configure_sshd_config = ipa_client_install.configure_sshd_config
|
||||
configure_automount = ipa_client_install.configure_automount
|
||||
@@ -198,9 +235,6 @@ if NUM_VERSION >= 40400:
|
||||
|
||||
from ipapython.ipautil import realm_to_suffix, run
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
try:
|
||||
from ipaclient.install import timeconf
|
||||
time_service = "chronyd"
|
||||
@@ -244,7 +278,7 @@ def ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
if ip_addresses is None:
|
||||
return None
|
||||
|
||||
ip_addrs = [ ]
|
||||
ip_addrs = []
|
||||
for ip in ip_addresses:
|
||||
try:
|
||||
ip_parsed = ipautil.CheckedIPAddress(ip)
|
||||
@@ -252,4 +286,3 @@ def ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
ansible_module.fail_json(msg="Invalid IP Address %s: %s" % (ip, e))
|
||||
ip_addrs.append(ip_parsed)
|
||||
return ip_addrs
|
||||
|
||||
|
||||
@@ -3,9 +3,8 @@
|
||||
|
||||
- name: Install - Ensure that IPA client packages are installed
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
name: "{{ ipaclient_packages }}"
|
||||
state: present
|
||||
with_items: "{{ ipaclient_packages }}"
|
||||
when: ipaclient_install_packages | bool
|
||||
|
||||
#- name: Install - Include Python2/3 import test
|
||||
@@ -64,8 +63,8 @@
|
||||
- name: Install - Configure NTP
|
||||
ipaclient_setup_ntp:
|
||||
### basic ###
|
||||
ntp_servers: "{{ ipaclient_ntp_servers | default(omit) }}"
|
||||
ntp_pool: "{{ ipaclient_ntp_pool | default(omit) }}"
|
||||
ntp_servers: "{{ result_ipaclient_test.ntp_servers | default(omit) }}"
|
||||
ntp_pool: "{{ result_ipaclient_test.ntp_pool | default(omit) }}"
|
||||
no_ntp: "{{ ipaclient_no_ntp }}"
|
||||
# force_ntpd: "{{ ipaclient_force_ntpd }}"
|
||||
on_master: "{{ ipaclient_on_master }}"
|
||||
@@ -107,10 +106,6 @@
|
||||
fail: msg="Keytab or password is required for otp"
|
||||
when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
|
||||
|
||||
- name: Install - Save client ansible_python_interpreter setting
|
||||
set_fact:
|
||||
ipaclient_ansible_python_interpreter: "{{ ansible_python_interpreter }}"
|
||||
|
||||
#- name: Install - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
# delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
@@ -119,13 +114,12 @@
|
||||
no_log: yes
|
||||
ipaclient_get_otp:
|
||||
state: present
|
||||
principal: "{{ ipaadmin_principal | default('admin') }}"
|
||||
principal: "{{ ipaadmin_principal | default(omit) }}"
|
||||
password: "{{ ipaadmin_password | default(omit) }}"
|
||||
keytab: "{{ ipaadmin_keytab | default(omit) }}"
|
||||
fqdn: "{{ result_ipaclient_test.hostname }}"
|
||||
lifetime: "{{ ipaclient_lifetime | default(omit) }}"
|
||||
random: True
|
||||
ansible_python_interpreter: "{{ ansible_python_interpreter }}"
|
||||
register: result_ipaclient_get_otp
|
||||
# If the host is already enrolled, this command will exit on error
|
||||
# The error can be ignored
|
||||
@@ -134,18 +128,21 @@
|
||||
in result_ipaclient_get_otp.msg
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
delegate_facts: yes
|
||||
ignore_errors: yes
|
||||
|
||||
- name: Install - Report error for OTP generation
|
||||
debug:
|
||||
msg: "{{ result_ipaclient_get_otp.msg }}"
|
||||
when: result_ipaclient_get_otp is failed
|
||||
failed_when: yes
|
||||
|
||||
- name: Install - Store the previously obtained OTP
|
||||
no_log: yes
|
||||
set_fact:
|
||||
ipaadmin_orig_password: "{{ ipaadmin_password }}"
|
||||
ipaadmin_orig_password: "{{ ipaadmin_password | default(omit) }}"
|
||||
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword
|
||||
if result_ipaclient_get_otp.host is defined }}"
|
||||
|
||||
- name: Install - Restore client ansible_python_interpreter setting
|
||||
set_fact:
|
||||
ansible_python_interpreter: "{{ ipaclient_ansible_python_interpreter }}"
|
||||
|
||||
when: ipaclient_use_otp | bool
|
||||
|
||||
- block:
|
||||
@@ -159,14 +156,14 @@
|
||||
|
||||
- name: Install - Check if principal and keytab are set
|
||||
fail: msg="Principal and keytab cannot be used together"
|
||||
when: ipaadmin_principal is defined and ipaadmin_principal|length > 0
|
||||
and ipaclient_keytab is defined and ipaclient_keytab|length > 0
|
||||
when: ipaadmin_principal is defined and ipaclient_keytab is defined
|
||||
|
||||
- name: Install - Check if one of password and keytab are set
|
||||
fail: msg="At least one of password or keytab must be specified"
|
||||
when: not result_ipaclient_test_keytab.krb5_keytab_ok and
|
||||
(ipaadmin_password is undefined or ipaadmin_password|length == 0)
|
||||
and (ipaclient_keytab is undefined or ipaclient_keytab|length == 0)
|
||||
- name: Install - Check if one of password or keytabs are set
|
||||
fail: msg="At least one of password or keytabs must be specified"
|
||||
when: not result_ipaclient_test_keytab.krb5_keytab_ok
|
||||
and ipaadmin_password is undefined
|
||||
and ipaadmin_keytab is undefined
|
||||
and ipaclient_keytab is undefined
|
||||
when: not ipaclient_on_master | bool
|
||||
|
||||
- name: Install - Purge {{ result_ipaclient_test.realm }} from host keytab
|
||||
@@ -197,9 +194,10 @@
|
||||
hostname: "{{ result_ipaclient_test.hostname }}"
|
||||
force_join: "{{ ipaclient_force_join | default(omit) }}"
|
||||
principal: "{{ ipaadmin_principal if not ipaclient_use_otp | bool and
|
||||
ipaclient_keytab is not defined else '' }}"
|
||||
ipaclient_keytab is not defined else omit }}"
|
||||
password: "{{ ipaadmin_password | default(omit) }}"
|
||||
keytab: "{{ ipaclient_keytab | default(omit) }}"
|
||||
admin_keytab: "{{ ipaadmin_keytab if ipaadmin_keytab is defined and not ipaclient_use_otp | bool else omit }}"
|
||||
# ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}"
|
||||
kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}"
|
||||
register: result_ipaclient_join
|
||||
@@ -298,6 +296,7 @@
|
||||
mkhomedir: "{{ ipaclient_mkhomedir }}"
|
||||
ca_enabled: "{{ result_ipaclient_api.ca_enabled }}"
|
||||
on_master: "{{ ipaclient_on_master }}"
|
||||
dnsok: "{{ result_ipaclient_test.dnsok }}"
|
||||
enable_dns_updates: "{{ ipassd_enable_dns_updates }}"
|
||||
all_ip_addresses: "{{ ipaclient_all_ip_addresses }}"
|
||||
ip_addresses: "{{ ipaclient_ip_addresses | default(omit) }}"
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
- "{{ role_path }}/vars/default.yml"
|
||||
|
||||
- name: Install IPA client
|
||||
include_tasks: tasks/install.yml
|
||||
include_tasks: install.yml
|
||||
when: state|default('present') == 'present'
|
||||
|
||||
- name: Uninstall IPA client
|
||||
include_tasks: tasks/uninstall.yml
|
||||
include_tasks: uninstall.yml
|
||||
when: state|default('present') == 'absent'
|
||||
|
||||
@@ -14,8 +14,7 @@
|
||||
failed_when: uninstall.rc != 0 and uninstall.rc != 2
|
||||
changed_when: uninstall.rc == 0
|
||||
|
||||
# - name: Remove IPA client package
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipaclient_packages }}"
|
||||
#- name: Remove IPA client package
|
||||
# package:
|
||||
# name: "{{ ipaclient_packages }}"
|
||||
# state: absent
|
||||
|
||||
3
roles/ipaclient/vars/RedHat-8.yml
Normal file
3
roles/ipaclient/vars/RedHat-8.yml
Normal file
@@ -0,0 +1,3 @@
|
||||
# defaults file for ipaclient
|
||||
# vars/RedHat-8.yml
|
||||
ipaclient_packages: [ "@idm:DL1/client" ]
|
||||
@@ -9,8 +9,41 @@ Changes made to any master are automatically replicated to other masters.
|
||||
|
||||
This can be done in differnt ways using auto-discovery of the servers, domain and other settings or by specifying them.
|
||||
|
||||
**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
|
||||
--------
|
||||
* Replica deployment
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.6 and up are supported by the replica 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 principal using auto-discovery with DNS records:
|
||||
|
||||
@@ -68,68 +101,146 @@ Example playbook to setup the IPA client(s) using principal and password from in
|
||||
- role: ipareplica
|
||||
state: present
|
||||
|
||||
|
||||
Playbooks
|
||||
=========
|
||||
|
||||
The playbooks needed to deploy or undeploy a replica are part of the repository in the playbooks folder. There are also playbooks to deploy and undeploy clusters.
|
||||
```
|
||||
install-replica.yml
|
||||
uninstall-replica.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.
|
||||
|
||||
|
||||
How to setup replicas
|
||||
---------------------
|
||||
|
||||
```bash
|
||||
ansible-playbook -v -i inventory/hosts install-replica.yml
|
||||
```
|
||||
This will deploy the replicas defined in the inventory file.
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
=========
|
||||
|
||||
**ipaserver** - Group with IPA server hostname.
|
||||
(list of strings, optional)
|
||||
Base Variables
|
||||
--------------
|
||||
|
||||
**ipaclients** - Group of IPA client hostnames.
|
||||
(list of strings)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaservers` | This group with the IPA master full qualified hostnames. (list of strings) | mostly
|
||||
`ipareplicas` | Group of IPA replica hostnames. (list of strings) | yes
|
||||
`ipaadmin_password` | The password for the IPA admin user (string) | mostly
|
||||
`ipareplica_ip_addresses` | The list of master server IP addresses. (list of strings) | no
|
||||
`ipareplica_domain` | The primary DNS domain of an existing IPA deployment. (string) | no
|
||||
`ipaserver_realm` | The Kerberos realm of an existing IPA deployment. (string) | no
|
||||
`ipaserver_hostname` | Fully qualified name of the server. (string) | no
|
||||
`ipaadmin_principal` | The authorized kerberos principal used to join the IPA realm. (string) | no
|
||||
`ipareplica_no_host_dns` | Do not use DNS for hostname lookup during installation. (bool, default: false) | no
|
||||
`ipareplica_skip_conncheck` | Skip connection check to remote master. (bool, default: false) | no
|
||||
`ipareplica_pki_config_override` | Path to ini file with config overrides. This is only usable with recent FreeIPA versions. (string) | no
|
||||
|
||||
**ipaadmin_keytab** - The path to the admin keytab used for alternative authentication.
|
||||
(string, optional)
|
||||
Server Vaiables
|
||||
---------------
|
||||
|
||||
**ipaadmin_principal** - The authorized kerberos principal used to join the IPA realm.
|
||||
(string, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipadm_password` | The password for the Directory Manager. (string) | mostly
|
||||
`ipareplica_setup_adtrust` | Configure AD trust capability. (bool, default: false) | no
|
||||
`ipareplica_setup_ca` | Configure a dogtag CA. (bool, default: false) | no
|
||||
`ipareplica_setup_kra` | Configure a dogtag KRA. (bool, default: false) | no
|
||||
`ipareplica_setup_dns` | Configure bind with our zone. (bool, default: false) | no
|
||||
`ipareplica_no_pkinit` | Disables pkinit setup steps. (bool, default: false) | no
|
||||
`ipareplica_no_ui_redirect` | Do not automatically redirect to the Web UI. (bool, default: false) | no
|
||||
`ipareplica_dirsrv_config_file` | The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance. (string)| no
|
||||
|
||||
**ipaadmin_password** - The password for the kerberos principal.
|
||||
(string, optional)
|
||||
|
||||
**ipaclient_domain** - The primary DNS domain of an existing IPA deployment.
|
||||
(string, optional)
|
||||
SSL certificate Variables
|
||||
-------------------------
|
||||
|
||||
**ipaclient_realm** - The Kerberos realm of an existing IPA deployment.
|
||||
(string, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipareplica_dirsrv_cert_files` | Files containing the Directory Server SSL certificate and private keys. (list of strings) | no
|
||||
`ipareplica_http_cert_file` | File containing the Apache Server SSL certificate and private key. (string) | no
|
||||
`ipareplica_pkinit_cert_file` | File containing the Kerberos KDC SSL certificate and private key. (string) | no
|
||||
`ipareplica_dirsrv_pin` | The password to unlock the Directory Server private key. (string) | no
|
||||
`ipareplica_http_pin` | The password to unlock the Apache Server private key. (string) | no
|
||||
`ipareplica_pkinit_pin` | The password to unlock the Kerberos KDC private key. (string) | no
|
||||
`ipareplica_dirsrv_cert_name` | Name of the Directory Server SSL certificate to install. (string) | no
|
||||
`ipareplica_http_cert_name` | Name of the Apache Server SSL certificate to install. (string) | no
|
||||
`ipareplica_pkinit_cert_name` | Name of the Kerberos KDC SSL certificate to install. (string) | no
|
||||
|
||||
**ipaclient_keytab** - The path to a backed-up host keytab from previous enrollment.
|
||||
(string, optional)
|
||||
Client Variables
|
||||
----------------
|
||||
|
||||
**ipaclient_force_join** - Set force_join to yes to join the host even if it is already enrolled.
|
||||
(bool, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaclient_keytab` | Path to backed up keytab from previous enrollment. (string) | no
|
||||
`ipaclient_mkhomedir` | Set to yes to configure PAM to create a users home directory if it does not exist. (string) | no
|
||||
`ipaclient_force_join` | Force client enrollment even if already enrolled. (bool, default: false) | no
|
||||
`ipaclient_ntp_servers` | The list defines the NTP servers to be used. (list of strings) | no
|
||||
`ipaclient_ntp_pool` | The string value defines the ntp server pool to be used. (string) | no
|
||||
`ipaclient_no_ntp` | The bool value defines if NTP will not be configured and enabled. (bool, default: false) | no
|
||||
`ipaclient_ssh_trust_dns` | The bool value defines if OpenSSH client will be configured to trust DNS SSHFP records. (bool, default: false) | no
|
||||
`ipaclient_no_ssh` | The bool value defines if OpenSSH client will be configured. (bool, default: false) | no
|
||||
`ipaclient_no_sshd` | The bool value defines if OpenSSH server will be configured. (bool, default: false) | no
|
||||
`ipaclient_no_sudo` | The bool value defines if SSSD will be configured as a data source for sudo. (bool, default: false) | no
|
||||
`ipaclient_no_dns_sshfp` | The bool value defines if DNS SSHFP records will not be created automatically. (bool, default: false) | no
|
||||
|
||||
**ipaclient_use_otp** - Enforce the generation of a one time password to configure new and existing hosts. The enforcement on an existing host is not done if there is a working krb5.keytab on the host. If the generation of an otp is enforced for an existing host entry, then the host gets diabled and the containing keytab gets removed.
|
||||
(bool, optional)
|
||||
Certificate system Variables
|
||||
----------------------------
|
||||
|
||||
**ipaclient_allow_repair** - Allow repair of already joined hosts. Contrary to ipaclient_force_join the host entry will not be changed on the server.
|
||||
(bool, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
~~`ipareplica_skip_schema_check`~~ | ~~Skip check for updated CA DS schema on the remote master. (bool, default: false)~~ | ~~no~~
|
||||
|
||||
**ipaclient_kinit_attempts** - Repeat the request for host Kerberos ticket X times if it fails.
|
||||
(int, optional)
|
||||
DNS Variables
|
||||
-------------
|
||||
|
||||
**ipaclient_no_ntp** - Set to yes to not configure and enable NTP
|
||||
(bool, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipareplica_allow_zone_overlap` | Allow creation of (reverse) zone even if the zone is already resolvable. (bool, default: false) | no
|
||||
`ipareplica_reverse_zones` | The reverse DNS zones to use. (list of strings) | no
|
||||
`ipareplica_no_reverse` | Do not create reverse DNS zone. (bool, default: false) | no
|
||||
`ipareplica_auto_reverse` | Try to resolve reverse records and reverse zones for server IP addresses. (bool, default: false) | no
|
||||
`ipareplica_zonemgr` | The e-mail address of the DNS zone manager. (string, default: hostmaster@DOMAIN.) | no
|
||||
`ipareplica_forwarders` | Add DNS forwarders to the DNS configuration. (list of strings) | no
|
||||
`ipareplica_no_forwarders` | Do not add any DNS forwarders. Root DNS servers will be used instead. (bool, default: false) | no
|
||||
`ipareplica_auto_forwarders` | Add DNS forwarders configured in /etc/resolv.conf to the list of forwarders used by IPA DNS. (bool, default: false) | no
|
||||
`ipareplica_forward_policy` | DNS forwarding policy for global forwarders specified using other options. (choice: first,only) | no
|
||||
`ipareplica_no_dnssec_validation` | Disable DNSSEC validation on this server. (bool, default: false) | no
|
||||
|
||||
**ipaclient_mkhomedir** - Set to yes to configure PAM to create a users home directory if it does not exist.
|
||||
(string, optional)
|
||||
AD trust Variables
|
||||
------------------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
~~`ipareplica_add_sids`~~ | ~~Add SIDs for existing users and groups as the final step. (bool, default: false)~~ | ~~no~~
|
||||
~~`ipareplica_add_agents`~~ | ~~Add IPA masters to a list of hosts allowed to serve information about users from trusted forests. (bool, default: false)~~ | ~~no~~
|
||||
`ipareplica_enable_compat`| Enables support for trusted domains users for old clients through Schema Compatibility plugin. (bool, default: false) | no
|
||||
`ipareplica_netbios_name` | The NetBIOS name for the IPA domain. (string) | no
|
||||
`ipareplica_rid_base` | First RID value of the local domain. (integer) | no
|
||||
`ipareplica_secondary_rid_base` | Start value of the secondary RID range. (integer) | no
|
||||
|
||||
Cluster Specific Variables
|
||||
--------------------------
|
||||
|
||||
**ipaclient_no_dns_lookup** - Set to 'yes' to use groups.ipaserver in cluster environments as servers for the clients. This deactivates DNS lookup in krb5.
|
||||
(bool, optional, default: 'no')
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipareplica_servers` | Manually override list of servers for example in a cluster environment on a per replica basis. The list of servers is normally taken from from groups.ipaserver in cluster environments. (list of strings) | no
|
||||
`ipaserver_domain` | Used if set in a cliuster environment to overload `ipareplica_domain` | no
|
||||
|
||||
**ipareplica_servers** - Manually override list of servers for example in a cluster environment on a per client basis. The list of servers is normally taken from from groups.ipaserver in cluster environments.
|
||||
(list of strings, optional)
|
||||
Special Variables
|
||||
-----------------
|
||||
|
||||
Requirements
|
||||
------------
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipareplica_install_packages` | The bool value defines if the needed packages are installed on the node. (bool, default: true) | no
|
||||
`ipareplica_setup_firewalld` | The value defines if the needed services will automatically be openen in the firewall managed by firewalld. (bool, default: true) | no
|
||||
|
||||
freeipa-server v4.6 or later
|
||||
|
||||
Authors
|
||||
-------
|
||||
|
||||
Florence Blanc-Renaud
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
|
||||
@@ -38,20 +38,20 @@ description:
|
||||
Add to ipaservers
|
||||
options:
|
||||
setup_kra:
|
||||
description:
|
||||
required: yes
|
||||
description: Configure a dogtag KRA
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
installer_ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer ccache setting
|
||||
required: no
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -62,21 +62,32 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import six
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_remote_api, api
|
||||
)
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_kra=dict(required=True, type='bool'),
|
||||
### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
installer_ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -85,33 +96,30 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
### additional ###
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
# additional
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
options._ccache = ansible_module.params.get('installer_ccache')
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALLER ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
#config = gen_ReplicaConfig()
|
||||
# config = gen_ReplicaConfig()
|
||||
|
||||
remote_api = gen_remote_api(config_master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
# installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
@@ -134,5 +142,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -45,7 +45,7 @@ options:
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: no
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
@@ -56,83 +56,73 @@ options:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ca_cert_files:
|
||||
description: List of iles containing CA certificates for the service certificate files
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
dirserv_cert_files:
|
||||
description:
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
force_join:
|
||||
description:
|
||||
description: Force client enrollment even if already enrolled
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
server:
|
||||
description:
|
||||
required: yes
|
||||
description: Fully qualified name of IPA server to enroll to
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
config_ca_host_name:
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
installer_ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer ccache setting
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description:
|
||||
required: yes
|
||||
_kra_enabled:
|
||||
description:
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description:
|
||||
required: yes
|
||||
_http_pkcs12_info:
|
||||
description:
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
_add_to_ipaservers:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _add_to_ipaservers setting
|
||||
required: no
|
||||
_ca_subject:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _ca_subject setting
|
||||
required: no
|
||||
_subject_base:
|
||||
description:
|
||||
description: The installer _subject_base setting
|
||||
required: no
|
||||
master:
|
||||
description: Master host name
|
||||
required: yes
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
config_setup_ca:
|
||||
description:
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
config_ca_host_name:
|
||||
description:
|
||||
required: yes
|
||||
config_ips:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -143,13 +133,21 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
ansible_module_get_parsed_ip_addresses, sysrestore,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, create_ipa_conf
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=False, no_log=True),
|
||||
password=dict(required=False, no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
@@ -158,35 +156,33 @@ def main():
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool'),
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
setup_dns=dict(required=False, type='bool'),
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
### client ###
|
||||
# client
|
||||
force_join=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
# additional
|
||||
server=dict(required=True),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
installer_ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_top_dir=dict(required=True),
|
||||
_add_to_ipaservers=dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
master=dict(required=False, default=None),
|
||||
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -205,16 +201,16 @@ def main():
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
### client ###
|
||||
# client
|
||||
options.force_join = ansible_module.params.get('force_join')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.external_ca = ansible_module.params.get('external_ca')
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
@@ -222,37 +218,34 @@ def main():
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options.ca_subject = ansible_module.params.get('ca_subject')
|
||||
### additional ###
|
||||
#options._host_name_overridden = ansible_module.params.get(
|
||||
# '_hostname_overridden')
|
||||
# additional
|
||||
# options._host_name_overridden = ansible_module.params.get(
|
||||
# '_hostname_overridden')
|
||||
options.server = ansible_module.params.get('server')
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ca_host_name = ansible_module.params.get('config_ca_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
http_pkcs12_info = ansible_module.params.get('_http_pkcs12_info')
|
||||
pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options._add_to_ipaservers = ansible_module.params.get('_add_to_ipaservers')
|
||||
options._add_to_ipaservers = ansible_module.params.get(
|
||||
'_add_to_ipaservers')
|
||||
|
||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||
options._subject_base = ansible_module.params.get('_subject_base')
|
||||
master = ansible_module.params.get('master')
|
||||
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
# prepare (install prepare, install checks) #
|
||||
|
||||
@@ -267,15 +260,13 @@ def main():
|
||||
config = gen_ReplicaConfig()
|
||||
config.subject_base = options.subject_base
|
||||
config.dirman_password = dirman_password
|
||||
config.ca_host_name = ca_host_name
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
cafile = paths.IPA_CA_CRT
|
||||
|
||||
if promote:
|
||||
ansible_log.debug("-- CREATE_IPA_CONF --")
|
||||
# Create the management framework config file. Do this irregardless
|
||||
@@ -284,11 +275,12 @@ def main():
|
||||
# successful uninstallation
|
||||
# The configuration creation has to be here otherwise previous call
|
||||
# To config certmonger would try to connect to local server
|
||||
create_ipa_conf(fstore, config, ca_enabled)
|
||||
create_ipa_conf(fstore, config, ca_enabled, master)
|
||||
|
||||
# done #
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,44 +38,52 @@ description:
|
||||
Import dm password into custodia
|
||||
options:
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_ca_file:
|
||||
description:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description:
|
||||
_kra_enabled:
|
||||
description: The installer _kra_enabled setting
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description:
|
||||
_kra_host_name:
|
||||
description: The installer _kra_host_name setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
config_setup_ca:
|
||||
description: The config setup_ca setting
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
config_ca_host_name:
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -86,32 +94,40 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, redirect_stdout, custodiainstance
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_kra_host_name=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -120,23 +136,23 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
kra_host_name = ansible_module.params.get('_kra_host_name')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
config_setup_ca = ansible_module.params.get('config_setup_ca')
|
||||
@@ -144,9 +160,6 @@ def main():
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
@@ -161,11 +174,12 @@ def main():
|
||||
config.ca_host_name = config_ca_host_name
|
||||
config.subject_base = options.subject_base
|
||||
config.promote = installer.promote
|
||||
config.kra_enabled = kra_enabled
|
||||
config.kra_host_name = kra_host_name
|
||||
|
||||
remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
# do the work #
|
||||
@@ -193,5 +207,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -37,6 +37,55 @@ short description: DS apply updates
|
||||
description:
|
||||
DS apply updates
|
||||
options:
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_ca_file:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
ds_ca_subject:
|
||||
description: The ds.ca_subject setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,32 +96,40 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout,
|
||||
replica_ds_init_info, dsinstance, upgradeinstance, installutils
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
_pkinit_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
ds_ca_subject=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -81,38 +138,37 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
### certificate system ###
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
installer._dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
installer._pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
installer._dirsrv_pkcs12_info = ansible_module.params.get(
|
||||
'_dirsrv_pkcs12_info')
|
||||
installer._pkinit_pkcs12_info = ansible_module.params.get(
|
||||
'_pkinit_pkcs12_info')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
ds_ca_subject = ansible_module.params.get('ds_ca_subject')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
pkinit_pkcs12_info = installer._pkinit_pkcs12_info
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -122,17 +178,15 @@ def main():
|
||||
config.subject_base = options.subject_base
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
# There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or
|
||||
# ntpinstance
|
||||
# ntpinstance
|
||||
api.Backend.ldap2.connect()
|
||||
conn.connect(ccache=ccache)
|
||||
|
||||
cafile = paths.IPA_CA_CRT
|
||||
with redirect_stdout(ansible_log):
|
||||
ds = replica_ds_init_info(ansible_log,
|
||||
config, options, ca_enabled,
|
||||
@@ -145,8 +199,8 @@ def main():
|
||||
|
||||
# Apply any LDAP updates. Needs to be done after the replica is
|
||||
# synced-up
|
||||
#service.print_msg("Applying LDAP updates")
|
||||
#ds.apply_updates()
|
||||
# service.print_msg("Applying LDAP updates")
|
||||
# ds.apply_updates()
|
||||
schema_files = dsinstance.get_all_external_schema_files(
|
||||
paths.EXTERNAL_SCHEMA_DIR)
|
||||
data_upgrade = upgradeinstance.IPAUpgrade(ds.realm,
|
||||
@@ -163,5 +217,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,44 +38,51 @@ description:
|
||||
DS enable SSL
|
||||
options:
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_ca_file:
|
||||
description:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
ds_ca_subject:
|
||||
description:
|
||||
required: yes
|
||||
description: The ds.ca_subject setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -86,31 +93,39 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout,
|
||||
replica_ds_init_info
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
_pkinit_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
ds_ca_subject=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -119,38 +134,37 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
### certificate system ###
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
options._dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
options._pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
options._dirsrv_pkcs12_info = ansible_module.params.get(
|
||||
'_dirsrv_pkcs12_info')
|
||||
options._pkinit_pkcs12_info = ansible_module.params.get(
|
||||
'_pkinit_pkcs12_info')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
ds_ca_subject = ansible_module.params.get('ds_ca_subject')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
pkinit_pkcs12_info = installer._pkinit_pkcs12_info
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -160,7 +174,7 @@ def main():
|
||||
config.subject_base = options.subject_base
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
# installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
@@ -187,5 +201,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -33,25 +33,36 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_enable_ipa
|
||||
short description:
|
||||
short description: Enable IPA
|
||||
description: Enable IPA
|
||||
Enable IPA
|
||||
options:
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
hidden_replica:
|
||||
description: Install a hidden replica
|
||||
required: yes
|
||||
subject_base:
|
||||
description: The certificate subject base (default O=<realm-name>).
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
ccache:
|
||||
description: The installation specific ccache file.
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_top_dir:
|
||||
description: The temporary top directory used for the installation.
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
required: no
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The master host name
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -62,24 +73,33 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, service,
|
||||
find_providing_servers, services
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
hostname=dict(required=False),
|
||||
hidden_replica=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
### certificate system ###
|
||||
# server
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
setup_kra=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -90,27 +110,24 @@ def main():
|
||||
options = installer
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.hidden_replica = ansible_module.params.get('hidden_replica')
|
||||
### server ###
|
||||
### certificate system ###
|
||||
# server
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
@@ -119,7 +136,6 @@ def main():
|
||||
remote_api = gen_remote_api(config_master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
api.Backend.ldap2.connect()
|
||||
@@ -153,5 +169,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -45,7 +45,7 @@ options:
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: no
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
@@ -56,37 +56,72 @@ options:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ca_cert_files:
|
||||
description: List of iles containing CA certificates for the service certificate files
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description:
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
required: yes
|
||||
setup_dns:
|
||||
description:
|
||||
required: yes
|
||||
external_ca:
|
||||
description:
|
||||
required: yes
|
||||
external_cert_files:
|
||||
description:
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
ca_subject:
|
||||
description:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
_hostname_overridden:
|
||||
description:
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
force_join:
|
||||
description: Force client enrollment even if already enrolled
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
server:
|
||||
description: Fully qualified name of IPA server to enroll to
|
||||
required: no
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
installer_ccache:
|
||||
description: The installer ccache setting
|
||||
required: no
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
_add_to_ipaservers:
|
||||
description: The installer _add_to_ipaservers setting
|
||||
required: no
|
||||
_ca_subject:
|
||||
description: The installer _ca_subject setting
|
||||
required: no
|
||||
_subject_base:
|
||||
description: The installer _subject_base setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
config_setup_ca:
|
||||
description: The config setup_ca setting
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
config_ca_host_name:
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
config_ips:
|
||||
description: The config ips setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
@@ -98,13 +133,22 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, ipaldap,
|
||||
install_ca_cert
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=False, no_log=True),
|
||||
password=dict(required=False, no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
@@ -113,28 +157,23 @@ def main():
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool'),
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
setup_dns=dict(required=False, type='bool'),
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
### client ###
|
||||
# client
|
||||
force_join=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
# additional
|
||||
server=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
installer_ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_top_dir=dict(required=True),
|
||||
_add_to_ipaservers=dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
@@ -143,7 +182,7 @@ def main():
|
||||
config_ca_host_name=dict(required=True),
|
||||
config_ips=dict(required=False, type='list', default=[]),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -152,7 +191,7 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### basic ###
|
||||
# basic
|
||||
options.dm_password = ansible_module.params.get('dm_password')
|
||||
options.password = options.dm_password
|
||||
options.admin_password = ansible_module.params.get('password')
|
||||
@@ -163,16 +202,16 @@ def main():
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
### client ###
|
||||
# client
|
||||
options.force_join = ansible_module.params.get('force_join')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.external_ca = ansible_module.params.get('external_ca')
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
@@ -180,36 +219,30 @@ def main():
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options.ca_subject = ansible_module.params.get('ca_subject')
|
||||
### additional ###
|
||||
# additional
|
||||
options.server = ansible_module.params.get('server')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
http_pkcs12_info = ansible_module.params.get('_http_pkcs12_info')
|
||||
pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options._add_to_ipaservers = ansible_module.params.get('_add_to_ipaservers')
|
||||
options._add_to_ipaservers = ansible_module.params.get(
|
||||
'_add_to_ipaservers')
|
||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||
options._subject_base = ansible_module.params.get('_subject_base')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
config_setup_ca = ansible_module.params.get('config_setup_ca')
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
config_ca_host_name = ansible_module.params.get('config_ca_host_name')
|
||||
config_ips = ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
"config_ips")
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALLER ==")
|
||||
|
||||
options = installer
|
||||
@@ -247,7 +280,8 @@ def main():
|
||||
|
||||
ansible_log.debug("-- INSTALL_CA_CERT --")
|
||||
# Update and istall updated CA file
|
||||
cafile = install_ca_cert(conn, api.env.basedn, api.env.realm, cafile)
|
||||
cafile = install_ca_cert(conn, api.env.basedn, api.env.realm,
|
||||
cafile)
|
||||
install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
|
||||
destfile=paths.KDC_CA_BUNDLE_PEM)
|
||||
install_ca_cert(conn, api.env.basedn, api.env.realm, cafile,
|
||||
@@ -264,5 +298,6 @@ def main():
|
||||
config_master_host_name=config.master_host_name,
|
||||
config_ca_host_name=config.ca_host_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -37,6 +37,41 @@ short description: KRB enable SSL
|
||||
description:
|
||||
KRB enable SSL
|
||||
options:
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_ca_file:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,29 +82,35 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths, sysrestore,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, krbinstance, redirect_stdout
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_pkinit_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -78,36 +119,32 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
options._pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
options._pkinit_pkcs12_info = ansible_module.params.get(
|
||||
'_pkinit_pkcs12_info')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
pkinit_pkcs12_info = installer._pkinit_pkcs12_info
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -116,7 +153,7 @@ def main():
|
||||
config.dirman_password = dirman_password
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
# installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
@@ -133,6 +170,8 @@ def main():
|
||||
krb.init_info(api.env.realm, api.env.host,
|
||||
setup_pkinit=not options.no_pkinit,
|
||||
subject_base=options.subject_base)
|
||||
krb.pkcs12_info = options._pkinit_pkcs12_info
|
||||
krb.master_fqdn = master_host_name
|
||||
|
||||
ansible_log.debug("-- KRB ENABLE_SSL --")
|
||||
|
||||
@@ -143,5 +182,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -37,7 +37,7 @@ description:
|
||||
options:
|
||||
master_password:
|
||||
description: kerberos master password (normally autogenerated)
|
||||
required: false
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -51,43 +51,31 @@ password:
|
||||
returned: always
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
ipa_generate_password
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
master_password=dict(required=False, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
|
||||
options.dm_password = module.params.get('dm_password')
|
||||
options.master_password = module.params.get('master_password')
|
||||
master_password = module.params.get('master_password')
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
# This will override any settings passed in on the cmdline
|
||||
if os.path.isfile(paths.ROOT_IPA_CACHE):
|
||||
# dm_password check removed, checked already
|
||||
try:
|
||||
cache_vars = read_cache(options.dm_password)
|
||||
options.__dict__.update(cache_vars)
|
||||
except Exception as e:
|
||||
module.fail_json(msg="Cannot process the cache file: %s" % str(e))
|
||||
|
||||
if not options.master_password:
|
||||
options.master_password = ipa_generate_password()
|
||||
if not master_password:
|
||||
master_password = ipa_generate_password()
|
||||
|
||||
module.exit_json(changed=True,
|
||||
password=options.master_password)
|
||||
password=master_password)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -38,23 +38,25 @@ description:
|
||||
Promote openldap.conf
|
||||
options:
|
||||
setup_kra:
|
||||
description:
|
||||
required: no
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
config_setup_ca:
|
||||
description:
|
||||
required: yes
|
||||
description: The config setup_ca setting
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -65,23 +67,30 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, redirect_stdout, promote_openldap_conf
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -90,30 +99,25 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
config_setup_ca = ansible_module.params.get('config_setup_ca')
|
||||
installer.setup_ca = config_setup_ca
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
@@ -125,7 +129,6 @@ def main():
|
||||
remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
@@ -137,5 +140,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,23 +38,25 @@ description:
|
||||
Promote sssd
|
||||
options:
|
||||
setup_kra:
|
||||
description:
|
||||
required: no
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
config_setup_ca:
|
||||
description:
|
||||
required: yes
|
||||
description: The config setup_ca setting
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -65,23 +67,30 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, redirect_stdout, promote_sssd
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -90,29 +99,25 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
config_setup_ca = ansible_module.params.get('config_setup_ca')
|
||||
installer.setup_ca = config_setup_ca
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
@@ -124,7 +129,6 @@ def main():
|
||||
remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
@@ -136,5 +140,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -37,6 +37,38 @@ short description: Restart KDC
|
||||
description:
|
||||
Restart KDC
|
||||
options:
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_file:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,30 +79,35 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths, sysrestore,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, service,
|
||||
krbinstance
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
#_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -79,36 +116,28 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
#pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
#pkinit_pkcs12_info = installer._pkinit_pkcs12_info
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -117,7 +146,6 @@ def main():
|
||||
config.dirman_password = dirman_password
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
@@ -144,5 +172,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,23 +38,41 @@ description:
|
||||
Setup adtrust
|
||||
options:
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
enable_compat:
|
||||
description: Enable support for trusted domains for old clients
|
||||
required: yes
|
||||
rid_base:
|
||||
description: Start value for mapping UIDs and GIDs to RIDs
|
||||
required: yes
|
||||
secondary_rid_base:
|
||||
description:
|
||||
Start value of the secondary range for mapping UIDs and GIDs to RIDs
|
||||
required: yes
|
||||
adtrust_netbios_name:
|
||||
description: The adtrust netbios_name setting
|
||||
required: no
|
||||
adtrust_reset_netbios_name:
|
||||
description: The adtrust reset_netbios_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
setup_ca:
|
||||
description:
|
||||
required: yes
|
||||
description: Configure a dogtag CA
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -65,30 +83,37 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths, sysrestore,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, adtrust
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### ad trust ###
|
||||
# ad trust
|
||||
enable_compat=dict(required=False, type='bool', default=False),
|
||||
rid_base=dict(required=False, type='int'),
|
||||
secondary_rid_base=dict(required=False, type='int'),
|
||||
### additional ###
|
||||
# additional
|
||||
adtrust_netbios_name=dict(required=True),
|
||||
adtrust_reset_netbios_name=dict(required=True, type='bool'),
|
||||
### additional ###
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
setup_ca=dict(required=True),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -97,34 +122,34 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### ad trust ###
|
||||
# ad trust
|
||||
options.enable_compat = ansible_module.params.get('enable_compat')
|
||||
options.rid_base = ansible_module.params.get('rid_base')
|
||||
options.secondary_rid_base = ansible_module.params.get('secondary_rid_base') ### additional ###
|
||||
options.secondary_rid_base = ansible_module.params.get(
|
||||
'secondary_rid_base')
|
||||
# additional
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
adtrust.netbios_name = ansible_module.params.get('adtrust_netbios_name')
|
||||
adtrust.reset_netbios_name = \
|
||||
ansible_module.params.get('adtrust_reset_netbios_name')
|
||||
adtrust.reset_netbios_name = ansible_module.params.get(
|
||||
'adtrust_reset_netbios_name')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
@@ -135,7 +160,6 @@ def main():
|
||||
remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
api.Backend.ldap2.connect()
|
||||
@@ -149,5 +173,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -37,59 +37,67 @@ short description: Setup CA
|
||||
description:
|
||||
Setup CA
|
||||
options:
|
||||
pki_config_override:
|
||||
description: Path to ini file with config overrides
|
||||
required: yes
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description:
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_ca_file:
|
||||
description:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_kra_enabled:
|
||||
description: The installer _kra_enabled setting
|
||||
required: yes
|
||||
_kra_host_name:
|
||||
description: The installer _kra_host_name setting
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
_ca_subject:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _ca_subject setting
|
||||
required: no
|
||||
_subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _subject_base setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
config_setup_ca:
|
||||
description:
|
||||
required: yes
|
||||
description: The config setup_ca setting
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
config_ca_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
config_ips:
|
||||
description:
|
||||
description: The config ips setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
@@ -101,26 +109,38 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, ca,
|
||||
custodiainstance
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
pki_config_override=dict(required=False),
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_kra_host_name=dict(required=False),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
_pkinit_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
@@ -129,7 +149,7 @@ def main():
|
||||
config_ca_host_name=dict(required=True),
|
||||
config_ips=dict(required=False, type='list', default=[]),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -138,22 +158,29 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# basic
|
||||
options.pki_config_override = ansible_module.params.get(
|
||||
'pki_config_override')
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
installer._dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
installer._pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
kra_host_name = ansible_module.params.get('_kra_host_name')
|
||||
installer._dirsrv_pkcs12_info = ansible_module.params.get(
|
||||
'_dirsrv_pkcs12_info')
|
||||
installer._pkinit_pkcs12_info = ansible_module.params.get(
|
||||
'_pkinit_pkcs12_info')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||
if options._ca_subject is not None:
|
||||
@@ -163,21 +190,17 @@ def main():
|
||||
options._subject_base = DN(options._subject_base)
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
config_setup_ca = ansible_module.params.get('config_setup_ca')
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
config_ca_host_name = ansible_module.params.get('config_ca_host_name')
|
||||
config_ips = ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
"config_ips")
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
pkinit_pkcs12_info = installer._pkinit_pkcs12_info
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -190,17 +213,18 @@ def main():
|
||||
config.ca_host_name = config_ca_host_name
|
||||
config.ips = config_ips
|
||||
config.promote = options.promote
|
||||
config.kra_enabled = kra_enabled
|
||||
config.kra_host_name = kra_host_name
|
||||
|
||||
remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA)
|
||||
options._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
# There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or
|
||||
# ntpinstance
|
||||
api.Backend.ldap2.connect()
|
||||
#conn.connect(ccache=ccache)
|
||||
# conn.connect(ccache=ccache)
|
||||
|
||||
ansible_log.debug("-- INSTALL CA --")
|
||||
|
||||
@@ -213,7 +237,10 @@ def main():
|
||||
if not hasattr(custodiainstance, "get_custodia_instance"):
|
||||
ca.install(False, config, options)
|
||||
else:
|
||||
if ca_enabled:
|
||||
if kra_enabled:
|
||||
# A KRA peer always provides a CA, too.
|
||||
mode = custodiainstance.CustodiaModes.KRA_PEER
|
||||
elif ca_enabled:
|
||||
mode = custodiainstance.CustodiaModes.CA_PEER
|
||||
else:
|
||||
mode = custodiainstance.CustodiaModes.MASTER_PEER
|
||||
@@ -225,5 +252,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -48,13 +48,16 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, redirect_stdout, configure_certmonger
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -62,8 +65,6 @@ def main():
|
||||
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
ansible_log.debug("-- CONFIGURE_CERTMONGER --")
|
||||
|
||||
@@ -74,5 +75,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,38 +38,49 @@ description:
|
||||
Setup custodia
|
||||
options:
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_ca_file:
|
||||
description:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_kra_enabled:
|
||||
description: The installer _kra_enabled setting
|
||||
required: yes
|
||||
_kra_host_name:
|
||||
description: The installer _kra_host_name setting
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -80,30 +91,38 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, custodiainstance
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_kra_host_name=dict(required=False),
|
||||
_pkinit_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -112,36 +131,34 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
options._pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
kra_host_name = ansible_module.params.get('_kra_host_name')
|
||||
options._pkinit_pkcs12_info = ansible_module.params.get(
|
||||
'_pkinit_pkcs12_info')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
pkinit_pkcs12_info = installer._pkinit_pkcs12_info
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -149,9 +166,10 @@ def main():
|
||||
config = gen_ReplicaConfig()
|
||||
config.dirman_password = dirman_password
|
||||
config.promote = installer.promote
|
||||
config.kra_enabled = kra_enabled
|
||||
config.kra_host_name = kra_host_name
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
@@ -167,14 +185,18 @@ def main():
|
||||
if not hasattr(custodiainstance, "get_custodia_instance"):
|
||||
custodia = custodiainstance.CustodiaInstance(config.host_name,
|
||||
config.realm_name)
|
||||
if promote:
|
||||
if promote and \
|
||||
hasattr(custodiainstance.CustodiaInstance, "create_replica"):
|
||||
ansible_log.debug("-- CUSTODIA CREATE_REPLICA --")
|
||||
custodia.create_replica(config.master_host_name)
|
||||
else:
|
||||
ansible_log.debug("-- CUSTODIA CREATE_INSTANCE --")
|
||||
custodia.create_instance()
|
||||
else:
|
||||
if ca_enabled:
|
||||
if kra_enabled:
|
||||
# A KRA peer always provides a CA, too.
|
||||
mode = custodiainstance.CustodiaModes.KRA_PEER
|
||||
elif ca_enabled:
|
||||
mode = custodiainstance.CustodiaModes.CA_PEER
|
||||
else:
|
||||
mode = custodiainstance.CustodiaModes.MASTER_PEER
|
||||
@@ -185,5 +207,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,26 +38,46 @@ description:
|
||||
Setup DNS
|
||||
options:
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
zonemgr:
|
||||
description: DNS zone manager e-mail address. Defaults to hostmaster@DOMAIN
|
||||
required: yes
|
||||
forwarders:
|
||||
description: Add DNS forwarders
|
||||
required: yes
|
||||
forward_policy:
|
||||
description: DNS forwarding policy for global forwarders
|
||||
required: yes
|
||||
no_dnssec_validation:
|
||||
description: Disable DNSSEC validation
|
||||
required: yes
|
||||
dns_ip_addresses:
|
||||
description: The dns ip_addresses setting
|
||||
required: no
|
||||
dns_reverse_zones:
|
||||
description: The dns reverse_zones setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
setup_ca:
|
||||
description:
|
||||
required: yes
|
||||
description: Configure a dogtag CA
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -68,30 +88,40 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, dns,
|
||||
ansible_module_get_parsed_ip_addresses
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
setup_dns=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### dns ###
|
||||
# dns
|
||||
zonemgr=dict(required=False),
|
||||
forwarders=dict(required=False, type='list', default=[]),
|
||||
forward_policy=dict(default=None, choices=['first', 'only']),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
### additional ###
|
||||
# additional
|
||||
dns_ip_addresses=dict(required=True, type='list'),
|
||||
dns_reverse_zones=dict(required=True, type='list'),
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -100,35 +130,34 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### dns ###
|
||||
# dns
|
||||
options.zonemgr = ansible_module.params.get('zonemgr')
|
||||
options.forwarders = ansible_module.params.get('forwarders')
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validationdnssec_validation')
|
||||
### additional ###
|
||||
# additional
|
||||
dns.ip_addresses = ansible_module_get_parsed_ip_addresses(
|
||||
ansible_module, 'dns_ip_addresses')
|
||||
dns.reverse_zones = ansible_module.params.get('dns_reverse_zones')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
@@ -139,7 +168,6 @@ def main():
|
||||
remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
# There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or
|
||||
@@ -158,5 +186,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -45,7 +45,7 @@ options:
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: no
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
@@ -56,82 +56,86 @@ options:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ca_cert_files:
|
||||
description: List of iles containing CA certificates for the service certificate files
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
dirserv_cert_files:
|
||||
description:
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
force_join:
|
||||
description:
|
||||
description: Force client enrollment even if already enrolled
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
server:
|
||||
description:
|
||||
required: yes
|
||||
description: Fully qualified name of IPA server to enroll to
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
installer_ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer ccache setting
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description:
|
||||
required: yes
|
||||
_kra_enabled:
|
||||
description:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description:
|
||||
required: yes
|
||||
_http_pkcs12_info:
|
||||
description:
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
_add_to_ipaservers:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _add_to_ipaservers setting
|
||||
required: no
|
||||
_ca_subject:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _ca_subject setting
|
||||
required: no
|
||||
_subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _subject_base setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
config_setup_ca:
|
||||
description:
|
||||
required: yes
|
||||
description: The config setup_ca setting
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
config_ca_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
config_ips:
|
||||
description:
|
||||
description: The config ips setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
@@ -143,13 +147,23 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths, sysrestore,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, redirect_stdout, ipaldap,
|
||||
install_replica_ds, install_dns_records, ntpinstance, ScriptError
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=False, no_log=True),
|
||||
password=dict(required=False, no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
@@ -158,30 +172,27 @@ def main():
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool'),
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
setup_dns=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool', default=False),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
### client ###
|
||||
# client
|
||||
force_join=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
# additional
|
||||
server=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
installer_ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
_add_to_ipaservers=dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
@@ -190,7 +201,7 @@ def main():
|
||||
config_ca_host_name=dict(required=True),
|
||||
config_ips=dict(required=False, type='list', default=[]),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -209,18 +220,19 @@ def main():
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
### ssl certificate ###
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
# ssl certificate
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
### client ###
|
||||
# client
|
||||
options.force_join = ansible_module.params.get('force_join')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.external_ca = ansible_module.params.get('external_ca')
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
@@ -228,34 +240,33 @@ def main():
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options.ca_subject = ansible_module.params.get('ca_subject')
|
||||
### additional ###
|
||||
#options._host_name_overridden = ansible_module.params.get(
|
||||
# '_hostname_overridden')
|
||||
# additional
|
||||
# options._host_name_overridden = ansible_module.params.get(
|
||||
# '_hostname_overridden')
|
||||
options.server = ansible_module.params.get('server')
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
http_pkcs12_info = ansible_module.params.get('_http_pkcs12_info')
|
||||
pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options._add_to_ipaservers = ansible_module.params.get('_add_to_ipaservers')
|
||||
options._add_to_ipaservers = ansible_module.params.get(
|
||||
'_add_to_ipaservers')
|
||||
|
||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||
options._subject_base = ansible_module.params.get('_subject_base')
|
||||
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
config_setup_ca = ansible_module.params.get('config_setup_ca')
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
config_ca_host_name = ansible_module.params.get('config_ca_host_name')
|
||||
config_ips = ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
"config_ips")
|
||||
@@ -263,7 +274,6 @@ def main():
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
@@ -338,6 +348,9 @@ def main():
|
||||
if ntpinstance is not None:
|
||||
ntpinstance.ntp_ldap_enable(config.host_name, ds.suffix,
|
||||
remote_api.env.realm)
|
||||
|
||||
except (ScriptError, RuntimeError) as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
finally:
|
||||
if conn.isconnected():
|
||||
ansible_log.debug("-- DISCONNECT --")
|
||||
@@ -349,5 +362,6 @@ def main():
|
||||
ds_suffix=str(ds.suffix),
|
||||
ds_ca_subject=str(ds.ca_subject))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,41 +38,46 @@ description:
|
||||
Setup HTTP
|
||||
options:
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
config_ca_host_name:
|
||||
description: The config ca_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_ca_file:
|
||||
description:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_http_pkcs12_info:
|
||||
description:
|
||||
description: The installer _http_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -83,29 +88,38 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths, sysrestore,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, create_ipa_conf,
|
||||
install_http
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_http_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -118,17 +132,17 @@ def main():
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.no_ui_redirect = ansible_module.params.get('no_ui_redirect')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ca_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
http_pkcs12_info = ansible_module.params.get('_http_pkcs12_info')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
@@ -137,11 +151,9 @@ def main():
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
@@ -151,12 +163,12 @@ def main():
|
||||
config.subject_base = options.subject_base
|
||||
config.dirman_password = dirman_password
|
||||
config.setup_ca = options.setup_ca
|
||||
#config.master_host_name = master_host_name
|
||||
# config.master_host_name = master_host_name
|
||||
config.ca_host_name = ca_host_name
|
||||
config.promote = installer.promote
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
# installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
@@ -221,5 +233,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -45,7 +45,7 @@ options:
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: no
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
@@ -56,22 +56,73 @@ options:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ca_cert_files:
|
||||
description: List of iles containing CA certificates for the service certificate files
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
pki_config_override:
|
||||
description: Path to ini file with config overrides
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
external_ca:
|
||||
description:
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
force_join:
|
||||
description: Force client enrollment even if already enrolled
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
server:
|
||||
description: Fully qualified name of IPA server to enroll to
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description: The local ccache
|
||||
required: no
|
||||
installer_ccache:
|
||||
description: The installer ccache setting
|
||||
required: no
|
||||
_ca_enabled:
|
||||
description: The installer _ca_enabled setting
|
||||
required: yes
|
||||
_kra_enabled:
|
||||
description: The installer _kra_enabled setting
|
||||
required: yes
|
||||
_kra_host_name:
|
||||
description: The installer _kra_host_name setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
_add_to_ipaservers:
|
||||
description: The installer _add_to_ipaservers setting
|
||||
required: no
|
||||
_ca_subject:
|
||||
description: The installer _ca_subject setting
|
||||
required: no
|
||||
_subject_base:
|
||||
description: The installer _subject_base setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -82,13 +133,22 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, custodiainstance,
|
||||
kra
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=False, no_log=True),
|
||||
password=dict(required=False, no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
@@ -97,33 +157,32 @@ def main():
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
pki_config_override=dict(required=False),
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool'),
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
setup_dns=dict(required=False, type='bool'),
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
### client ###
|
||||
# client
|
||||
force_join=dict(required=False, type='bool'),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
# additional
|
||||
server=dict(required=True),
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
installer_ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_kra_enabled=dict(required=False, type='bool'),
|
||||
_dirsrv_pkcs12_info = dict(required=False),
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_kra_host_name=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
_add_to_ipaservers=dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -142,16 +201,18 @@ def main():
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
### server ###
|
||||
options.pki_config_override = ansible_module.params.get(
|
||||
'pki_config_override')
|
||||
# server
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
### client ###
|
||||
# client
|
||||
options.force_join = ansible_module.params.get('force_join')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.external_ca = ansible_module.params.get('external_ca')
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
@@ -159,7 +220,7 @@ def main():
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options.ca_subject = ansible_module.params.get('ca_subject')
|
||||
### dns ###
|
||||
# dns
|
||||
options.reverse_zones = ansible_module.params.get('reverse_zones')
|
||||
options.no_reverse = ansible_module.params.get('no_reverse')
|
||||
options.auto_reverse = ansible_module.params.get('auto_reverse')
|
||||
@@ -167,38 +228,32 @@ def main():
|
||||
options.no_forwarders = ansible_module.params.get('no_forwarders')
|
||||
options.auto_forwarders = ansible_module.params.get('auto_forwarders')
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
### additional ###
|
||||
# additional
|
||||
options.server = ansible_module.params.get('server')
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
#os.environ['KRB5CCNAME'] = ccache
|
||||
# os.environ['KRB5CCNAME'] = ccache
|
||||
os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
kra_enabled = ansible_module.params.get('_kra_enabled')
|
||||
|
||||
dirsrv_pkcs12_info = ansible_module.params.get('_dirsrv_pkcs12_info')
|
||||
http_pkcs12_info = ansible_module.params.get('_http_pkcs12_info')
|
||||
pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
kra_host_name = ansible_module.params.get('_kra_host_name')
|
||||
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
options._add_to_ipaservers = ansible_module.params.get('_add_to_ipaservers')
|
||||
options._add_to_ipaservers = ansible_module.params.get(
|
||||
'_add_to_ipaservers')
|
||||
|
||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||
options._subject_base = ansible_module.params.get('_subject_base')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -206,12 +261,13 @@ def main():
|
||||
config = gen_ReplicaConfig()
|
||||
config.subject_base = options.subject_base
|
||||
config.promote = installer.promote
|
||||
config.kra_enabled = kra_enabled
|
||||
config.kra_host_name = kra_host_name
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
# ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
ansible_log.debug("-- INSTALL KRA --")
|
||||
@@ -231,5 +287,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,29 +38,31 @@ description:
|
||||
Setup KRB
|
||||
options:
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_pkinit_pkcs12_info:
|
||||
description:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -71,25 +73,33 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths, sysrestore,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, api, redirect_stdout, install_krb
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_pkinit_pkcs12_info=dict(required=False),
|
||||
_top_dir=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -98,26 +108,27 @@ def main():
|
||||
# get parameters #
|
||||
|
||||
options = installer
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
config_master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
# additional
|
||||
config_master_host_name = ansible_module.params.get(
|
||||
'config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
installer._pkinit_pkcs12_info = ansible_module.params.get('_pkinit_pkcs12_info')
|
||||
installer._pkinit_pkcs12_info = ansible_module.params.get(
|
||||
'_pkinit_pkcs12_info')
|
||||
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
@@ -132,10 +143,6 @@ def main():
|
||||
config.master_host_name = config_master_host_name
|
||||
config.subject_base = options.subject_base
|
||||
|
||||
remote_api = gen_remote_api(config.master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
# There is a api.Backend.ldap2.connect call somewhere in ca, ds, dns or
|
||||
@@ -170,5 +177,6 @@ def main():
|
||||
ansible_module.exit_json(changed=True,
|
||||
config_master_host_name=config.master_host_name)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -38,38 +38,37 @@ description:
|
||||
Setup OTPD
|
||||
options:
|
||||
setup_ca:
|
||||
description:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_kra:
|
||||
description:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
required: yes
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: no
|
||||
config_master_host_name:
|
||||
description:
|
||||
required: yes
|
||||
description: The config master_host_name setting
|
||||
required: no
|
||||
ccache:
|
||||
description:
|
||||
required: yes
|
||||
_ca_enabled:
|
||||
description:
|
||||
required: yes
|
||||
description: The local ccache
|
||||
required: no
|
||||
_ca_file:
|
||||
description:
|
||||
description: The installer _ca_file setting
|
||||
required: yes
|
||||
_top_dir:
|
||||
description:
|
||||
required: yes
|
||||
description: The installer _top_dir setting
|
||||
required: no
|
||||
dirman_password:
|
||||
description:
|
||||
required: yes
|
||||
description: Directory Manager (master) password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -80,28 +79,35 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, installer, DN, paths,
|
||||
gen_env_boostrap_finalize_core, constants, api_bootstrap_finalize,
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, otpdinstance,
|
||||
ipautil
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#### server ###
|
||||
argument_spec=dict(
|
||||
# server
|
||||
setup_ca=dict(required=False, type='bool'),
|
||||
setup_kra=dict(required=False, type='bool'),
|
||||
no_pkinit=dict(required=False, type='bool'),
|
||||
no_ui_redirect=dict(required=False, type='bool'),
|
||||
#### certificate system ###
|
||||
# certificate system
|
||||
subject_base=dict(required=True),
|
||||
#### additional ###
|
||||
# additional
|
||||
config_master_host_name=dict(required=True),
|
||||
ccache=dict(required=True),
|
||||
_ca_enabled=dict(required=False, type='bool'),
|
||||
_ca_file=dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_top_dir=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
@@ -113,29 +119,24 @@ def main():
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
if options.subject_base is not None:
|
||||
options.subject_base = DN(options.subject_base)
|
||||
### additional ###
|
||||
# additional
|
||||
master_host_name = ansible_module.params.get('config_master_host_name')
|
||||
ccache = ansible_module.params.get('ccache')
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
#os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
#installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
ca_enabled = ansible_module.params.get('_ca_enabled')
|
||||
# os.environ['KRB5CCNAME'] = ansible_module.params.get('installer_ccache')
|
||||
# installer._ccache = ansible_module.params.get('installer_ccache')
|
||||
options._top_dir = ansible_module.params.get('_top_dir')
|
||||
dirman_password = ansible_module.params.get('dirman_password')
|
||||
|
||||
# init #
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
ansible_log.debug("== INSTALL ==")
|
||||
|
||||
options = installer
|
||||
promote = installer.promote
|
||||
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
@@ -144,7 +145,6 @@ def main():
|
||||
config.dirman_password = dirman_password
|
||||
|
||||
remote_api = gen_remote_api(master_host_name, paths.ETC_IPA)
|
||||
#installer._remote_api = remote_api
|
||||
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
@@ -154,7 +154,6 @@ def main():
|
||||
api.Backend.ldap2.connect()
|
||||
conn.connect(ccache=ccache)
|
||||
|
||||
cafile = paths.IPA_CA_CRT
|
||||
with redirect_stdout(ansible_log):
|
||||
ansible_log.debug("-- INSTALL_OTPD --")
|
||||
|
||||
@@ -167,5 +166,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -31,9 +31,91 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipareplica_test
|
||||
short description:
|
||||
description:
|
||||
short description: IPA replica deployment tests
|
||||
description: IPA replica deployment tests
|
||||
options:
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: yes
|
||||
servers:
|
||||
description: Fully qualified name of IPA servers to enroll to
|
||||
required: yes
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: yes
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ca_cert_files:
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
hidden_replica:
|
||||
description: Install a hidden replica
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
http_cert_files:
|
||||
description:
|
||||
File containing the Apache Server SSL certificate and private key
|
||||
required: yes
|
||||
pkinit_cert_files:
|
||||
description:
|
||||
File containing the Kerberos KDC SSL certificate and private key
|
||||
required: yes
|
||||
no_ntp:
|
||||
description: Do not configure ntp
|
||||
required: yes
|
||||
ntp_servers:
|
||||
description: ntp servers to use
|
||||
required: yes
|
||||
ntp_pool:
|
||||
description: ntp server pool to use
|
||||
required: yes
|
||||
no_reverse:
|
||||
description: Do not create new reverse DNS zone
|
||||
required: yes
|
||||
auto_reverse:
|
||||
description: Create necessary reverse zones
|
||||
required: yes
|
||||
forwarders:
|
||||
description: Add DNS forwarders
|
||||
required: yes
|
||||
no_forwarders:
|
||||
description: Do not add any DNS forwarders, use root servers instead
|
||||
required: yes
|
||||
auto_forwarders:
|
||||
description: Use DNS forwarders configured in /etc/resolv.conf
|
||||
required: yes
|
||||
forward_policy:
|
||||
description: DNS forwarding policy for global forwarders
|
||||
required: yes
|
||||
no_dnssec_validation:
|
||||
description: Disable DNSSEC validation
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -45,19 +127,24 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
import sys
|
||||
import logging
|
||||
import tempfile, shutil
|
||||
import inspect
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_replica import *
|
||||
from ansible.module_utils.ansible_ipa_replica import (
|
||||
AnsibleModuleLog, options, installer, paths, sysrestore,
|
||||
ansible_module_get_parsed_ip_addresses, service,
|
||||
redirect_stdout, create_ipa_conf, ipautil,
|
||||
x509, validate_domain_name, common_check,
|
||||
IPA_PYTHON_VERSION
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
#dm_password=dict(required=False, no_log=True),
|
||||
#password=dict(required=False, no_log=True),
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
# dm_password=dict(required=False, no_log=True),
|
||||
# password=dict(required=False, no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
domain=dict(required=False),
|
||||
servers=dict(required=False, type='list', default=[]),
|
||||
@@ -65,21 +152,21 @@ def main():
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
hidden_replica=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool', default=False),
|
||||
setup_kra=dict(required=False, type='bool', default=False),
|
||||
setup_dns=dict(required=False, type='bool', default=False),
|
||||
no_pkinit=dict(required=False, type='bool', default=False),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
http_cert_files=dict(required=False, type='list', default=[]),
|
||||
pkinit_cert_files=dict(required=False, type='list', default=[]),
|
||||
### client ###
|
||||
# client
|
||||
no_ntp=dict(required=False, type='bool', default=False),
|
||||
ntp_servers=dict(required=False, type='list', default=[]),
|
||||
ntp_pool=dict(required=False),
|
||||
### dns ###
|
||||
# dns
|
||||
no_reverse=dict(required=False, type='bool', default=False),
|
||||
auto_reverse=dict(required=False, type='bool', default=False),
|
||||
forwarders=dict(required=False, type='list', default=[]),
|
||||
@@ -96,10 +183,10 @@ def main():
|
||||
|
||||
# get parameters #
|
||||
|
||||
### basic ###
|
||||
#options.dm_password = ansible_module.params.get('dm_password')
|
||||
##options.password = ansible_module.params.get('password')
|
||||
#options.password = options.dm_password
|
||||
# basic
|
||||
# options.dm_password = ansible_module.params.get('dm_password')
|
||||
# # options.password = ansible_module.params.get('password')
|
||||
# options.password = options.dm_password
|
||||
options.ip_addresses = ansible_module_get_parsed_ip_addresses(
|
||||
ansible_module)
|
||||
options.domain_name = ansible_module.params.get('domain')
|
||||
@@ -108,21 +195,22 @@ def main():
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.hidden_replica = ansible_module.params.get('hidden_replica')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
### ssl certificate ###
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
# ssl certificate
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
options.http_cert_files = ansible_module.params.get('http_cert_files')
|
||||
options.pkinit_cert_files = ansible_module.params.get('pkinit_cert_files')
|
||||
### client ###
|
||||
# client
|
||||
options.no_ntp = ansible_module.params.get('no_ntp')
|
||||
options.ntp_servers = ansible_module.params.get('ntp_servers')
|
||||
options.ntp_pool = ansible_module.params.get('ntp_pool')
|
||||
### dns ###
|
||||
# dns
|
||||
options.no_reverse = ansible_module.params.get('no_reverse')
|
||||
options.auto_reverse = ansible_module.params.get('auto_reverse')
|
||||
options.forwarders = ansible_module.params.get('forwarders')
|
||||
@@ -141,12 +229,12 @@ def main():
|
||||
else:
|
||||
installer.server = None
|
||||
# TODO: Kills ipa-client-install
|
||||
#if installer.replica_file is None:
|
||||
# installer.password = installer.admin_password
|
||||
#else:
|
||||
# installer.password = installer.dm_password
|
||||
# if installer.replica_file is None:
|
||||
# installer.password = installer.admin_password
|
||||
# else:
|
||||
# installer.password = installer.dm_password
|
||||
|
||||
#installer._ccache = os.environ.get('KRB5CCNAME')
|
||||
# installer._ccache = os.environ.get('KRB5CCNAME')
|
||||
|
||||
# If not defined, set domain from server name
|
||||
if installer.domain_name is None and installer.server is not None:
|
||||
@@ -161,17 +249,17 @@ def main():
|
||||
|
||||
# version specific tests #
|
||||
|
||||
#if options.setup_adtrust and not adtrust_imported:
|
||||
# #if "adtrust" not in options._allow_missing:
|
||||
# if options.setup_adtrust and not adtrust_imported:
|
||||
# # if "adtrust" not in options._allow_missing:
|
||||
# ansible_module.fail_json(msg="adtrust can not be imported")
|
||||
# #else:
|
||||
# # else:
|
||||
# # options.setup_adtrust = False
|
||||
# # ansible_module.warn(msg="adtrust is not supported, disabling")
|
||||
|
||||
#if options.setup_kra and not kra_imported:
|
||||
# #if "kra" not in options._allow_missing:
|
||||
# if options.setup_kra and not kra_imported:
|
||||
# # if "kra" not in options._allow_missing:
|
||||
# ansible_module.fail_json(msg="kra can not be imported")
|
||||
# #else:
|
||||
# # else:
|
||||
# # options.setup_kra = False
|
||||
# # ansible_module.warn(msg="kra is not supported, disabling")
|
||||
|
||||
@@ -179,6 +267,14 @@ def main():
|
||||
ansible_module.fail_json(
|
||||
msg="Hidden replica is not supported in this version.")
|
||||
|
||||
# We need to point to the master in ipa default conf when certmonger
|
||||
# asks for HTTP certificate in newer ipa versions. In these versions
|
||||
# create_ipa_conf has the additional master argument.
|
||||
change_master_for_certmonger = False
|
||||
argspec = inspect.getargspec(create_ipa_conf)
|
||||
if "master" in argspec.args:
|
||||
change_master_for_certmonger = True
|
||||
|
||||
# From ipa installer classes
|
||||
|
||||
# pkinit is not supported on DL0, don't allow related options
|
||||
@@ -264,32 +360,38 @@ def main():
|
||||
msg="You must specify at least one of --forwarder, "
|
||||
"--auto-forwarders, or --no-forwarders options")
|
||||
|
||||
if installer.dirsrv_config_file is not None and not os.path.exists(installer.dirsrv_config_file):
|
||||
ansible_module.fail_json(msg="File %s does not exist." % installer.dirsrv_config_file)
|
||||
if installer.dirsrv_config_file is not None and \
|
||||
not os.path.exists(installer.dirsrv_config_file):
|
||||
ansible_module.fail_json(
|
||||
msg="File %s does not exist." % installer.dirsrv_config_file)
|
||||
|
||||
if installer.ca_cert_files is not None:
|
||||
if not isinstance(installer.ca_cert_files, list):
|
||||
ansible_module.fail_json(msg="Expected list, got {!r}".format(installer.ca_cert_files))
|
||||
ansible_module.fail_json(
|
||||
msg="Expected list, got {!r}".format(installer.ca_cert_files))
|
||||
for cert in installer.ca_cert_files:
|
||||
if not os.path.exists(cert):
|
||||
ansible_module.fail_json(msg="'%s' does not exist" % cert)
|
||||
if not os.path.isfile(cert):
|
||||
ansible_module.fail_json(msg="'%s' is not a file" % cert)
|
||||
if not os.path.isabs(cert):
|
||||
ansible_module.fail_json(msg="'%s' is not an absolute file path" % cert)
|
||||
ansible_module.fail_json(
|
||||
msg="'%s' is not an absolute file path" % cert)
|
||||
|
||||
try:
|
||||
x509.load_certificate_from_file(cert)
|
||||
except Exception:
|
||||
ansible_module.fail_json(msg="'%s' is not a valid certificate file" % cert)
|
||||
ansible_module.fail_json(
|
||||
msg="'%s' is not a valid certificate file" % cert)
|
||||
|
||||
if installer.ip_addresses is not None:
|
||||
for value in installer.ip_addresses:
|
||||
try:
|
||||
CheckedIPAddress(value)
|
||||
ipautil.CheckedIPAddress(value)
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg="invalid IP address {0}: {1}".format(
|
||||
value, e))
|
||||
ansible_module.fail_json(
|
||||
msg="invalid IP address {0}: {1}".format(
|
||||
value, e))
|
||||
|
||||
if installer.domain_name is not None:
|
||||
validate_domain_name(installer.domain_name)
|
||||
@@ -302,7 +404,7 @@ def main():
|
||||
try:
|
||||
with redirect_stdout(ansible_log):
|
||||
common_check(options.no_ntp)
|
||||
except Exception as msg: #ScriptError as msg:
|
||||
except Exception as msg: # ScriptError as msg:
|
||||
_msg = str(msg)
|
||||
if "server is already configured" in _msg:
|
||||
ansible_module.exit_json(changed=False,
|
||||
@@ -318,8 +420,8 @@ def main():
|
||||
client_enrolled = client_fstore.has_files()
|
||||
|
||||
if not client_enrolled:
|
||||
## One-step replica installation
|
||||
#if options.dm_password and options.password:
|
||||
# # One-step replica installation
|
||||
# if options.dm_password and options.password:
|
||||
# ansible_module.fail_json(
|
||||
# msg="--password and --admin-password options are "
|
||||
# "mutually exclusive")
|
||||
@@ -332,19 +434,22 @@ def main():
|
||||
|
||||
# done #
|
||||
|
||||
ansible_module.exit_json(changed=False,
|
||||
ipa_python_version=IPA_PYTHON_VERSION,
|
||||
### basic ###
|
||||
domain=options.domain_name,
|
||||
realm=options.realm_name,
|
||||
hostname=options.host_name,
|
||||
### server ###
|
||||
setup_adtrust=options.setup_adtrust,
|
||||
setup_kra=options.setup_kra,
|
||||
server=options.server,
|
||||
### additional ###
|
||||
client_enrolled=client_enrolled,
|
||||
ansible_module.exit_json(
|
||||
changed=False,
|
||||
ipa_python_version=IPA_PYTHON_VERSION,
|
||||
# basic
|
||||
domain=options.domain_name,
|
||||
realm=options.realm_name,
|
||||
hostname=options.host_name,
|
||||
# server
|
||||
setup_adtrust=options.setup_adtrust,
|
||||
setup_kra=options.setup_kra,
|
||||
server=options.server,
|
||||
# additional
|
||||
client_enrolled=client_enrolled,
|
||||
change_master_for_certmonger=change_master_for_certmonger,
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -22,10 +22,31 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import os
|
||||
__all__ = ["contextlib", "dnsexception", "dnsresolver", "dnsreversename",
|
||||
"parse_version", "IPAChangeConf",
|
||||
"certstore", "sysrestore", "ipa_generate_password", "kinit_keytab",
|
||||
"IPA_CA_TRUST_FLAGS", "EXTERNAL_CA_TRUST_FLAGS", "DN",
|
||||
"ScriptError", "services", "tasks", "constants", "errors", "rpc",
|
||||
"x509", "validate_domain_name",
|
||||
"no_matching_interface_for_ip_address_warning",
|
||||
"configure_krb5_conf", "purge_host_keytab", "adtrust",
|
||||
"bindinstance", "ca", "certs", "dns", "httpinstance", "kra",
|
||||
"otpdinstance", "custodiainstance", "service", "upgradeinstance",
|
||||
"find_providing_servers", "find_providing_server", "load_pkcs12",
|
||||
"is_ipa_configured", "ReplicationManager", "replica_conn_check",
|
||||
"install_replica_ds", "install_krb", "install_ca_cert",
|
||||
"install_http", "install_dns_records", "create_ipa_conf",
|
||||
"check_dirsrv", "check_dns_resolution", "configure_certmonger",
|
||||
"remove_replica_info_dir", "preserve_enrollment_state",
|
||||
"uninstall_client", "promote_sssd", "promote_openldap_conf",
|
||||
"rpc_client", "check_remote_fips_mode", "check_remote_version",
|
||||
"common_check", "current_domain_level",
|
||||
"check_domain_level_is_supported", "promotion_check_ipa_domain",
|
||||
"SSSDConfig", "CalledProcessError", "timeconf", "ntpinstance",
|
||||
"dnsname", "kernel_keyring", "krbinstance"]
|
||||
|
||||
import sys
|
||||
import logging
|
||||
import inspect
|
||||
from contextlib import contextmanager as contextlib_contextmanager
|
||||
|
||||
|
||||
@@ -33,7 +54,7 @@ from ipapython.version import NUM_VERSION, VERSION
|
||||
|
||||
if NUM_VERSION < 30201:
|
||||
# See ipapython/version.py
|
||||
IPA_MAJOR,IPA_MINOR,IPA_RELEASE = [ int(x) for x in VERSION.split(".", 2) ]
|
||||
IPA_MAJOR, IPA_MINOR, IPA_RELEASE = [int(x) for x in VERSION.split(".", 2)]
|
||||
IPA_PYTHON_VERSION = IPA_MAJOR*10000 + IPA_MINOR*100 + IPA_RELEASE
|
||||
else:
|
||||
IPA_PYTHON_VERSION = NUM_VERSION
|
||||
@@ -48,14 +69,8 @@ if NUM_VERSION >= 40600:
|
||||
import dns.name as dnsname
|
||||
import dns.resolver as dnsresolver
|
||||
import dns.reversename as dnsreversename
|
||||
import os
|
||||
import shutil
|
||||
import socket
|
||||
import tempfile
|
||||
import traceback
|
||||
|
||||
from pkg_resources import parse_version
|
||||
import six
|
||||
|
||||
from ipaclient.install.ipachangeconf import IPAChangeConf
|
||||
from ipalib.install import certstore, sysrestore
|
||||
@@ -93,21 +108,18 @@ if NUM_VERSION >= 40600:
|
||||
make_pkcs12_info, install_replica_ds, install_krb, install_ca_cert,
|
||||
install_http, install_dns_records, create_ipa_conf, check_dirsrv,
|
||||
check_dns_resolution, configure_certmonger, remove_replica_info_dir,
|
||||
#common_cleanup,
|
||||
# common_cleanup,
|
||||
preserve_enrollment_state, uninstall_client,
|
||||
promote_sssd, promote_openldap_conf, rpc_client,
|
||||
check_remote_fips_mode, check_remote_version, common_check,
|
||||
current_domain_level, check_domain_level_is_supported,
|
||||
#enroll_dl0_replica,
|
||||
#ensure_enrolled,
|
||||
# enroll_dl0_replica,
|
||||
# ensure_enrolled,
|
||||
promotion_check_ipa_domain
|
||||
)
|
||||
import SSSDConfig
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
try:
|
||||
from ipaclient.install import timeconf
|
||||
time_service = "chronyd"
|
||||
@@ -128,11 +140,12 @@ else:
|
||||
|
||||
|
||||
logger = logging.getLogger("ipa-server-install")
|
||||
#logger.setLevel(logging.DEBUG)
|
||||
# logger.setLevel(logging.DEBUG)
|
||||
standard_logging_setup(
|
||||
paths.IPAREPLICA_INSTALL_LOG, verbose=False, debug=False,
|
||||
filemode='a', console_format='%(message)s')
|
||||
|
||||
|
||||
@contextlib_contextmanager
|
||||
def redirect_stdout(f):
|
||||
sys.stdout = f
|
||||
@@ -162,7 +175,7 @@ class AnsibleModuleLog():
|
||||
pass
|
||||
|
||||
def log(self, msg):
|
||||
#self.write(msg+"\n")
|
||||
# self.write(msg+"\n")
|
||||
self.write(msg)
|
||||
|
||||
def debug(self, msg):
|
||||
@@ -173,7 +186,7 @@ class AnsibleModuleLog():
|
||||
|
||||
def write(self, msg):
|
||||
self.module.debug(msg)
|
||||
#self.module.warn(msg)
|
||||
# self.module.warn(msg)
|
||||
|
||||
|
||||
class installer_obj(object):
|
||||
@@ -195,33 +208,34 @@ class installer_obj(object):
|
||||
# others
|
||||
self._ccache = None
|
||||
self.password = None
|
||||
self.reverse_zones = [ ]
|
||||
#def _is_promote(self):
|
||||
# return self.replica_file is None
|
||||
#self.skip_conncheck = False
|
||||
self.reverse_zones = []
|
||||
# def _is_promote(self):
|
||||
# return self.replica_file is None
|
||||
# self.skip_conncheck = False
|
||||
self._replica_install = False
|
||||
#self.dnssec_master = False # future unknown
|
||||
#self.disable_dnssec_master = False # future unknown
|
||||
#self.domainlevel = MAX_DOMAIN_LEVEL # deprecated
|
||||
#self.domain_level = self.domainlevel # deprecated
|
||||
# self.dnssec_master = False # future unknown
|
||||
# self.disable_dnssec_master = False # future unknown
|
||||
# self.domainlevel = MAX_DOMAIN_LEVEL # deprecated
|
||||
# self.domain_level = self.domainlevel # deprecated
|
||||
self.interactive = False
|
||||
self.unattended = not self.interactive
|
||||
#self.promote = self.replica_file is None
|
||||
# self.promote = self.replica_file is None
|
||||
self.promote = True
|
||||
self.skip_schema_check = None
|
||||
|
||||
#def __getattribute__(self, attr):
|
||||
# value = super(installer_obj, self).__getattribute__(attr)
|
||||
# if not attr.startswith("--") and not attr.endswith("--"):
|
||||
# logger.debug(
|
||||
# " <-- Accessing installer.%s (%s)" % (attr, repr(value)))
|
||||
# return value
|
||||
# def __getattribute__(self, attr):
|
||||
# value = super(installer_obj, self).__getattribute__(attr)
|
||||
# if not attr.startswith("--") and not attr.endswith("--"):
|
||||
# logger.debug(
|
||||
# " <-- Accessing installer.%s (%s)" % (attr, repr(value)))
|
||||
# return value
|
||||
|
||||
def __getattr__(self, attr):
|
||||
logger.info(" --> ADDING missing installer.%s" % attr)
|
||||
logger.info(" --> ADDING missing installer.%s", attr)
|
||||
setattr(self, attr, None)
|
||||
return getattr(self, attr)
|
||||
|
||||
#def __setattr__(self, attr, value):
|
||||
# def __setattr__(self, attr, value):
|
||||
# logger.debug(" --> Setting installer.%s to %s" % (attr, repr(value)))
|
||||
# return super(installer_obj, self).__setattr__(attr, value)
|
||||
|
||||
@@ -240,7 +254,7 @@ options.kasp_db_file = None
|
||||
options.force = False
|
||||
|
||||
# ServerMasterInstall
|
||||
options.add_sids = True
|
||||
options.add_sids = False
|
||||
options.add_agents = False
|
||||
|
||||
# ServerReplicaInstall
|
||||
@@ -248,25 +262,10 @@ options.subject_base = None
|
||||
options.ca_subject = None
|
||||
|
||||
|
||||
def api_Backend_ldap2(host_name, setup_ca, connect=False):
|
||||
# we are sure we have the configuration file ready.
|
||||
cfg = dict(context='installer', confdir=paths.ETC_IPA, in_server=True,
|
||||
host=host_name,
|
||||
)
|
||||
if setup_ca:
|
||||
# we have an IPA-integrated CA
|
||||
cfg['ca_host'] = host_name
|
||||
|
||||
api.bootstrap(**cfg)
|
||||
api.finalize()
|
||||
if connect:
|
||||
api.Backend.ldap2.connect()
|
||||
|
||||
|
||||
def gen_env_boostrap_finalize_core(etc_ipa, default_config):
|
||||
env = Env()
|
||||
#env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None)
|
||||
#env._finalize_core(**dict(constants.DEFAULT_CONFIG))
|
||||
# env._bootstrap(context='installer', confdir=paths.ETC_IPA, log=None)
|
||||
# env._finalize_core(**dict(constants.DEFAULT_CONFIG))
|
||||
env._bootstrap(context='installer', confdir=etc_ipa, log=None)
|
||||
env._finalize_core(**dict(default_config))
|
||||
return env
|
||||
@@ -289,26 +288,27 @@ def gen_ReplicaConfig():
|
||||
def __init__(self, top_dir=None):
|
||||
super(ExtendedReplicaConfig, self).__init__(top_dir)
|
||||
|
||||
#def __getattribute__(self, attr):
|
||||
# def __getattribute__(self, attr):
|
||||
# value = super(ExtendedReplicaConfig, self).__getattribute__(attr)
|
||||
# if attr not in [ "__dict__", "knobs" ]:
|
||||
# logger.debug(" <== Accessing config.%s (%s)" % (attr, repr(value)))
|
||||
# if attr not in ["__dict__", "knobs"]:
|
||||
# logger.debug(" <== Accessing config.%s (%s)" %
|
||||
# (attr, repr(value)))
|
||||
# return value
|
||||
|
||||
def __getattr__(self, attr):
|
||||
logger.info(" ==> ADDING missing config.%s" % attr)
|
||||
logger.info(" ==> ADDING missing config.%s", attr)
|
||||
setattr(self, attr, None)
|
||||
return getattr(self, attr)
|
||||
|
||||
#def __setattr__(self, attr, value):
|
||||
# logger.debug(" ==> Setting config.%s to %s" % (attr, repr(value)))
|
||||
# return super(ExtendedReplicaConfig, self).__setattr__(attr, value)
|
||||
# def __setattr__(self, attr, value):
|
||||
# logger.debug(" ==> Setting config.%s to %s" % (attr, repr(value)))
|
||||
# return super(ExtendedReplicaConfig, self).__setattr__(attr, value)
|
||||
|
||||
def knobs(self):
|
||||
for name in self.__dict__:
|
||||
yield self, name
|
||||
|
||||
#config = ReplicaConfig()
|
||||
# config = ReplicaConfig()
|
||||
config = ExtendedReplicaConfig()
|
||||
config.realm_name = api.env.realm
|
||||
config.host_name = api.env.host
|
||||
@@ -321,45 +321,11 @@ def gen_ReplicaConfig():
|
||||
config.setup_kra = options.setup_kra
|
||||
config.dir = options._top_dir
|
||||
config.basedn = api.env.basedn
|
||||
#config.subject_base = options.subject_base
|
||||
# config.subject_base = options.subject_base
|
||||
|
||||
return config
|
||||
|
||||
|
||||
def ds_init_info(ansible_log, fstore, domainlevel, dirsrv_config_file,
|
||||
realm_name, host_name, domain_name, dm_password,
|
||||
idstart, idmax, subject_base, ca_subject,
|
||||
#no_hbac_allow,
|
||||
dirsrv_pkcs12_info, no_pkinit,
|
||||
external_cert_files, dirsrv_cert_files):
|
||||
|
||||
if not external_cert_files:
|
||||
ds = dsinstance.DsInstance(fstore=fstore, domainlevel=domainlevel,
|
||||
config_ldif=dirsrv_config_file)
|
||||
ds.set_output(ansible_log)
|
||||
|
||||
if dirsrv_cert_files:
|
||||
_dirsrv_pkcs12_info = dirsrv_pkcs12_info
|
||||
else:
|
||||
_dirsrv_pkcs12_info = None
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
ds.init_info(realm_name, host_name, domain_name, dm_password,
|
||||
subject_base, ca_subject, idstart, idmax,
|
||||
#hbac_allow=not no_hbac_allow,
|
||||
_dirsrv_pkcs12_info, setup_pkinit=not no_pkinit)
|
||||
else:
|
||||
ds = dsinstance.DsInstance(fstore=fstore, domainlevel=domainlevel)
|
||||
ds.set_output(ansible_log)
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
ds.init_info(realm_name, host_name, domain_name, dm_password,
|
||||
subject_base, ca_subject, 1101, 1100, None,
|
||||
setup_pkinit=not no_pkinit)
|
||||
|
||||
return ds
|
||||
|
||||
|
||||
def replica_ds_init_info(ansible_log,
|
||||
config, options, ca_is_configured, remote_api,
|
||||
ds_ca_subject, ca_file,
|
||||
@@ -376,10 +342,10 @@ def replica_ds_init_info(ansible_log,
|
||||
|
||||
# during replica install, this gets invoked before local DS is
|
||||
# available, so use the remote api.
|
||||
#if ca_is_configured:
|
||||
# ca_subject = ca.lookup_ca_subject(_api, config.subject_base)
|
||||
#else:
|
||||
# ca_subject = installutils.default_ca_subject_dn(config.subject_base)
|
||||
# if ca_is_configured:
|
||||
# ca_subject = ca.lookup_ca_subject(_api, config.subject_base)
|
||||
# else:
|
||||
# ca_subject = installutils.default_ca_subject_dn(config.subject_base)
|
||||
ca_subject = ds_ca_subject
|
||||
|
||||
ds = dsinstance.DsInstance(
|
||||
@@ -425,112 +391,9 @@ def replica_ds_init_info(ansible_log,
|
||||
return ds
|
||||
|
||||
|
||||
def krb_init_info(ansible_log, fstore, realm_name, host_name, no_pkinit,
|
||||
subject_base):
|
||||
krb = krbinstance.KrbInstance(fstore)
|
||||
krb.set_output(ansible_log)
|
||||
with redirect_stdout(ansible_log):
|
||||
krb.init_info(realm_name, host_name, etup_pkinit=not no_pkinit,
|
||||
subject_base=subject_base)
|
||||
|
||||
|
||||
def replica_krb_init_info(ansible_log, fstore, realm_name, master_host_name,
|
||||
host_name, domain_name, admin_password,
|
||||
no_pkinit, subject_base, pkcs12_info=None):
|
||||
# promote is not needed here
|
||||
|
||||
# From replicainstall.install_krb
|
||||
krb = krbinstance.KrbInstance(fstore=fstore)
|
||||
krb.set_output(ansible_log)
|
||||
|
||||
# pkinit files
|
||||
if pkcs12_info is None:
|
||||
pkcs12_info = make_pkcs12_info(config.dir, "pkinitcert.p12",
|
||||
"pkinit_pin.txt")
|
||||
|
||||
#krb.create_replica(realm_name,
|
||||
# master_host_name, host_name,
|
||||
# domain_name, dirman_password,
|
||||
# setup_pkinit, pkcs12_info,
|
||||
# subject_base=subject_base,
|
||||
# promote=promote)
|
||||
with redirect_stdout(ansible_log):
|
||||
krb.init_info(realm_name, host_name, setup_pkinit=not no_pkinit,
|
||||
subject_base=subject_base)
|
||||
|
||||
# From ipaserver.install.krbinstance.create_replica
|
||||
|
||||
krb.pkcs12_info = pkcs12_info
|
||||
krb.subject_base = subject_base
|
||||
krb.master_fqdn = master_host_name
|
||||
krb.config_pkinit = not no_pkinit
|
||||
|
||||
#krb.__common_setup(realm_name, host_name, domain_name, admin_password)
|
||||
krb.fqdn = host_name
|
||||
krb.realm = realm_name.upper()
|
||||
krb.host = host_name.split(".")[0]
|
||||
krb.ip = socket.getaddrinfo(host_name, None, socket.AF_UNSPEC, socket.SOCK_STREAM)[0][4][0]
|
||||
krb.domain = domain_name
|
||||
krb.suffix = ipautil.realm_to_suffix(krb.realm)
|
||||
krb.kdc_password = ipautil.ipa_generate_password()
|
||||
krb.admin_password = admin_password
|
||||
krb.dm_password = admin_password
|
||||
|
||||
#krb.__setup_sub_dict()
|
||||
if os.path.exists(paths.COMMON_KRB5_CONF_DIR):
|
||||
includes = 'includedir {}'.format(paths.COMMON_KRB5_CONF_DIR)
|
||||
else:
|
||||
includes = ''
|
||||
|
||||
krb.sub_dict = dict(FQDN=krb.fqdn,
|
||||
IP=krb.ip,
|
||||
PASSWORD=krb.kdc_password,
|
||||
SUFFIX=krb.suffix,
|
||||
DOMAIN=krb.domain,
|
||||
HOST=krb.host,
|
||||
SERVER_ID=installutils.realm_to_serverid(krb.realm),
|
||||
REALM=krb.realm,
|
||||
KRB5KDC_KADM5_ACL=paths.KRB5KDC_KADM5_ACL,
|
||||
DICT_WORDS=paths.DICT_WORDS,
|
||||
KRB5KDC_KADM5_KEYTAB=paths.KRB5KDC_KADM5_KEYTAB,
|
||||
KDC_CERT=paths.KDC_CERT,
|
||||
KDC_KEY=paths.KDC_KEY,
|
||||
CACERT_PEM=paths.CACERT_PEM,
|
||||
KDC_CA_BUNDLE_PEM=paths.KDC_CA_BUNDLE_PEM,
|
||||
CA_BUNDLE_PEM=paths.CA_BUNDLE_PEM,
|
||||
INCLUDES=includes)
|
||||
|
||||
# IPA server/KDC is not a subdomain of default domain
|
||||
# Proper domain-realm mapping needs to be specified
|
||||
domain = dnsname.from_text(krb.domain)
|
||||
fqdn = dnsname.from_text(krb.fqdn)
|
||||
if not fqdn.is_subdomain(domain):
|
||||
logger.debug("IPA FQDN '%s' is not located in default domain '%s'",
|
||||
fqdn, domain)
|
||||
server_domain = fqdn.parent().to_unicode(omit_final_dot=True)
|
||||
logger.debug("Domain '%s' needs additional mapping in krb5.conf",
|
||||
server_domain)
|
||||
dr_map = " .%(domain)s = %(realm)s\n %(domain)s = %(realm)s\n" \
|
||||
% dict(domain=server_domain, realm=krb.realm)
|
||||
else:
|
||||
dr_map = ""
|
||||
krb.sub_dict['OTHER_DOMAIN_REALM_MAPS'] = dr_map
|
||||
|
||||
# Configure KEYRING CCACHE if supported
|
||||
if kernel_keyring.is_persistent_keyring_supported():
|
||||
logger.debug("Enabling persistent keyring CCACHE")
|
||||
krb.sub_dict['OTHER_LIBDEFAULTS'] = \
|
||||
" default_ccache_name = KEYRING:persistent:%{uid}\n"
|
||||
else:
|
||||
logger.debug("Persistent keyring CCACHE is not enabled")
|
||||
krb.sub_dict['OTHER_LIBDEFAULTS'] = ''
|
||||
|
||||
return krb
|
||||
|
||||
|
||||
def ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
param='ip_addresses'):
|
||||
ip_addrs = [ ]
|
||||
ip_addrs = []
|
||||
for ip in ansible_module.params.get(param):
|
||||
try:
|
||||
ip_parsed = ipautil.CheckedIPAddress(ip)
|
||||
@@ -542,7 +405,8 @@ def ansible_module_get_parsed_ip_addresses(ansible_module,
|
||||
|
||||
def gen_remote_api(master_host_name, etc_ipa):
|
||||
ldapuri = 'ldaps://%s' % ipautil.format_netloc(master_host_name)
|
||||
xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(master_host_name))
|
||||
xmlrpc_uri = 'https://{}/ipa/xml'.format(
|
||||
ipautil.format_netloc(master_host_name))
|
||||
remote_api = create_api(mode=None)
|
||||
remote_api.bootstrap(in_server=True,
|
||||
context='installer',
|
||||
|
||||
@@ -5,22 +5,19 @@
|
||||
|
||||
- name: Install - Ensure IPA replica packages are installed
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
name: "{{ ipareplica_packages }}"
|
||||
state: present
|
||||
with_items: "{{ ipareplica_packages }}"
|
||||
|
||||
- name: Install - Ensure IPA replica packages for dns are installed
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
name: "{{ ipareplica_packages_dns }}"
|
||||
state: present
|
||||
with_items: "{{ ipareplica_packages_dns }}"
|
||||
when: ipareplica_setup_dns | bool
|
||||
|
||||
- name: Install - Ensure IPA replica packages for adtrust are installed
|
||||
package:
|
||||
name: "{{ item }}"
|
||||
name: "{{ ipareplica_packages_adtrust }}"
|
||||
state: present
|
||||
with_items: "{{ ipareplica_packages_adtrust }}"
|
||||
when: ipareplica_setup_adtrust | bool
|
||||
|
||||
when: ipareplica_install_packages | bool
|
||||
@@ -28,6 +25,11 @@
|
||||
#- name: Install - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
|
||||
- name: Install - Set ipareplica_servers
|
||||
set_fact:
|
||||
ipareplica_servers: "{{ groups['ipaservers'] | list }}"
|
||||
when: groups.ipaservers is defined and ipareplica_servers is not defined
|
||||
|
||||
- name: Install - Set default principal if no keytab is given
|
||||
set_fact:
|
||||
ipaadmin_principal: admin
|
||||
@@ -41,8 +43,7 @@
|
||||
ip_addresses: "{{ ipareplica_ip_addresses | default([]) }}"
|
||||
domain: "{{ ipareplica_domain | default(ipaserver_domain) |
|
||||
default(omit) }}"
|
||||
servers: "{{ groups.ipaservers | default(groups.ipaserver) |
|
||||
default(omit) }}"
|
||||
servers: "{{ ipareplica_servers | default(omit) }}"
|
||||
realm: "{{ ipareplica_realm | default(omit) }}"
|
||||
hostname: "{{ ipareplica_hostname | default(ansible_fqdn) }}"
|
||||
ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}"
|
||||
@@ -82,9 +83,9 @@
|
||||
name: ipaclient
|
||||
vars:
|
||||
state: present
|
||||
ipaclient_domain: "{{ result_ipareplica_test.domain }}"
|
||||
ipaclient_realm: "{{ result_ipareplica_test.realm }}"
|
||||
ipaclient_servers: ["{{ result_ipareplica_test.server }}"]
|
||||
ipaclient_domain: "{{ result_ipareplica_test.domain | default(omit) }}"
|
||||
ipaclient_realm: "{{ result_ipareplica_test.realm | default(omit) }}"
|
||||
ipaclient_servers: "{{ ipareplica_servers | default(omit) }}"
|
||||
ipaclient_hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
ipaclient_no_ntp: "{{ result_ipareplica_test.ipa_python_version
|
||||
< 40690 }}"
|
||||
@@ -132,10 +133,13 @@
|
||||
setup_dns: "{{ ipareplica_setup_dns }}"
|
||||
### ssl certificate ###
|
||||
dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}"
|
||||
dirsrv_cert_name: "{{ ipareplica_dirsrv_cert_name | default(omit) }}"
|
||||
dirsrv_pin: "{{ ipareplica_dirsrv_pin | default(omit) }}"
|
||||
http_cert_files: "{{ ipareplica_http_cert_files | default([]) }}"
|
||||
http_cert_name: "{{ ipareplica_http_cert_name | default(omit) }}"
|
||||
http_pin: "{{ ipareplica_http_pin | default(omit) }}"
|
||||
pkinit_cert_files: "{{ ipareplica_pkinit_cert_files | default([]) }}"
|
||||
pkinit_cert_name: "{{ ipareplica_pkinit_cert_name | default(omit) }}"
|
||||
pkinit_pin: "{{ ipareplica_pkinit_pin | default(omit) }}"
|
||||
### client ###
|
||||
keytab: "{{ ipaclient_keytab | default(omit) }}"
|
||||
@@ -181,7 +185,6 @@
|
||||
- name: Install - Create dirman password
|
||||
no_log: yes
|
||||
ipareplica_master_password:
|
||||
dm_password: "{{ ipadm_password }}"
|
||||
master_password: "{{ ipareplica_master_password | default(omit) }}"
|
||||
register: result_ipareplica_master_password
|
||||
|
||||
@@ -222,11 +225,6 @@
|
||||
server: "{{ result_ipareplica_test.server }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}"
|
||||
_http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
@@ -270,10 +268,7 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}"
|
||||
_http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
@@ -314,13 +309,10 @@
|
||||
server: "{{ result_ipareplica_test.server }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}"
|
||||
_http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
@@ -343,6 +335,50 @@
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
|
||||
# We need to point to the master in ipa default conf when certmonger
|
||||
# asks for HTTP certificate in newer ipa versions. In these versions
|
||||
# create_ipa_conf has the additional master argument.
|
||||
- name: Install - Create override IPA conf
|
||||
ipareplica_create_ipa_conf:
|
||||
### basic ###
|
||||
dm_password: "{{ ipadm_password | default(omit) }}"
|
||||
password: "{{ ipaadmin_password | default(omit) }}"
|
||||
ip_addresses: "{{ ipareplica_ip_addresses | default([]) }}"
|
||||
domain: "{{ result_ipareplica_test.domain }}"
|
||||
realm: "{{ result_ipareplica_test.realm }}"
|
||||
hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}"
|
||||
no_host_dns: "{{ ipareplica_no_host_dns }}"
|
||||
### replica ###
|
||||
setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}"
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
setup_dns: "{{ ipareplica_setup_dns }}"
|
||||
### ssl certificate ###
|
||||
dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}"
|
||||
### client ###
|
||||
force_join: "{{ ipaclient_force_join }}"
|
||||
### ad trust ###
|
||||
netbios_name: "{{ ipareplica_netbios_name | default(omit) }}"
|
||||
rid_base: "{{ ipareplica_rid_base | default(omit) }}"
|
||||
secondary_rid_base: "{{ ipareplica_secondary_rid_base | default(omit) }}"
|
||||
### additional ###
|
||||
server: "{{ result_ipareplica_test.server }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
master:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
when: result_ipareplica_test.change_master_for_certmonger
|
||||
|
||||
- name: Install - DS enable SSL
|
||||
ipareplica_ds_enable_ssl:
|
||||
### server ###
|
||||
@@ -383,6 +419,46 @@
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
|
||||
# Need to point back to ourself after the cert for HTTP is obtained
|
||||
- name: Install - Create original IPA conf again
|
||||
ipareplica_create_ipa_conf:
|
||||
### basic ###
|
||||
dm_password: "{{ ipadm_password | default(omit) }}"
|
||||
password: "{{ ipaadmin_password | default(omit) }}"
|
||||
ip_addresses: "{{ ipareplica_ip_addresses | default([]) }}"
|
||||
domain: "{{ result_ipareplica_test.domain }}"
|
||||
realm: "{{ result_ipareplica_test.realm }}"
|
||||
hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}"
|
||||
no_host_dns: "{{ ipareplica_no_host_dns }}"
|
||||
### replica ###
|
||||
setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}"
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
setup_dns: "{{ ipareplica_setup_dns }}"
|
||||
### ssl certificate ###
|
||||
dirsrv_cert_files: "{{ ipareplica_dirsrv_cert_files | default([]) }}"
|
||||
### client ###
|
||||
force_join: "{{ ipaclient_force_join }}"
|
||||
### ad trust ###
|
||||
netbios_name: "{{ ipareplica_netbios_name | default(omit) }}"
|
||||
rid_base: "{{ ipareplica_rid_base | default(omit) }}"
|
||||
secondary_rid_base: "{{ ipareplica_secondary_rid_base | default(omit) }}"
|
||||
### additional ###
|
||||
server: "{{ result_ipareplica_test.server }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
when: result_ipareplica_test.change_master_for_certmonger
|
||||
|
||||
- name: Install - Setup otpd
|
||||
ipareplica_setup_otpd:
|
||||
### server ###
|
||||
@@ -396,7 +472,6 @@
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
@@ -415,6 +490,8 @@
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
@@ -426,7 +503,8 @@
|
||||
setup_ca: "{{ ipareplica_setup_ca }}"
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
no_pkinit: "{{ ipareplica_no_pkinit }}"
|
||||
no_ui_redirect: "{{ ipareplica_no_ui_redirect }}"
|
||||
pki_config_override:
|
||||
"{{ ipareplica_pki_config_override | default(omit) }}"
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
@@ -434,6 +512,8 @@
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
@@ -452,7 +532,6 @@
|
||||
setup_ca: "{{ ipareplica_setup_ca }}"
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
no_pkinit: "{{ ipareplica_no_pkinit }}"
|
||||
# no_ui_redirect: "{{ ipareplica_no_ui_redirect }}"
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
@@ -497,6 +576,8 @@
|
||||
hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}"
|
||||
no_host_dns: "{{ ipareplica_no_host_dns }}"
|
||||
pki_config_override:
|
||||
"{{ ipareplica_pki_config_override | default(omit) }}"
|
||||
### replica ###
|
||||
setup_adtrust: "{{ result_ipareplica_test.setup_adtrust }}"
|
||||
setup_ca: "{{ ipareplica_setup_ca }}"
|
||||
@@ -516,9 +597,7 @@
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_dirsrv_pkcs12_info: "{{ result_ipareplica_prepare._dirsrv_pkcs12_info }}"
|
||||
_http_pkcs12_info: "{{ result_ipareplica_prepare._http_pkcs12_info }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
_add_to_ipaservers: "{{ result_ipareplica_prepare._add_to_ipaservers }}"
|
||||
_ca_subject: "{{ result_ipareplica_prepare._ca_subject }}"
|
||||
@@ -538,9 +617,7 @@
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
# _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
|
||||
@@ -560,7 +637,8 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_kra_enabled: "{{ result_ipareplica_prepare._kra_enabled }}"
|
||||
_kra_host_name: "{{ result_ipareplica_prepare.config_kra_host_name }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
@@ -607,6 +685,8 @@
|
||||
not none else omit }}"
|
||||
no_dnssec_validation: "{{ ipareplica_no_dnssec_validation }}"
|
||||
### additional ###
|
||||
dns_ip_addresses: "{{ result_ipareplica_prepare.dns_ip_addresses }}"
|
||||
dns_reverse_zones: "{{ result_ipareplica_prepare.dns_reverse_zones }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
@@ -640,6 +720,8 @@
|
||||
hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
hidden_replica: "{{ ipareplica_hidden_replica }}"
|
||||
### server ###
|
||||
### replica ###
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
- "vars/default.yml"
|
||||
|
||||
- name: Install IPA replica
|
||||
include_tasks: tasks/install.yml
|
||||
include_tasks: install.yml
|
||||
when: state|default('present') == 'present'
|
||||
|
||||
- name: Uninstall IPA replica
|
||||
include_tasks: tasks/uninstall.yml
|
||||
include_tasks: uninstall.yml
|
||||
when: state|default('present') == 'absent'
|
||||
|
||||
@@ -34,8 +34,7 @@
|
||||
# failed_when: False
|
||||
# delegate_to: "{{ groups.ipaserver[0] | default(fail) }}"
|
||||
|
||||
# - name: Remove IPA replica packages
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipareplica_packages }}"
|
||||
#- name: Remove IPA replica packages
|
||||
# package:
|
||||
# name: "{{ ipareplica_packages }}"
|
||||
# state: absent
|
||||
|
||||
5
roles/ipareplica/vars/RedHat-8.yml
Normal file
5
roles/ipareplica/vars/RedHat-8.yml
Normal file
@@ -0,0 +1,5 @@
|
||||
# defaults file for ipareplica
|
||||
# vars/RedHat-8.yml
|
||||
ipareplica_packages: [ "@idm:DL1/server" ]
|
||||
ipareplica_packages_dns: [ "@idm:DL1/dns" ]
|
||||
ipareplica_packages_adtrust: [ "@idm:DL1/adtrust" ]
|
||||
@@ -1,4 +1,4 @@
|
||||
# vars/Ubuntu.yml
|
||||
ipareplica_packages: [ "freeipa-server" ]
|
||||
ipareplica_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipareplica_packages_adtrust: [ ]
|
||||
ipareplica_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
|
||||
@@ -6,8 +6,51 @@ Description
|
||||
|
||||
This role allows to configure and IPA 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 deployment
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.5 and up are supported by the server 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)
|
||||
|
||||
|
||||
Limitations
|
||||
-----------
|
||||
|
||||
External signed CA
|
||||
|
||||
External signed CA is now supported. But the currently needed two step process is an issue for the processing in a simple playbook.
|
||||
|
||||
Work is planned to have a new method to handle CSR for external signed CAs in a separate step before starting the server installation.
|
||||
|
||||
|
||||
Usage
|
||||
-----
|
||||
=====
|
||||
|
||||
Example inventory file with fixed domain and realm, setting up of the DNS server and using forwarders from /etc/resolv.conf:
|
||||
|
||||
@@ -63,111 +106,187 @@ Example playbook to setup the IPA server using admin and dirman passwords from i
|
||||
- role: ipaserver
|
||||
state: present
|
||||
|
||||
Example playbook to setup the IPA primary with external signed CA using the previous inventory file:
|
||||
|
||||
Server installation step 1: Generate CSR, copy to controller as `<ipaserver hostname>-ipa.csr`
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to configure IPA server step1
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
vars:
|
||||
ipaserver_external_ca: yes
|
||||
|
||||
roles:
|
||||
- role: ipaserver
|
||||
state: present
|
||||
|
||||
post_tasks:
|
||||
- name: Copy CSR /root/ipa.csr from node to "{{ groups.ipaserver[0] + '-ipa.csr' }}"
|
||||
fetch:
|
||||
src: /root/ipa.csr
|
||||
dest: "{{ groups.ipaserver[0] + '-ipa.csr' }}"
|
||||
flat: yes
|
||||
```
|
||||
|
||||
Sign with CA: This is up to you
|
||||
|
||||
Server installatin step 2: Copy `<ipaserver hostname>-chain.crt` to the IPA server and continue with installation of the primary.
|
||||
|
||||
```yaml
|
||||
- name: Playbook to configure IPA server step3
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
vars:
|
||||
ipaserver_external_cert_files: "/root/chain.crt"
|
||||
|
||||
pre_tasks:
|
||||
- name: Copy "{{ groups.ipaserver[0] + '-chain.crt' }}" to /root/chain.crt on node
|
||||
copy:
|
||||
src: "{{ groups.ipaserver[0] + '-chain.crt' }}"
|
||||
dest: "/root/chain.crt"
|
||||
force: yes
|
||||
|
||||
roles:
|
||||
- role: ipaserver
|
||||
state: present
|
||||
```
|
||||
|
||||
The files can also be copied automatically: Set `ipaserver_copy_csr_to_controller` to true in the server installation step 1 and set `ipaserver_external_cert_files_from_controller` to point to the `chain.crt` file in the server installatin step 2.
|
||||
|
||||
|
||||
Playbooks
|
||||
=========
|
||||
|
||||
The playbooks needed to deploy or undeploy a server are part of the repository in the playbooks folder. There are also playbooks to deploy and undeploy clusters.
|
||||
```
|
||||
install-server.yml
|
||||
uninstall-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.
|
||||
|
||||
|
||||
How to setup a server
|
||||
---------------------
|
||||
|
||||
```bash
|
||||
ansible-playbook -v -i inventory/hosts install-server.yml
|
||||
```
|
||||
This will deploy the server defined in the inventory file.
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
=========
|
||||
|
||||
**ipaserver** - Group with the IPA server hostname
|
||||
(list of strings)
|
||||
Base Variables
|
||||
--------------
|
||||
|
||||
**ipaadmin_password** - The password for the IPA admin user.
|
||||
(string, optional)
|
||||
|
||||
**ipadm_password** - The password for the Directory Manager.
|
||||
(string, optional)
|
||||
|
||||
**ipaserver_domain** - The primary DNS domain of an existing IPA deployment.
|
||||
(string)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaserver` | This group with the single IPA server full qualified hostname. (list of strings) | yes
|
||||
`ipadm_password` | The password for the Directory Manager. (string) | no
|
||||
`ipaadmin_password` | The password for the IPA admin user (string) | no
|
||||
`ipaserver_ip_addresses` | The list of master server IP addresses. (list of strings) | no
|
||||
`ipaserver_domain` | The primary DNS domain of an existing IPA deployment. (string) | no
|
||||
`ipaserver_realm` | The Kerberos realm of an existing IPA deployment. (string) | no
|
||||
`ipaserver_hostname` | Fully qualified name of the server. (string) | no
|
||||
`ipaserver_no_host_dns` | Do not use DNS for hostname lookup during installation. (bool, default: false) | no
|
||||
|
||||
**ipaserver_realm** - The Kerberos realm of an existing IPA deployment.
|
||||
(string)
|
||||
Server Variables
|
||||
----------------
|
||||
|
||||
**ipaserver_idstart** - The starting user and group id number (default random).
|
||||
(integer, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaserver_setup_adtrust` | Configure AD Trust capability. (bool, default: false) | no
|
||||
`ipaserver_setup_kra` | Install and configure a KRA on this server. (bool, default: false) | no
|
||||
`ipaserver_setup_dns` | Configure an integrated DNS server, create DNS zone specified by domain. (bool, default: false) | no
|
||||
`ipaserver_idstart` | The starting user and group id number. (integer, default: random) | no
|
||||
`ipaserver_idmax` | The maximum user and group id number. (integer, default: idstart+199999) | no
|
||||
`ipaserver_no_hbac_allow` | Do not install allow_all HBAC rule. (bool) | no
|
||||
`ipaserver_no_ui_redirect` | Do not automatically redirect to the Web UI. (bool) | no
|
||||
`ipaserver_dirsrv_config_file` | The path to LDIF file that will be used to modify configuration of dse.ldif during installation. (string) | no
|
||||
`ipaserver_pki_config_override` | Path to ini file with config overrides. This is only usable with recent FreeIPA versions. (string) | no
|
||||
|
||||
**ipaserver_idmax** - The maximum user and group id number (default: idstart+199999).
|
||||
(integer, optional)
|
||||
SSL certificate Variables
|
||||
-------------------------
|
||||
|
||||
**ipaserver_no_hbac_allow** - Do not install allow_all HBAC rule.
|
||||
(bool, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaserver_dirsrv_cert_files` | Files containing the Directory Server SSL certificate and private keys. (list of strings) | no
|
||||
`ipaserver_http_cert_file` | File containing the Apache Server SSL certificate and private key. (string) | no
|
||||
`ipaserver_pkinit_cert_file` | File containing the Kerberos KDC SSL certificate and private key. (string) | no
|
||||
`ipaserver_dirsrv_pin` | The password to unlock the Directory Server private key. (string) | no
|
||||
`ipaserver_http_pin` | The password to unlock the Apache Server private key. (string) | no
|
||||
`ipaserver_pkinit_pin` | The password to unlock the Kerberos KDC private key. (string) | no
|
||||
`ipaserver_dirsrv_cert_name` | Name of the Directory Server SSL certificate to install. (string) | no
|
||||
`ipaserver_http_cert_name` | Name of the Apache Server SSL certificate to install. (string) | no
|
||||
`ipaserver_pkinit_cert_name` | Name of the Kerberos KDC SSL certificate to install. (string) | no
|
||||
|
||||
**ipaserver_no_ui_redirect** - Do not automatically redirect to the Web UI.
|
||||
(bool, optional)
|
||||
Client Variables
|
||||
----------------
|
||||
|
||||
**ipaserver_dirsrv_config_file** - The path to LDIF file that will be used to modify configuration of dse.ldif during installation.
|
||||
(string, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaclient_ntp_servers` | The list defines the NTP servers to be used. | no
|
||||
`ipaclient_ntp_pool` | The string value defines the ntp server pool to be used. | no
|
||||
`ipaclient_no_ntp` | The bool value defines if NTP will not be configured and enabled. `ipaclient_no_ntp` defaults to `no`. | no
|
||||
`ipaclient_ssh_trust_dns` | The bool value defines if OpenSSH client will be configured to trust DNS SSHFP records. `ipaclient_ssh_trust_dns` defaults to `no`. | no
|
||||
`ipaclient_no_ssh` | The bool value defines if OpenSSH client will be configured. `ipaclient_no_ssh` defaults to `no`. | no
|
||||
`ipaclient_no_sshd` | The bool value defines if OpenSSH server will be configured. `ipaclient_no_sshd` defaults to `no`. | no
|
||||
`ipaclient_no_sudo` | The bool value defines if SSSD will be configured as a data source for sudo. `ipaclient_no_sudo` defaults to `no`. | no
|
||||
`ipaclient_no_dns_sshfp` | The bool value defines if DNS SSHFP records will not be created automatically. `ipaclient_no_dns_sshfp` defaults to `no`. | no
|
||||
|
||||
**ipaserver_setup_kra** - Install and configure a KRA on this server.
|
||||
(bool, optional)
|
||||
Certificate system Variables
|
||||
----------------------------
|
||||
|
||||
**ipaserver_setup_dns** - Configure an integrated DNS server, create DNS zone specified by domain
|
||||
(string, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaserver_external_ca` | Generate a CSR for the IPA CA certificate to be signed by an external CA. (bool, default: false) | no
|
||||
`ipaserver_external_ca_type` | Type of the external CA. (choice: generic,ms-cs) | no
|
||||
`ipaserver_external_ca_profile` | Specify the certificate profile/template to use at the external CA. (string) | no
|
||||
`ipaserver_external_cert_files` | Files containing the IPA CA certificates and the external CA certificate chains (list of string) | no
|
||||
`ipaserver_subject_base` | The certificate subject base (default O=<realm-name>). RDNs are in LDAP order (most specific RDN first). (string) | no
|
||||
`ipaserver_ca_subject` | The CA certificate subject DN (default CN=Certificate Authority,O=<realm-name>). RDNs are in LDAP order (most specific RDN first). (string) | no
|
||||
`ipaserver_ca_signing_algorithm` | Signing algorithm of the IPA CA certificate. (choice: SHA1withRSA,SHA256withRSA,SHA512withRSA) | no
|
||||
|
||||
**ipaserver_forwarders** - Add DNS forwarders to the DNS configuration.
|
||||
(list of strings, optional)
|
||||
DNS Variables
|
||||
-------------
|
||||
|
||||
**ipaserver_no_forwarders** - Do not add any DNS forwarders. Root DNS servers will be used instead.
|
||||
(bool, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaserver_allow_zone_overlap` | Allow creation of (reverse) zone even if the zone is already resolvable. (bool, default: false) | no
|
||||
`ipaserver_reverse_zones` | The reverse DNS zones to use. (list of strings) | no
|
||||
`ipaserver_no_reverse` | Do not create reverse DNS zone. (bool, default: false) | no
|
||||
`ipaserver_auto_reverse` | Try to resolve reverse records and reverse zones for server IP addresses. (bool, default: false) | no
|
||||
`ipaserver_zonemgr` | The e-mail address of the DNS zone manager. (string, default: hostmaster@DOMAIN.) | no
|
||||
`ipaserver_forwarders` | Add DNS forwarders to the DNS configuration. (list of strings) | no
|
||||
`ipaserver_no_forwarders` | Do not add any DNS forwarders. Root DNS servers will be used instead. (bool, default: false) | no
|
||||
`ipaserver_auto_forwarders` | Add DNS forwarders configured in /etc/resolv.conf to the list of forwarders used by IPA DNS. (bool, default: false) | no
|
||||
`ipaserver_forward_policy` | DNS forwarding policy for global forwarders specified using other options. (choice: first|only) | no
|
||||
`ipaserver_no_dnssec_validation` | Disable DNSSEC validation on this server. (bool, default: false) | no
|
||||
|
||||
**ipaserver_auto_forwarders** - Add DNS forwarders configured in /etc/resolv.conf to the list of forwarders used by IPA DNS.
|
||||
(bool, optional)
|
||||
AD trust Variables
|
||||
------------------
|
||||
|
||||
**ipaserver_forward_policy** - DNS forwarding policy for global forwarders specified using other options. first|only
|
||||
(choice, optional)
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaserver_enable_compat`| Enables support for trusted domains users for old clients through Schema Compatibility plugin. (bool, default: false) | no
|
||||
`ipaserver_netbios_name` | The NetBIOS name for the IPA domain. (string) | no
|
||||
`ipaserver_rid_base` | First RID value of the local domain. (integer) | no
|
||||
`ipaserver_secondary_rid_base` | Start value of the secondary RID range. (integer) | no
|
||||
|
||||
**ipaserver_reverse_zones** - The reverse DNS zones to use.
|
||||
(list of strings, optional)
|
||||
Special Variables
|
||||
-----------------
|
||||
|
||||
**ipaserver_no_reverse** - Do not create reverse DNS zone.
|
||||
(bool, optional)
|
||||
|
||||
**ipaserver_auto_reverse** - Try to resolve reverse records and reverse zones for server IP addresses.
|
||||
(bool, optional)
|
||||
|
||||
**ipaserver_zonemgr** - The e-mail address of the DNS zone manager. Defaults to hostmaster@DOMAIN.
|
||||
(string, optional)
|
||||
|
||||
**ipaserver_no_host_dns** - Do not use DNS for hostname lookup during installation.
|
||||
(bool, optional)
|
||||
|
||||
**ipaserver_pki_config_override** - Path to ini file with config overrides.
|
||||
(string, optional)
|
||||
|
||||
**ipaserver_no_dnssec_validation** - Disable DNSSEC validation on this server.
|
||||
(bool, optional)
|
||||
|
||||
**ipaserver_allow_zone_overlap** - Allow creation of (reverse) zone even if the zone is already resolvable.
|
||||
(bool, optional)
|
||||
|
||||
**ipaserver_setup_adtrust** - Configure AD Trust capability.
|
||||
(bool, optional)
|
||||
|
||||
**ipaserver_netbios_name** - The NetBIOS name for the IPA domain.
|
||||
(string, optional)
|
||||
|
||||
**ipaserver_rid_base** - First RID value of the local domain.
|
||||
(integer, optional)
|
||||
|
||||
**ipaserver_secondary_rid_base** - Start value of the secondary RID range.
|
||||
(integer, optional)
|
||||
|
||||
**ipaserver_enable_compat** - Enables support for trusted domains users for old clients through Schema Compatibility plugin.
|
||||
(bool, optional)
|
||||
|
||||
**ipaclient_force_join** - Set force_join to yes to join the host even if it is already enrolled.
|
||||
(bool, optional)
|
||||
|
||||
**ipaclient_no_ntp** - Set to no to not configure and enable NTP
|
||||
(bool, optional)
|
||||
|
||||
**ipaclient_mkhomedir** - Set to yes to configure PAM to create a users home directory if it does not exist.
|
||||
(string, optional)
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
freeipa-server v4.5 or later
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`ipaserver_install_packages` | The bool value defines if the needed packages are installed on the node. (bool, default: true) | no
|
||||
`ipaserver_setup_firewalld` | The value defines if the needed services will automatically be openen in the firewall managed by firewalld. (bool, default: true) | no
|
||||
`ipaserver_external_cert_files_from_controller` | Files containing the IPA CA certificates and the external CA certificate chains on the controller that will be copied to the ipaserver host to `/root` folder. (list of string) | no
|
||||
`ipaserver_copy_csr_to_controller` | Copy the generated CSR from the ipaserver to the controller as `"{{ inventory_hostname }}-ipa.csr"`. (bool) | no
|
||||
|
||||
Authors
|
||||
-------
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
|
||||
@@ -36,7 +36,7 @@ ipaserver_install_packages: yes
|
||||
ipaserver_setup_firewalld: yes
|
||||
|
||||
### additional ###
|
||||
ipaserver_allow_missing: [ ]
|
||||
ipaserver_copy_csr_to_controller: no
|
||||
|
||||
### uninstall ###
|
||||
ipaserver_ignore_topology_disconnect: no
|
||||
|
||||
@@ -1,536 +0,0 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Florence Blanc-Renaud <frenaud@redhat.com>
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2017 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {'metadata_version': '1.0',
|
||||
'status': ['preview'],
|
||||
'supported_by': 'community'}
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaserver
|
||||
short description: Configures a server machine as IPA server
|
||||
description:
|
||||
Configures a server machine to use IPA for authentication and
|
||||
identity services.
|
||||
The enrollment requires one authentication method among the 3 following:
|
||||
- Kerberos principal and password (principal/password)
|
||||
- Kerberos keytab file (keytab)
|
||||
- One-Time-Password (otp)
|
||||
options:
|
||||
state:
|
||||
description: the server state
|
||||
required: false
|
||||
default: present
|
||||
choices: [ "present", "absent" ]
|
||||
domain:
|
||||
description: The primary DNS domain of an existing IPA deployment
|
||||
required: true
|
||||
realm:
|
||||
description: The Kerberos realm of an existing IPA deployment
|
||||
required: true
|
||||
password:
|
||||
description: The password for the kerberos admin
|
||||
required: true
|
||||
dm_password:
|
||||
description: The password for the Directory Manager
|
||||
required: true
|
||||
|
||||
# ip_addresses:
|
||||
# description: Master Server IP Addresses
|
||||
# required: false
|
||||
# hostname:
|
||||
# description: Fully qualified name of this host
|
||||
# required: false
|
||||
|
||||
mkhomedir:
|
||||
description: Create home directories for users on their first login
|
||||
required: false
|
||||
default: no
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: false
|
||||
default: no
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: false
|
||||
default: no
|
||||
no_ntp:
|
||||
description: Do not configure ntp
|
||||
required: false
|
||||
default: no
|
||||
|
||||
idstart:
|
||||
description: The starting value for the IDs range (default random)
|
||||
required: false
|
||||
idmax:
|
||||
description: The max value for the IDs range (default: idstart+199999)
|
||||
required: false
|
||||
no_hbac_allow:
|
||||
description: Don't install allow_all HBAC rule
|
||||
required: false
|
||||
default: no
|
||||
# ignore_topology_disconnect:
|
||||
# description: Do not check whether server uninstall disconnects the topology (domain level 1+)
|
||||
# required: false
|
||||
# default: no
|
||||
# ignore_last_of_role:
|
||||
# description: Do not check whether server uninstall removes last CA/DNS server or DNSSec master (domain level 1+)
|
||||
# required: false
|
||||
no_pkinit:
|
||||
description: Disables pkinit setup steps
|
||||
required: false
|
||||
no_ui_redirect:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: false
|
||||
|
||||
ssh_trust_dns:
|
||||
description: Configure OpenSSH client to trust DNS SSHFP records
|
||||
required: false
|
||||
no_ssh:
|
||||
description: Do not configure OpenSSH client
|
||||
required: false
|
||||
no_sshd:
|
||||
description: Do not configure OpenSSH server
|
||||
required: false
|
||||
no_dns_sshfp:
|
||||
description: Do not automatically create DNS SSHFP records
|
||||
required: false
|
||||
dirsrv_config_file:
|
||||
description: The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance
|
||||
required: false
|
||||
|
||||
external_ca:
|
||||
description: Generate a CSR for the IPA CA certificate to be signed by an external CA
|
||||
required: false
|
||||
external_ca_type:
|
||||
description: Type of the external CA
|
||||
required: false
|
||||
external_cert_files:
|
||||
description: File containing the IPA CA certificate and the external CA certificate chain
|
||||
required: false
|
||||
|
||||
dirsrv_cert_files:
|
||||
description: File containing the Directory Server SSL certificate and private key
|
||||
required: false
|
||||
dirsrv_pin:
|
||||
description: The password to unlock the Directory Server private key
|
||||
required: false
|
||||
dirsrv_cert_name:
|
||||
description: Name of the Directory Server SSL certificate to install
|
||||
required: false
|
||||
|
||||
http_cert_files:
|
||||
description: File containing the Apache Server SSL certificate and private key
|
||||
required: false
|
||||
http_pin:
|
||||
description: The password to unlock the Apache Server private key
|
||||
required: false
|
||||
http_cert_name:
|
||||
description: Name of the Apache Server SSL certificate to install
|
||||
required: false
|
||||
|
||||
pkinit_cert_files:
|
||||
description: File containing the Kerberos KDC SSL certificate and private key
|
||||
required: false
|
||||
pkinit_pin:
|
||||
description: The password to unlock the Kerberos KDC private key
|
||||
required: false
|
||||
pkinit_cert_name:
|
||||
description: Name of the Kerberos KDC SSL certificate to install
|
||||
required: false
|
||||
|
||||
ca_cert_files:
|
||||
description: File containing CA certificates for the service certificate files
|
||||
required: false
|
||||
subject:
|
||||
description: The certificate subject base (default O=<realm-name>)
|
||||
required: false
|
||||
ca_signing_algorithm:
|
||||
description: Signing algorithm of the IPA CA certificate
|
||||
required: false
|
||||
|
||||
forwarders:
|
||||
description: Add DNS forwarders
|
||||
required: false
|
||||
|
||||
|
||||
|
||||
author:
|
||||
- Florence Blanc-Renaud
|
||||
- Thomas Woerner
|
||||
'''
|
||||
|
||||
EXAMPLES = '''
|
||||
# Example from Ansible Playbooks
|
||||
# Unenroll server
|
||||
- ipaserver:
|
||||
state: absent
|
||||
|
||||
# Enroll server using admin credentials, with auto-discovery
|
||||
- ipaserver:
|
||||
password: MySecretPassword
|
||||
dm_password: MySecretPassword
|
||||
'''
|
||||
|
||||
RETURN = '''
|
||||
tbd
|
||||
'''
|
||||
|
||||
import os
|
||||
from six.moves.configparser import RawConfigParser
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
try:
|
||||
from ipalib.install.sysrestore import SYSRESTORE_STATEFILE
|
||||
except ImportError:
|
||||
from ipapython.sysrestore import SYSRESTORE_STATEFILE
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
|
||||
def is_server_configured():
|
||||
"""
|
||||
Check if ipa server is configured.
|
||||
|
||||
IPA server is configured when /etc/ipa/default.conf exists and
|
||||
/var/lib/ipa/sysrestore/sysrestore.state exists.
|
||||
|
||||
:returns: boolean
|
||||
"""
|
||||
|
||||
return (os.path.isfile(paths.IPA_DEFAULT_CONF) and
|
||||
os.path.isfile(os.path.join(paths.SYSRESTORE,
|
||||
SYSRESTORE_STATEFILE)))
|
||||
|
||||
|
||||
def get_ipa_conf():
|
||||
"""
|
||||
Return IPA configuration read from /etc/ipa/default.conf
|
||||
|
||||
:returns: dict containing key,value
|
||||
"""
|
||||
|
||||
parser = RawConfigParser()
|
||||
parser.read(paths.IPA_DEFAULT_CONF)
|
||||
result = dict()
|
||||
for item in ['basedn', 'realm', 'domain', 'server', 'host', 'xmlrpc_uri']:
|
||||
if parser.has_option('global', item):
|
||||
value = parser.get('global', item)
|
||||
else:
|
||||
value = None
|
||||
if value:
|
||||
result[item] = value
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
supports_check_mode=True,
|
||||
argument_spec=dict(
|
||||
state=dict(default='present', choices=['present', 'absent']),
|
||||
# basic
|
||||
dm_password=dict(required=False, no_log=True),
|
||||
password=dict(required=False, no_log=True),
|
||||
# ip_addresses=dict(required=False, type='list'),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
# hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list'),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
# server
|
||||
# setup_adtrust=dict(required=False, type='bool', default=F#alse),
|
||||
# setup_kra=dict(required=False, type='bool', default=False),
|
||||
setup_dns=dict(required=False, type='bool', default=False),
|
||||
idstart=dict(required=False, type='int', default=0),
|
||||
idmax=dict(required=False, type='int', default=0),
|
||||
no_hbac_allow=dict(required=False, type='bool', default=False),
|
||||
no_pkinit=dict(required=False, type='bool', default=False),
|
||||
no_ui_redirect=dict(required=False, type='bool', default=False),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list'),
|
||||
dirsrv_pin=dict(required=False),
|
||||
dirsrv_cert_name=dict(required=False),
|
||||
http_cert_files=dict(required=False, type='list'),
|
||||
http_pin=dict(required=False),
|
||||
http_cert_name=dict(required=False),
|
||||
pkinit_cert_files=dict(required=False, type='list'),
|
||||
pkinit_pin=dict(required=False),
|
||||
pkinit_cert_name=dict(required=False),
|
||||
# client
|
||||
mkhomedir=dict(required=False, type='bool', default=False),
|
||||
no_ntp=dict(required=False, type='bool', default=False),
|
||||
ssh_trust_dns=dict(required=False, type='bool', default=False),
|
||||
no_ssh=dict(required=False, type='bool', default=False),
|
||||
no_sshd=dict(required=False, type='bool', default=False),
|
||||
no_dns_sshfp=dict(required=False, type='bool', default=False),
|
||||
# certificate system
|
||||
external_ca=dict(required=False),
|
||||
external_ca_type=dict(default='generic',
|
||||
choices=['generic', 'ms-cs']),
|
||||
external_cert_files=dict(required=False, type='list'),
|
||||
subject_base=dict(required=False),
|
||||
ca_signing_algorithm=dict(required=False),
|
||||
|
||||
# dns
|
||||
allow_zone_overlap=dict(required=False, type='bool', default=False),
|
||||
reverse_zones=dict(required=False, type='list'),
|
||||
no_reverse=dict(required=False, type='bool', default=False),
|
||||
auto_reverse=dict(required=False, type='bool', default=False),
|
||||
zone_manager=dict(required=False),
|
||||
forwarders=dict(required=False, type='list'),
|
||||
no_forwarders=dict(required=False, type='bool', default=False),
|
||||
auto_forwarders=dict(required=False, type='bool', default=False),
|
||||
forward_policy=dict(default='first', choices=['first', 'only']),
|
||||
no_dnssec_validation=dict(required=False, type='bool', default=False),
|
||||
# ad trust
|
||||
enable_compat=dict(required=False, type='bool', default=False),
|
||||
netbios_name=dict(required=False),
|
||||
rid_base=dict(required=False),
|
||||
secondary_rid_base=dict(required=False),
|
||||
),
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
state = module.params.get('state')
|
||||
|
||||
domain = module.params.get('domain')
|
||||
realm = module.params.get('realm')
|
||||
password = module.params.get('password')
|
||||
dm_password = module.params.get('dm_password')
|
||||
|
||||
#ip_addresses = module.params.get('ip_addresses')
|
||||
#hostname = module.params.get('hostname')
|
||||
|
||||
mkhomedir = module.params.get('mkhomedir')
|
||||
setup_dns = module.params.get('setup_dns')
|
||||
no_host_dns = module.params.get('no_host_dns')
|
||||
no_ntp = module.params.get('no_ntp')
|
||||
|
||||
idstart = module.params.get('idstart')
|
||||
idmax = module.params.get('idmax')
|
||||
no_hbac_allow = module.params.get('no_hbac_allow')
|
||||
ignore_topology_disconnect = module.params.get('ignore_topology_disconnect')
|
||||
ignore_last_of_role = module.params.get('ignore_last_of_role')
|
||||
no_pkinit = module.params.get('no_pkinit')
|
||||
no_ui_redirect = module.params.get('no_ui_redirect')
|
||||
|
||||
ssh_trust_dns = module.params.get('ssh_trust_dns')
|
||||
no_ssh = module.params.get('no_ssh')
|
||||
no_sshd = module.params.get('no_sshd')
|
||||
no_dns_sshfp = module.params.get('no_dns_sshfp')
|
||||
dirsrv_config_file = module.params.get('dirsrv_config_file')
|
||||
|
||||
external_ca = module.params.get('external_ca')
|
||||
external_ca_type = module.params.get('external_ca_type')
|
||||
external_cert_files = module.params.get('external_cert_files')
|
||||
|
||||
dirsrv_cert_files=module.params.get('dirsrv_cert_files')
|
||||
dirsrv_pin=module.params.get('dirsrv_pin')
|
||||
dirsrv_cert_name=module.params.get('dirsrv_cert_name')
|
||||
|
||||
http_cert_files=module.params.get('http_cert_files')
|
||||
http_pin=module.params.get('http_pin')
|
||||
http_cert_name=module.params.get('http_cert_name')
|
||||
|
||||
pkinit_cert_files=module.params.get('pkinit_cert_files')
|
||||
pkinit_pin=module.params.get('pkinit_pin')
|
||||
pkinit_cert_name=module.params.get('pkinit_cert_name')
|
||||
|
||||
ca_cert_files=module.params.get('ca_cert_files')
|
||||
subject=module.params.get('subject')
|
||||
ca_signing_algorithm=module.params.get('ca_signing_algorithm')
|
||||
|
||||
forwarders = module.params.get('forwarders')
|
||||
|
||||
if state == 'present':
|
||||
if not password or not dm_password:
|
||||
module.fail_json(
|
||||
msg="Password and dm password need to be specified")
|
||||
|
||||
# Check if ipa server is already configured
|
||||
if is_server_configured():
|
||||
# Check that realm and domain match
|
||||
current_config = get_ipa_conf()
|
||||
if domain and domain != current_config.get('domain'):
|
||||
module.fail_json(msg="IPA server already installed "
|
||||
"with a conflicting domain")
|
||||
if realm and realm != current_config.get('realm'):
|
||||
module.fail_json(msg="IPA server already installed "
|
||||
"with a conflicting realm")
|
||||
|
||||
# server is already configured and no inconsistency
|
||||
# detected
|
||||
return module.exit_json(changed=False, domain=domain, realm=realm)
|
||||
|
||||
# ipa server not installed
|
||||
if module.check_mode:
|
||||
# Do nothing, just return changed=True
|
||||
return module.exit_json(changed=True)
|
||||
|
||||
# basic options
|
||||
cmd = [
|
||||
module.get_bin_path("ipa-server-install"),
|
||||
"-U",
|
||||
"--ds-password", dm_password,
|
||||
"--admin-password", password,
|
||||
"--domain", domain,
|
||||
"--realm", realm,
|
||||
]
|
||||
|
||||
#for ip in ip_addresses:
|
||||
# cmd.append("--ip-address=%s" % ip)
|
||||
#if hostname:
|
||||
# cmd.append("--hostname=%s" % hostname)
|
||||
|
||||
for cert_file in ca_cert_files:
|
||||
cmd.append("--ca-cert-file=%s" % cert_file)
|
||||
if no_host_dns:
|
||||
cmd.append("--no-host-dns")
|
||||
|
||||
# server options
|
||||
#if setup_adtrust:
|
||||
# cmd.append("--setup-adtrust")
|
||||
#if setup_kra:
|
||||
# cmd.append("--setup-kra")
|
||||
if setup_dns:
|
||||
cmd.append("--setup-dns")
|
||||
if idstart:
|
||||
cmd.append("--idstart=%d", idstart)
|
||||
if idmax:
|
||||
cmd.append("--idstart=%d", idmax)
|
||||
if no_hbac_allow:
|
||||
cmd.append("--no_hbac_allow")
|
||||
if no_pkinit:
|
||||
cmd.append("--no-pkinit")
|
||||
if no_ui_redirect:
|
||||
cmd.append("--no-ui-redirect")
|
||||
if dirsrv_config_file:
|
||||
cmd.append("--dirsrv-config-file=%s" % dirsrv_config_file)
|
||||
|
||||
# ssl certificate options
|
||||
for cert_file in dirsrv_cert_files:
|
||||
cmd.append("--dirsrv-cert-file=%s" % cert_file)
|
||||
if dirsrv_pin:
|
||||
cmd.append("--dirsrv-pin=%s" % dirserv_pin)
|
||||
if dirsrv_cert_name:
|
||||
cmd.append("--dirsrv-cert-name=%s" % dirsrv_cert_name)
|
||||
for cert_file in http_cert_files:
|
||||
cmd.append("--http-cert-file=%s" % cert_file)
|
||||
if http_pin:
|
||||
cmd.append("--http-pin=%s" % http_pin)
|
||||
if http_cert_name:
|
||||
cmd.append("--http-cert-name=%s" % http_cert_name)
|
||||
for cert_file in pkinit_cert_files:
|
||||
cmd.append("--pkinit-cert-file=%s" % cert_file)
|
||||
if pkinit_pin:
|
||||
cmd.append("--pkinit-pin=%s" % pkinit_pin)
|
||||
if pkinit_cert_name:
|
||||
cmd.append("--pkinit-cert-name=%s" % pkinit_cert_name)
|
||||
|
||||
# client options
|
||||
if mkhomedir:
|
||||
cmd.append("--mkhomedir")
|
||||
if no_ntp:
|
||||
cmd.append("--no-ntp")
|
||||
if ssh_trust_dns:
|
||||
cmd.append("--ssh-trust-dns")
|
||||
if no_ssh:
|
||||
cmd.append("--no-ssh")
|
||||
if no_sshd:
|
||||
cmd.append("--no-sshd")
|
||||
if no_dns_sshfp:
|
||||
cmd.append("--no-dns-sshfp")
|
||||
|
||||
# certificate system options
|
||||
if external_ca:
|
||||
cmd.append("--external-ca")
|
||||
if external_ca_type:
|
||||
cmd.append("--external-ca-type=%s" % external_ca_type)
|
||||
for cert_file in external_cert_files:
|
||||
cmd.append("--external-cert-file=%s" % cert_file)
|
||||
if subject_base:
|
||||
cmd.append("--subject=%s" % subject)
|
||||
if ca_signing_algorithm:
|
||||
cmd.append("--ca-signing-algorithm=%s" % ca_signing_algorithm)
|
||||
|
||||
# dns options
|
||||
if allow_zone_overlop:
|
||||
cmd.append("--allow-zone-overlap")
|
||||
for reverse_zone in reverse_zones:
|
||||
cmd.append("--reverse-zone=%s" % reverse_zone)
|
||||
if no_reverse:
|
||||
cmd.append("--no-reverse")
|
||||
if auto_reverse:
|
||||
cmd.append("--auto-reverse")
|
||||
if zonemgr:
|
||||
cmd.append("--zonemgr=%s" % zonemgr)
|
||||
for forwarder in forwarders:
|
||||
cmd.append("--forwarder=%s" % forwarder)
|
||||
if no_forwarders:
|
||||
cmd.append("--no-forwarders")
|
||||
if auto_forwarders:
|
||||
cmd.append("--auto-forwarders")
|
||||
if forward_policy:
|
||||
cmd.append("--forward-policy=%s" % forward_policy)
|
||||
if no_dnssec_validation:
|
||||
cmd.append("--no-dnssec-validation")
|
||||
|
||||
# ad trust options
|
||||
#if enable_compat:
|
||||
# cmd.append("--enable-compat")
|
||||
#if netbios_name:
|
||||
# cmd.append("--netbios-name=%s" % netbios_name)
|
||||
#if rid_base:
|
||||
# cmd.append("--rid-base=%s" % rid_base)
|
||||
#if secondary_rid_base:
|
||||
# cmd.append("--secondary-rid-base=%s" % rid_base)
|
||||
|
||||
else: # state == adsent
|
||||
if not is_server_configured():
|
||||
# Nothing to do
|
||||
module.exit_json(changed=False)
|
||||
|
||||
# Server is configured
|
||||
# If in check mode, do nothing but return changed=True
|
||||
if module.check_mode:
|
||||
module.exit_json(changed=True)
|
||||
|
||||
cmd = [
|
||||
module.get_bin_path('ipa-server-install'),
|
||||
"--uninstall",
|
||||
"-U",
|
||||
]
|
||||
|
||||
if ignore_topology_disconnect:
|
||||
cmd.append("--ignore-topology-disconnect")
|
||||
if ignore_last_of_role:
|
||||
cmd.append("--ignore-last-of-role")
|
||||
|
||||
retcode, stdout, stderr = module.run_command(cmd)
|
||||
if retcode != 0:
|
||||
module.fail_json(msg="Failed to uninstall IPA server: %s" % stderr)
|
||||
|
||||
module.exit_json(changed=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
@@ -32,10 +32,19 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: enable_ipa
|
||||
short description:
|
||||
description:
|
||||
module: ipaserver_enable_ipa
|
||||
short description: Enable IPA
|
||||
description: Enable IPA
|
||||
options:
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: no
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,11 +56,15 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, paths, api, sysrestore, tasks,
|
||||
service, bindinstance, redirect_stdout, services
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
hostname=dict(required=False),
|
||||
setup_dns=dict(required=True, type='bool'),
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
@@ -87,9 +100,8 @@ def main():
|
||||
# setup ds ######################################################
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
if NUM_VERSION < 40600:
|
||||
if hasattr(tasks, "configure_tmpfiles"):
|
||||
# Make sure the files we crated in /var/run are recreated at startup
|
||||
tasks.configure_tmpfiles()
|
||||
|
||||
@@ -109,5 +121,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -33,10 +33,12 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaserver_load_cache
|
||||
short description:
|
||||
description:
|
||||
short description: Load cache file
|
||||
description: Load cache file
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,23 +49,27 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
options, paths, read_cache
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
),
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
# set values ############################################################
|
||||
|
||||
### basic ###
|
||||
# basic
|
||||
options.dm_password = ansible_module.params.get('dm_password')
|
||||
|
||||
# restore cache #########################################################
|
||||
@@ -72,7 +78,7 @@ def main():
|
||||
if options.dm_password is None:
|
||||
ansible_module.fail_json(msg="Directory Manager password required")
|
||||
try:
|
||||
cache_vars = read_cache(dm_password)
|
||||
cache_vars = read_cache(options.dm_password)
|
||||
options.__dict__.update(cache_vars)
|
||||
if cache_vars.get('external_ca', False):
|
||||
options.external_ca = False
|
||||
@@ -81,14 +87,15 @@ def main():
|
||||
ansible_module.fail_json(
|
||||
msg="Cannot process the cache file: %s" % str(e))
|
||||
|
||||
kwargs = { "changed": True }
|
||||
kwargs = {"changed": True}
|
||||
for name in options.__dict__:
|
||||
kwargs[name] = options.__dict__[name]
|
||||
ansible_module.exit_json(kwargs)
|
||||
ansible_module.exit_json(**kwargs)
|
||||
|
||||
# done ##################################################################
|
||||
|
||||
ansible_module.exit_json(changed=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -30,14 +30,17 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: master_password
|
||||
module: ipaserver_master_password
|
||||
short description: Generate kerberos master password if not given
|
||||
description:
|
||||
Generate kerberos master password if not given
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
master_password:
|
||||
description: kerberos master password (normally autogenerated)
|
||||
required: false
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -54,16 +57,19 @@ password:
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
options, paths, read_cache, ipa_generate_password
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
#basic
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
master_password=dict(required=False, no_log=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
module._ansible_debug = True
|
||||
@@ -71,9 +77,6 @@ def main():
|
||||
options.dm_password = module.params.get('dm_password')
|
||||
options.master_password = module.params.get('master_password')
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
# This will override any settings passed in on the cmdline
|
||||
if os.path.isfile(paths.ROOT_IPA_CACHE):
|
||||
# dm_password check removed, checked already
|
||||
@@ -89,5 +92,6 @@ def main():
|
||||
module.exit_json(changed=True,
|
||||
password=options.master_password)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -33,37 +33,116 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaserver_prepare
|
||||
short description:
|
||||
description:
|
||||
short description: Prepare IPA server deployment
|
||||
description: Prepare IPA server deployment
|
||||
options:
|
||||
force:
|
||||
description: Installer force parameter
|
||||
required: yes
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: no
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ca_cert_files:
|
||||
description:
|
||||
List of files containing CA certificates for the service certificate
|
||||
files
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
external_ca:
|
||||
description: External ca setting
|
||||
required: yes
|
||||
external_ca_type:
|
||||
description: Type of the external CA
|
||||
required: yes
|
||||
external_ca_profile:
|
||||
description:
|
||||
Specify the certificate profile/template to use at the external CA
|
||||
required: yes
|
||||
external_cert_files:
|
||||
description:
|
||||
File containing the IPA CA certificate and the external CA certificate
|
||||
chain
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: yes
|
||||
ca_subject:
|
||||
description: The installer ca_subject setting
|
||||
required: yes
|
||||
allow_zone_overlap:
|
||||
description: Create DNS zone even if it already exists
|
||||
required: yes
|
||||
reverse_zones:
|
||||
description: The reverse DNS zones to use
|
||||
required: yes
|
||||
no_reverse:
|
||||
description: Do not create new reverse DNS zone
|
||||
required: yes
|
||||
auto_reverse:
|
||||
description: Create necessary reverse zones
|
||||
required: yes
|
||||
forwarders:
|
||||
description: Add DNS forwarders
|
||||
required: yes
|
||||
no_forwarders:
|
||||
description: Do not add any DNS forwarders, use root servers instead
|
||||
required: yes
|
||||
auto_forwarders:
|
||||
description: Use DNS forwarders configured in /etc/resolv.conf
|
||||
required: yes
|
||||
forward_policy:
|
||||
description: DNS forwarding policy for global forwarders
|
||||
required: yes
|
||||
no_dnssec_validation:
|
||||
description: Disable DNSSEC validation
|
||||
required: yes
|
||||
enable_compat:
|
||||
description: Enable support for trusted domains for old clients
|
||||
required: yes
|
||||
netbios_name:
|
||||
description: NetBIOS name of the IPA domain
|
||||
required: yes
|
||||
rid_base:
|
||||
description: Start value for mapping UIDs and GIDs to RIDs
|
||||
required: yes
|
||||
secondary_rid_base:
|
||||
description:
|
||||
Start value of the secondary range for mapping UIDs and GIDs to RIDs
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
_hostname_overridden:
|
||||
description: The installer _hostname_overridden setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -74,13 +153,23 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, sysrestore, paths,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
redirect_stdout, adtrust, api, default_subject_base,
|
||||
default_ca_subject_dn, ipautil, installutils, ca, kra, dns,
|
||||
get_server_ip_address, no_matching_interface_for_ip_address_warning,
|
||||
services, logger, tasks, update_hosts_file, ScriptError
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
force=dict(required=False, type='bool', default=False),
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
password=dict(required=True, no_log=True),
|
||||
@@ -90,19 +179,22 @@ def main():
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool', default=False),
|
||||
setup_kra=dict(required=False, type='bool', default=False),
|
||||
setup_dns=dict(required=False, type='bool', default=False),
|
||||
### ssl certificate ###
|
||||
### client ###
|
||||
### certificate system ###
|
||||
external_ca=dict(required=False),
|
||||
# ssl certificate
|
||||
# client
|
||||
# certificate system
|
||||
external_ca=dict(required=False, type='bool'),
|
||||
external_ca_type=dict(required=False),
|
||||
external_ca_profile=dict(required=False),
|
||||
external_cert_files=dict(required=False, type='list', default=[]),
|
||||
subject_base=dict(required=False),
|
||||
ca_subject=dict(required=False),
|
||||
### dns ###
|
||||
allow_zone_overlap=dict(required=False, type='bool', default=False),
|
||||
# dns
|
||||
allow_zone_overlap=dict(required=False, type='bool',
|
||||
default=False),
|
||||
reverse_zones=dict(required=False, type='list', default=[]),
|
||||
no_reverse=dict(required=False, type='bool', default=False),
|
||||
auto_reverse=dict(required=False, type='bool', default=False),
|
||||
@@ -112,23 +204,29 @@ def main():
|
||||
forward_policy=dict(default=None, choices=['first', 'only']),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
### ad trust ###
|
||||
# ad trust
|
||||
enable_compat=dict(required=False, type='bool', default=False),
|
||||
netbios_name=dict(required=False),
|
||||
rid_base=dict(required=False, type='int'),
|
||||
secondary_rid_base=dict(required=False, type='int'),
|
||||
|
||||
### additional ###
|
||||
# additional
|
||||
setup_ca=dict(required=False, type='bool', default=False),
|
||||
_hostname_overridden=dict(required=False, type='bool',
|
||||
default=False),
|
||||
default=False),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
ansible_log = AnsibleModuleLog(ansible_module)
|
||||
|
||||
# initialize return values for flake ############################
|
||||
|
||||
# These are set by ca.install_check
|
||||
options._subject_base = None
|
||||
options._ca_subject = None
|
||||
|
||||
# set values ####################################################
|
||||
|
||||
options.force = ansible_module.params.get('force')
|
||||
@@ -141,23 +239,28 @@ def main():
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
#options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
### ssl certificate ###
|
||||
#options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
### client ###
|
||||
#options.no_ntp = ansible_module.params.get('no_ntp')
|
||||
### certificate system ###
|
||||
# options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
# ssl certificate
|
||||
# options.dirsrv_cert_files = ansible_module.params.get(
|
||||
# 'dirsrv_cert_files')
|
||||
# client
|
||||
# options.no_ntp = ansible_module.params.get('no_ntp')
|
||||
# certificate system
|
||||
options.external_ca = ansible_module.params.get('external_ca')
|
||||
options.external_ca_type = ansible_module.params.get('external_ca_type')
|
||||
options.external_ca_profile = ansible_module.params.get(
|
||||
'external_ca_profile')
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
options.ca_subject = ansible_module.params.get('ca_subject')
|
||||
### dns ###
|
||||
options.allow_zone_overlap = ansible_module.params.get('allow_zone_overlap')
|
||||
# dns
|
||||
options.allow_zone_overlap = ansible_module.params.get(
|
||||
'allow_zone_overlap')
|
||||
options.reverse_zones = ansible_module.params.get('reverse_zones')
|
||||
options.no_reverse = ansible_module.params.get('no_reverse')
|
||||
options.auto_reverse = ansible_module.params.get('auto_reverse')
|
||||
@@ -167,10 +270,10 @@ def main():
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
### ad trust ###
|
||||
# ad trust
|
||||
options.enable_compat = ansible_module.params.get('enable_compat')
|
||||
options.netbios_name = ansible_module.params.get('netbios_name')
|
||||
### additional ###
|
||||
# additional
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options._host_name_overridden = ansible_module.params.get(
|
||||
'_hostname_overridden')
|
||||
@@ -190,116 +293,126 @@ def main():
|
||||
if not options.ca_subject:
|
||||
options.ca_subject = str(default_ca_subject_dn(options.subject_base))
|
||||
|
||||
# Configuration for ipalib, we will bootstrap and finalize later, after
|
||||
# we are sure we have the configuration file ready.
|
||||
cfg = dict(
|
||||
context='installer',
|
||||
confdir=paths.ETC_IPA,
|
||||
in_server=True,
|
||||
# make sure host name specified by user is used instead of default
|
||||
host=options.host_name,
|
||||
)
|
||||
if options.setup_ca:
|
||||
# we have an IPA-integrated CA
|
||||
cfg['ca_host'] = options.host_name
|
||||
try:
|
||||
|
||||
# Create the management framework config file and finalize api
|
||||
target_fname = paths.IPA_DEFAULT_CONF
|
||||
fd = open(target_fname, "w")
|
||||
fd.write("[global]\n")
|
||||
fd.write("host=%s\n" % options.host_name)
|
||||
fd.write("basedn=%s\n" % ipautil.realm_to_suffix(options.realm_name))
|
||||
fd.write("realm=%s\n" % options.realm_name)
|
||||
fd.write("domain=%s\n" % options.domain_name)
|
||||
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % \
|
||||
ipautil.format_netloc(options.host_name))
|
||||
fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % \
|
||||
installutils.realm_to_serverid(options.realm_name))
|
||||
if options.setup_ca:
|
||||
fd.write("enable_ra=True\n")
|
||||
fd.write("ra_plugin=dogtag\n")
|
||||
fd.write("dogtag_version=10\n")
|
||||
else:
|
||||
fd.write("enable_ra=False\n")
|
||||
fd.write("ra_plugin=none\n")
|
||||
fd.write("mode=production\n")
|
||||
fd.close()
|
||||
# Configuration for ipalib, we will bootstrap and finalize later, after
|
||||
# we are sure we have the configuration file ready.
|
||||
cfg = dict(
|
||||
context='installer',
|
||||
confdir=paths.ETC_IPA,
|
||||
in_server=True,
|
||||
# make sure host name specified by user is used instead of default
|
||||
host=options.host_name,
|
||||
)
|
||||
if options.setup_ca:
|
||||
# we have an IPA-integrated CA
|
||||
cfg['ca_host'] = options.host_name
|
||||
|
||||
# Must be readable for everyone
|
||||
os.chmod(target_fname, 0o644)
|
||||
# Create the management framework config file and finalize api
|
||||
target_fname = paths.IPA_DEFAULT_CONF
|
||||
fd = open(target_fname, "w")
|
||||
fd.write("[global]\n")
|
||||
fd.write("host=%s\n" % options.host_name)
|
||||
fd.write("basedn=%s\n" % ipautil.realm_to_suffix(options.realm_name))
|
||||
fd.write("realm=%s\n" % options.realm_name)
|
||||
fd.write("domain=%s\n" % options.domain_name)
|
||||
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" %
|
||||
ipautil.format_netloc(options.host_name))
|
||||
fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" %
|
||||
installutils.realm_to_serverid(options.realm_name))
|
||||
if options.setup_ca:
|
||||
fd.write("enable_ra=True\n")
|
||||
fd.write("ra_plugin=dogtag\n")
|
||||
fd.write("dogtag_version=10\n")
|
||||
else:
|
||||
fd.write("enable_ra=False\n")
|
||||
fd.write("ra_plugin=none\n")
|
||||
fd.write("mode=production\n")
|
||||
fd.close()
|
||||
|
||||
api.bootstrap(**cfg)
|
||||
api.finalize()
|
||||
# Must be readable for everyone
|
||||
os.chmod(target_fname, 0o644)
|
||||
|
||||
if options.setup_ca:
|
||||
with redirect_stdout(ansible_log):
|
||||
ca.install_check(False, None, options)
|
||||
if options.setup_kra:
|
||||
with redirect_stdout(ansible_log):
|
||||
kra.install_check(api, None, options)
|
||||
api.bootstrap(**cfg)
|
||||
api.finalize()
|
||||
|
||||
if options.setup_dns:
|
||||
with redirect_stdout(ansible_log):
|
||||
dns.install_check(False, api, False, options, options.host_name)
|
||||
ip_addresses = dns.ip_addresses
|
||||
else:
|
||||
ip_addresses = get_server_ip_address(options.host_name,
|
||||
not options.interactive, False,
|
||||
options.ip_addresses)
|
||||
if options.setup_ca:
|
||||
with redirect_stdout(ansible_log):
|
||||
ca.install_check(False, None, options)
|
||||
if options.setup_kra:
|
||||
with redirect_stdout(ansible_log):
|
||||
kra.install_check(api, None, options)
|
||||
|
||||
# check addresses here, dns module is doing own check
|
||||
no_matching_interface_for_ip_address_warning(ip_addresses)
|
||||
options.ip_addresses = ip_addresses
|
||||
options.reverse_zones = dns.reverse_zones
|
||||
if options.setup_dns:
|
||||
with redirect_stdout(ansible_log):
|
||||
dns.install_check(False, api, False, options,
|
||||
options.host_name)
|
||||
ip_addresses = dns.ip_addresses
|
||||
else:
|
||||
ip_addresses = get_server_ip_address(options.host_name,
|
||||
not options.interactive,
|
||||
False,
|
||||
options.ip_addresses)
|
||||
|
||||
instance_name = "-".join(options.realm_name.split("."))
|
||||
dirsrv = services.knownservices.dirsrv
|
||||
if (options.external_cert_files
|
||||
and dirsrv.is_installed(instance_name)
|
||||
and not dirsrv.is_running(instance_name)):
|
||||
logger.debug('Starting Directory Server')
|
||||
services.knownservices.dirsrv.start(instance_name)
|
||||
# check addresses here, dns module is doing own check
|
||||
no_matching_interface_for_ip_address_warning(ip_addresses)
|
||||
options.ip_addresses = ip_addresses
|
||||
options.reverse_zones = dns.reverse_zones
|
||||
|
||||
if options.setup_adtrust:
|
||||
with redirect_stdout(ansible_log):
|
||||
adtrust.install_check(False, options, api)
|
||||
instance_name = "-".join(options.realm_name.split("."))
|
||||
dirsrv = services.knownservices.dirsrv
|
||||
if options.external_cert_files \
|
||||
and dirsrv.is_installed(instance_name) \
|
||||
and not dirsrv.is_running(instance_name):
|
||||
logger.debug('Starting Directory Server')
|
||||
services.knownservices.dirsrv.start(instance_name)
|
||||
|
||||
_update_hosts_file = False
|
||||
# options needs to update hosts file when DNS subsystem will be
|
||||
# installed or custom addresses are used
|
||||
if options.ip_addresses or options.setup_dns:
|
||||
_update_hosts_file = True
|
||||
if options.setup_adtrust:
|
||||
with redirect_stdout(ansible_log):
|
||||
adtrust.install_check(False, options, api)
|
||||
|
||||
if options._host_name_overridden:
|
||||
tasks.backup_hostname(fstore, sstore)
|
||||
tasks.set_hostname(options.host_name)
|
||||
_update_hosts_file = False
|
||||
# options needs to update hosts file when DNS subsystem will be
|
||||
# installed or custom addresses are used
|
||||
if options.ip_addresses or options.setup_dns:
|
||||
_update_hosts_file = True
|
||||
|
||||
if _update_hosts_file:
|
||||
update_hosts_file(ip_addresses, options.host_name, fstore)
|
||||
if options._host_name_overridden:
|
||||
tasks.backup_hostname(fstore, sstore)
|
||||
tasks.set_hostname(options.host_name)
|
||||
|
||||
if hasattr(tasks, "configure_pkcs11_modules"):
|
||||
if tasks.configure_pkcs11_modules(fstore):
|
||||
ansible_log.info("Disabled p11-kit-proxy")
|
||||
if _update_hosts_file:
|
||||
update_hosts_file(ip_addresses, options.host_name, fstore)
|
||||
|
||||
if hasattr(tasks, "configure_pkcs11_modules"):
|
||||
if tasks.configure_pkcs11_modules(fstore):
|
||||
ansible_log.info("Disabled p11-kit-proxy")
|
||||
|
||||
except (RuntimeError, ValueError, ScriptError,
|
||||
ipautil.CalledProcessError) as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
ansible_module.exit_json(
|
||||
changed=True,
|
||||
# basic
|
||||
ip_addresses=[str(ip) for ip in ip_addresses],
|
||||
# certificate system
|
||||
subject_base=options.subject_base,
|
||||
_subject_base=options._subject_base,
|
||||
ca_subject=options.ca_subject,
|
||||
_ca_subject=options._ca_subject,
|
||||
# dns
|
||||
reverse_zones=options.reverse_zones,
|
||||
forward_policy=options.forward_policy,
|
||||
forwarders=options.forwarders,
|
||||
no_dnssec_validation=options.no_dnssec_validation,
|
||||
# additional
|
||||
dns_ip_addresses=[str(ip) for ip
|
||||
in dns.ip_addresses],
|
||||
dns_reverse_zones=dns.reverse_zones,
|
||||
adtrust_netbios_name=adtrust.netbios_name,
|
||||
adtrust_reset_netbios_name=adtrust.reset_netbios_name)
|
||||
|
||||
ansible_module.exit_json(changed=True,
|
||||
### basic ###
|
||||
ip_addresses=[ str(ip) for ip in ip_addresses ],
|
||||
### certificate system ###
|
||||
subject_base=options.subject_base,
|
||||
_subject_base=options._subject_base,
|
||||
ca_subject=options.ca_subject,
|
||||
_ca_subject=options._ca_subject,
|
||||
### dns ###
|
||||
reverse_zones=options.reverse_zones,
|
||||
forward_policy=options.forward_policy,
|
||||
forwarders=options.forwarders,
|
||||
no_dnssec_validation=options.no_dnssec_validation,
|
||||
### additional ###
|
||||
dns_ip_addresses=[ str(ip) for ip
|
||||
in dns.ip_addresses ],
|
||||
dns_reverse_zones=dns.reverse_zones,
|
||||
adtrust_netbios_name=adtrust.netbios_name,
|
||||
adtrust_reset_netbios_name=adtrust.reset_netbios_name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -32,10 +32,68 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: set_ds_password
|
||||
short description:
|
||||
description:
|
||||
module: ipaserver_set_ds_password
|
||||
short description: Set DS password
|
||||
description: Set DS password
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: no
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: no
|
||||
idstart:
|
||||
description: The starting value for the IDs range (default random)
|
||||
required: no
|
||||
idmax:
|
||||
description: The max value for the IDs range (default: idstart+199999)
|
||||
required: no
|
||||
no_hbac_allow:
|
||||
description: Don't install allow_all HBAC rule
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: yes
|
||||
ca_subject:
|
||||
description: The installer ca_subject setting
|
||||
required: yes
|
||||
external_cert_files:
|
||||
description:
|
||||
File containing the IPA CA certificate and the external CA certificate
|
||||
chain
|
||||
required: yes
|
||||
domainlevel:
|
||||
description: The domain level
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,18 +105,22 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
MAX_DOMAIN_LEVEL, AnsibleModuleLog, options, sysrestore, paths,
|
||||
api_Backend_ldap2, ds_init_info, redirect_stdout
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
password=dict(required=True, no_log=True),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
### server ###
|
||||
# server
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
idstart=dict(required=True, type='int'),
|
||||
idmax=dict(required=True, type='int'),
|
||||
@@ -66,13 +128,13 @@ def main():
|
||||
no_pkinit=dict(required=False, type='bool', default=False),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
subject_base=dict(required=False),
|
||||
ca_subject=dict(required=False),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
external_cert_files=dict(required=False, type='list', default=[]),
|
||||
### additional ###
|
||||
# additional
|
||||
domainlevel=dict(required=False, type='int',
|
||||
default=MAX_DOMAIN_LEVEL),
|
||||
),
|
||||
@@ -83,36 +145,36 @@ def main():
|
||||
|
||||
# set values ####################################################
|
||||
|
||||
### basic ###
|
||||
# basic
|
||||
options.dm_password = ansible_module.params.get('dm_password')
|
||||
options.admin_password = ansible_module.params.get('password')
|
||||
options.domain_name = ansible_module.params.get('domain')
|
||||
options.realm_name = ansible_module.params.get('realm')
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.idstart = ansible_module.params.get('idstart')
|
||||
options.idmax = ansible_module.params.get('idmax')
|
||||
options.no_hbac_allow = ansible_module.params.get('no_hbac_allow')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
options._dirsrv_pkcs12_info = ansible_module.params.get(
|
||||
'_dirsrv_pkcs12_info')
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
options.ca_subject = ansible_module.params.get('ca_subject')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
### additional ###
|
||||
# additional
|
||||
options.domainlevel = ansible_module.params.get('domainlevel')
|
||||
options.domain_level = options.domainlevel
|
||||
|
||||
# init ##########################################################
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
|
||||
|
||||
@@ -134,5 +196,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -32,10 +32,35 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: setup_adtrust
|
||||
short description:
|
||||
description:
|
||||
module: ipaserver_setup_adtrust
|
||||
short description: Setup trust ad
|
||||
description: Setup trust ad
|
||||
options:
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
enable_compat:
|
||||
description: Enable support for trusted domains for old clients
|
||||
required: yes
|
||||
rid_base:
|
||||
description: Start value for mapping UIDs and GIDs to RIDs
|
||||
required: yes
|
||||
secondary_rid_base:
|
||||
description:
|
||||
Start value of the secondary range for mapping UIDs and GIDs to RIDs
|
||||
required: yes
|
||||
adtrust_netbios_name:
|
||||
description: The adtrust netbios_name setting
|
||||
required: no
|
||||
adtrust_reset_netbios_name:
|
||||
description: The adtrust reset_netbios_name setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,22 +72,26 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, sysrestore, paths,
|
||||
api_Backend_ldap2, redirect_stdout, adtrust, api
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
hostname=dict(required=False),
|
||||
setup_ca=dict(required=False, type='bool', default=False),
|
||||
setup_adtrust=dict(required=False, type='bool', default=False),
|
||||
### ad trust ###
|
||||
# ad trust
|
||||
enable_compat=dict(required=False, type='bool', default=False),
|
||||
rid_base=dict(required=False, type='int'),
|
||||
secondary_rid_base=dict(required=False, type='int'),
|
||||
### additional ###
|
||||
# additional
|
||||
adtrust_netbios_name=dict(required=True),
|
||||
adtrust_reset_netbios_name=dict(required=True, type='bool')
|
||||
adtrust_reset_netbios_name=dict(required=True, type='bool'),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -74,19 +103,19 @@ def main():
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
### ad trust ###
|
||||
# ad trust
|
||||
options.enable_compat = ansible_module.params.get('enable_compat')
|
||||
options.rid_base = ansible_module.params.get('rid_base')
|
||||
options.secondary_rid_base = ansible_module.params.get('secondary_rid_base')
|
||||
### additional ###
|
||||
options.secondary_rid_base = ansible_module.params.get(
|
||||
'secondary_rid_base')
|
||||
# additional
|
||||
adtrust.netbios_name = ansible_module.params.get('adtrust_netbios_name')
|
||||
adtrust.reset_netbios_name = \
|
||||
ansible_module.params.get('adtrust_reset_netbios_name')
|
||||
adtrust.reset_netbios_name = ansible_module.params.get(
|
||||
'adtrust_reset_netbios_name')
|
||||
|
||||
# init ##########################################################
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
|
||||
|
||||
@@ -99,5 +128,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -33,39 +33,119 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaserver_setup_ca
|
||||
short description:
|
||||
description:
|
||||
short description: Setup CA
|
||||
description: Setup CA
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: no
|
||||
master_password:
|
||||
description: kerberos master password (normally autogenerated)
|
||||
required: no
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
pki_config_override:
|
||||
description: Path to ini file with config overrides
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
idstart:
|
||||
description: The starting value for the IDs range (default random)
|
||||
required: no
|
||||
idmax:
|
||||
description: The max value for the IDs range (default: idstart+199999)
|
||||
required: no
|
||||
no_hbac_allow:
|
||||
description: Don't install allow_all HBAC rule
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
external_ca:
|
||||
description: External ca setting
|
||||
required: yes
|
||||
external_ca_type:
|
||||
description: Type of the external CA
|
||||
required: yes
|
||||
external_ca_profile:
|
||||
description:
|
||||
Specify the certificate profile/template to use at the external CA
|
||||
required: yes
|
||||
external_cert_files:
|
||||
description:
|
||||
File containing the IPA CA certificate and the external CA certificate
|
||||
chain
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: yes
|
||||
_subject_base:
|
||||
description: The installer _subject_base setting
|
||||
required: yes
|
||||
ca_subject:
|
||||
description: The installer ca_subject setting
|
||||
required: yes
|
||||
_ca_subject:
|
||||
description: The installer _ca_subject setting
|
||||
required: yes
|
||||
ca_signing_algorithm:
|
||||
description: Signing algorithm of the IPA CA certificate
|
||||
required: yes
|
||||
reverse_zones:
|
||||
description: The reverse DNS zones to use
|
||||
required: yes
|
||||
no_reverse:
|
||||
description: Do not create new reverse DNS zone
|
||||
required: yes
|
||||
auto_forwarders:
|
||||
description: Use DNS forwarders configured in /etc/resolv.conf
|
||||
required: yes
|
||||
domainlevel:
|
||||
description: The domain level
|
||||
required: yes
|
||||
_http_ca_cert:
|
||||
description: The installer _http_ca_cert setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -76,13 +156,21 @@ EXAMPLES = '''
|
||||
RETURN = '''
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, sysrestore, paths,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
api_Backend_ldap2, redirect_stdout, ca, installutils, ds_init_info,
|
||||
custodiainstance, write_cache, x509
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
password=dict(required=True, no_log=True),
|
||||
master_password=dict(required=True, no_log=True),
|
||||
@@ -92,7 +180,7 @@ def main():
|
||||
hostname=dict(required=False),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
pki_config_override=dict(required=False),
|
||||
### server ###
|
||||
# server
|
||||
setup_adtrust=dict(required=False, type='bool', default=False),
|
||||
setup_kra=dict(required=False, type='bool', default=False),
|
||||
setup_dns=dict(required=False, type='bool', default=False),
|
||||
@@ -104,19 +192,22 @@ def main():
|
||||
dirsrv_config_file=dict(required=False),
|
||||
dirsrv_cert_files=dict(required=False, type='list'),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
external_ca=dict(required=False, type='bool', default=False),
|
||||
external_cert_files=dict(required=False, type='list', default=[]),
|
||||
external_ca_type=dict(required=False),
|
||||
external_ca_profile=dict(required=False),
|
||||
external_cert_files=dict(required=False, type='list',
|
||||
default=None),
|
||||
subject_base=dict(required=False),
|
||||
_subject_base=dict(required=False),
|
||||
ca_subject=dict(required=False),
|
||||
_ca_subject=dict(required=False),
|
||||
ca_signing_algorithm=dict(required=False),
|
||||
### dns ###
|
||||
# dns
|
||||
reverse_zones=dict(required=False, type='list', default=[]),
|
||||
no_reverse=dict(required=False, type='bool', default=False),
|
||||
auto_forwarders=dict(required=False, type='bool', default=False),
|
||||
### additional ###
|
||||
# additional
|
||||
domainlevel=dict(required=False, type='int'),
|
||||
_http_ca_cert=dict(required=False),
|
||||
),
|
||||
@@ -127,7 +218,7 @@ def main():
|
||||
|
||||
# set values ############################################################
|
||||
|
||||
### basic ###
|
||||
# basic
|
||||
options.dm_password = ansible_module.params.get('dm_password')
|
||||
options.admin_password = ansible_module.params.get('password')
|
||||
options.master_password = ansible_module.params.get('master_password')
|
||||
@@ -139,7 +230,7 @@ def main():
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
options.pki_config_override = ansible_module.params.get(
|
||||
'pki_config_override')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
@@ -148,12 +239,16 @@ def main():
|
||||
options.idmax = ansible_module.params.get('idmax')
|
||||
options.no_hbac_allow = ansible_module.params.get('no_hbac_allow')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
options._dirsrv_pkcs12_info = ansible_module.params.get(
|
||||
'_dirsrv_pkcs12_info')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.external_ca = ansible_module.params.get('external_ca')
|
||||
options.external_ca_type = ansible_module.params.get('external_ca_type')
|
||||
options.external_ca_profile = ansible_module.params.get(
|
||||
'external_ca_profile')
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
@@ -162,19 +257,27 @@ def main():
|
||||
options._ca_subject = ansible_module.params.get('_ca_subject')
|
||||
options.ca_signing_algorithm = ansible_module.params.get(
|
||||
'ca_signing_algorithm')
|
||||
### dns ###
|
||||
# dns
|
||||
options.reverse_zones = ansible_module.params.get('reverse_zones')
|
||||
options.no_reverse = ansible_module.params.get('no_reverse')
|
||||
options.auto_forwarders = ansible_module.params.get('auto_forwarders')
|
||||
### additional ###
|
||||
# additional
|
||||
options.domainlevel = ansible_module.params.get('domainlevel')
|
||||
options._http_ca_cert = ansible_module.params.get('_http_ca_cert')
|
||||
#options._update_hosts_file = ansible_module.params.get('update_hosts_file')
|
||||
# tions._update_hosts_file = ansible_module.params.get(
|
||||
# 'update_hosts_file')
|
||||
|
||||
# init #################################################################
|
||||
|
||||
options.promote = False # first master, no promotion
|
||||
|
||||
# Repeat from ca.install_check
|
||||
# ca.external_cert_file and ca.external_ca_file need to be set
|
||||
if options.external_cert_files:
|
||||
ca.external_cert_file, ca.external_ca_file = \
|
||||
installutils.load_external_cert(
|
||||
options.external_cert_files, options._ca_subject)
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
|
||||
api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
|
||||
@@ -190,53 +293,62 @@ def main():
|
||||
|
||||
# setup CA ##############################################################
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
if hasattr(custodiainstance, "get_custodia_instance"):
|
||||
if hasattr(custodiainstance.CustodiaModes, "FIRST_MASTER"):
|
||||
mode = custodiainstance.CustodiaModes.FIRST_MASTER
|
||||
else:
|
||||
mode = custodiainstance.CustodiaModes.MASTER_PEER
|
||||
custodia = custodiainstance.get_custodia_instance(options, mode)
|
||||
if hasattr(custodiainstance, "get_custodia_instance"):
|
||||
if hasattr(custodiainstance.CustodiaModes, "FIRST_MASTER"):
|
||||
mode = custodiainstance.CustodiaModes.FIRST_MASTER
|
||||
else:
|
||||
mode = custodiainstance.CustodiaModes.MASTER_PEER
|
||||
custodia = custodiainstance.get_custodia_instance(options, mode)
|
||||
custodia.set_output(ansible_log)
|
||||
with redirect_stdout(ansible_log):
|
||||
custodia.create_instance()
|
||||
|
||||
if options.setup_ca:
|
||||
if not options.external_cert_files and options.external_ca:
|
||||
# stage 1 of external CA installation
|
||||
cache_vars = {n: options.__dict__[n] for o, n in options.knobs()
|
||||
if n in options.__dict__}
|
||||
write_cache(cache_vars)
|
||||
if options.setup_ca:
|
||||
if not options.external_cert_files and options.external_ca:
|
||||
# stage 1 of external CA installation
|
||||
cache_vars = {n: options.__dict__[n] for o, n in options.knobs()
|
||||
if n in options.__dict__}
|
||||
write_cache(cache_vars)
|
||||
|
||||
if hasattr(custodiainstance, "get_custodia_instance"):
|
||||
ca.install_step_0(False, None, options, custodia=custodia)
|
||||
else:
|
||||
ca.install_step_0(False, None, options)
|
||||
try:
|
||||
with redirect_stdout(ansible_log):
|
||||
if hasattr(custodiainstance, "get_custodia_instance"):
|
||||
ca.install_step_0(False, None, options, custodia=custodia)
|
||||
else:
|
||||
ca.install_step_0(False, None, options)
|
||||
except SystemExit:
|
||||
ansible_module.exit_json(changed=True,
|
||||
csr_generated=True)
|
||||
else:
|
||||
# Put the CA cert where other instances expect it
|
||||
x509.write_certificate(options._http_ca_cert, paths.IPA_CA_CRT)
|
||||
os.chmod(paths.IPA_CA_CRT, 0o444)
|
||||
|
||||
if not options.no_pkinit:
|
||||
x509.write_certificate(options._http_ca_cert,
|
||||
paths.KDC_CA_BUNDLE_PEM)
|
||||
else:
|
||||
# Put the CA cert where other instances expect it
|
||||
x509.write_certificate(options._http_ca_cert, paths.IPA_CA_CRT)
|
||||
os.chmod(paths.IPA_CA_CRT, 0o444)
|
||||
with open(paths.KDC_CA_BUNDLE_PEM, 'w'):
|
||||
pass
|
||||
os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444)
|
||||
|
||||
if not options.no_pkinit:
|
||||
x509.write_certificate(options._http_ca_cert,
|
||||
paths.KDC_CA_BUNDLE_PEM)
|
||||
else:
|
||||
with open(paths.KDC_CA_BUNDLE_PEM, 'w'):
|
||||
pass
|
||||
os.chmod(paths.KDC_CA_BUNDLE_PEM, 0o444)
|
||||
|
||||
x509.write_certificate(options._http_ca_cert, paths.CA_BUNDLE_PEM)
|
||||
os.chmod(paths.CA_BUNDLE_PEM, 0o444)
|
||||
x509.write_certificate(options._http_ca_cert, paths.CA_BUNDLE_PEM)
|
||||
os.chmod(paths.CA_BUNDLE_PEM, 0o444)
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
# we now need to enable ssl on the ds
|
||||
ds.enable_ssl()
|
||||
|
||||
if options.setup_ca:
|
||||
with redirect_stdout(ansible_log):
|
||||
if hasattr(custodiainstance, "get_custodia_instance"):
|
||||
ca.install_step_1(False, None, options, custodia=custodia)
|
||||
else:
|
||||
ca.install_step_1(False, None, options)
|
||||
if options.setup_ca:
|
||||
with redirect_stdout(ansible_log):
|
||||
if hasattr(custodiainstance, "get_custodia_instance"):
|
||||
ca.install_step_1(False, None, options, custodia=custodia)
|
||||
else:
|
||||
ca.install_step_1(False, None, options)
|
||||
|
||||
ansible_module.exit_json(changed=True,
|
||||
csr_generated=False)
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -33,12 +33,18 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaserver_setup_custodia
|
||||
short description:
|
||||
description:
|
||||
short description: Setup custodia
|
||||
description: Setup custodia
|
||||
options:
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -50,11 +56,16 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options,
|
||||
api_Backend_ldap2,
|
||||
custodiainstance, redirect_stdout
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=False),
|
||||
@@ -74,8 +85,6 @@ def main():
|
||||
|
||||
# init ##################################################################
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
|
||||
api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
|
||||
|
||||
# setup custodia ########################################################
|
||||
@@ -97,5 +106,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -32,17 +32,46 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: setup_dns
|
||||
short description:
|
||||
description:
|
||||
module: ipaserver_setup_dns
|
||||
short description: Setup DNS
|
||||
description: Setup DNS
|
||||
options:
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: no
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: no
|
||||
zonemgr:
|
||||
description: DNS zone manager e-mail address. Defaults to hostmaster@DOMAIN
|
||||
required: yes
|
||||
forwarders:
|
||||
description: Add DNS forwarders
|
||||
required: no
|
||||
forward_policy:
|
||||
description: DNS forwarding policy for global forwarders
|
||||
required: yes
|
||||
no_dnssec_validation:
|
||||
description: Disable DNSSEC validation
|
||||
required: yes
|
||||
dns_ip_addresses:
|
||||
description: The dns ip_addresses setting
|
||||
required: no
|
||||
dns_reverse_zones:
|
||||
description: The dns reverse_zones setting
|
||||
required: no
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -54,23 +83,31 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, paths, dns,
|
||||
ansible_module_get_parsed_ip_addresses, sysrestore, api_Backend_ldap2,
|
||||
redirect_stdout, bindinstance
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=True),
|
||||
### server ###
|
||||
# server
|
||||
setup_dns=dict(required=True, type='bool'),
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
### dns ###
|
||||
# dns
|
||||
zonemgr=dict(required=False),
|
||||
forwarders=dict(required=True, type='list'),
|
||||
forward_policy=dict(default='first', choices=['first', 'only']),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
### additional ###
|
||||
# additional
|
||||
dns_ip_addresses=dict(required=True, type='list'),
|
||||
dns_reverse_zones=dict(required=True, type='list'),
|
||||
),
|
||||
@@ -81,18 +118,22 @@ def main():
|
||||
|
||||
# set values ############################################################
|
||||
|
||||
### basic ###
|
||||
# basic
|
||||
options.ip_addresses = ansible_module_get_parsed_ip_addresses(
|
||||
ansible_module)
|
||||
options.domain_name = ansible_module.params.get('domain')
|
||||
options.realm_name = ansible_module.params.get('realm')
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
### server ###
|
||||
# server
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
### dns ###
|
||||
# dns
|
||||
options.zonemgr = ansible_module.params.get('zonemgr')
|
||||
options.forwarders = ansible_module.params.get('forwarders')
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
### additional ###
|
||||
# additional
|
||||
dns.ip_addresses = ansible_module_get_parsed_ip_addresses(
|
||||
ansible_module, 'dns_ip_addresses')
|
||||
dns.reverse_zones = ansible_module.params.get('dns_reverse_zones')
|
||||
@@ -112,8 +153,9 @@ def main():
|
||||
# Create a BIND instance
|
||||
bind = bindinstance.BindInstance(fstore)
|
||||
bind.set_output(ansible_log)
|
||||
bind.setup(host_name, ip_addresses, realm_name,
|
||||
domain_name, (), 'first', (),
|
||||
bind.setup(options.host_name, options.ip_addresses,
|
||||
options.realm_name,
|
||||
options.domain_name, (), 'first', (),
|
||||
zonemgr=options.zonemgr,
|
||||
no_dnssec_validation=options.no_dnssec_validation)
|
||||
bind.create_file_with_system_records()
|
||||
@@ -122,5 +164,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -33,21 +33,64 @@ ANSIBLE_METADATA = {
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: ipaserver_setup_ds
|
||||
short description:
|
||||
description:
|
||||
short description: Configure directory server
|
||||
description: Configure directory server
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: no
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
idstart:
|
||||
description: The starting value for the IDs range (default random)
|
||||
required: no
|
||||
idmax:
|
||||
no_pkinit:
|
||||
description: The max value for the IDs range (default: idstart+199999)
|
||||
required: no
|
||||
no_hbac_allow:
|
||||
description: Don't install allow_all HBAC rule
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
external_cert_files:
|
||||
description:
|
||||
File containing the IPA CA certificate and the external CA certificate
|
||||
chain
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: yes
|
||||
ca_subject:
|
||||
setup_ca
|
||||
description: The installer ca_subject setting
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -59,31 +102,37 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, sysrestore, paths,
|
||||
api_Backend_ldap2, redirect_stdout, api, NUM_VERSION, tasks,
|
||||
dsinstance, ntpinstance, IPAAPI_USER
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
### basic ###
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
password=dict(required=True, no_log=True),
|
||||
domain=dict(required=True),
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=False),
|
||||
### server ###
|
||||
# server
|
||||
idstart=dict(required=True, type='int'),
|
||||
idmax=dict(required=True, type='int'),
|
||||
no_hbac_allow=dict(required=False, type='bool', default=False),
|
||||
no_pkinit=dict(required=False, type='bool', default=False),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
### ssl certificate ###
|
||||
# ssl certificate
|
||||
dirsrv_cert_files=dict(required=False, type='list', default=[]),
|
||||
### certificate system ###
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
# certificate system
|
||||
external_cert_files=dict(required=False, type='list', default=[]),
|
||||
subject_base=dict(required=False),
|
||||
ca_subject=dict(required=False),
|
||||
|
||||
### additional ###
|
||||
# additional
|
||||
setup_ca=dict(required=False, type='bool', default=False),
|
||||
),
|
||||
)
|
||||
@@ -93,26 +142,29 @@ def main():
|
||||
|
||||
# set values ############################################################
|
||||
|
||||
### basic ###
|
||||
# basic
|
||||
options.dm_password = ansible_module.params.get('dm_password')
|
||||
options.domain_name = ansible_module.params.get('domain')
|
||||
options.realm_name = ansible_module.params.get('realm')
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
### server ###
|
||||
# server
|
||||
options.idstart = ansible_module.params.get('idstart')
|
||||
options.idmax = ansible_module.params.get('idmax')
|
||||
options.no_pkinit = ansible_module.params.get('no_pkinit')
|
||||
options.no_hbac_allow = ansible_module.params.get('no_hbac_allow')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
### ssl certificate ###
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
options._dirsrv_pkcs12_info = ansible_module.params.get(
|
||||
'_dirsrv_pkcs12_info')
|
||||
# ssl certificate
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
### certificate system ###
|
||||
# certificate system
|
||||
options.external_cert_files = ansible_module.params.get(
|
||||
'external_cert_files')
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
options.ca_subject = ansible_module.params.get('ca_subject')
|
||||
|
||||
### additional ###
|
||||
# additional
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
|
||||
# init ##################################################################
|
||||
@@ -127,7 +179,7 @@ def main():
|
||||
# Make sure tmpfiles dir exist before installing components
|
||||
if NUM_VERSION == 40504:
|
||||
tasks.create_tmpfiles_dirs(IPAAPI_USER)
|
||||
elif NUM_VERSION >= 40500 and NUM_VERSION <= 40503:
|
||||
elif 40500 <= NUM_VERSION <= 40503:
|
||||
tasks.create_tmpfiles_dirs()
|
||||
|
||||
# Create a directory server instance
|
||||
@@ -138,9 +190,9 @@ def main():
|
||||
ds.set_output(ansible_log)
|
||||
|
||||
if options.dirsrv_cert_files:
|
||||
_dirsrv_pkcs12_info=options.dirsrv_pkcs12_info
|
||||
_dirsrv_pkcs12_info = options._dirsrv_pkcs12_info
|
||||
else:
|
||||
_dirsrv_pkcs12_info=None
|
||||
_dirsrv_pkcs12_info = None
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
ds.create_instance(options.realm_name, options.host_name,
|
||||
@@ -173,5 +225,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -32,10 +32,111 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: setup_ds
|
||||
short description:
|
||||
description:
|
||||
module: ipaserver_setup_http
|
||||
short description: Setup HTTP
|
||||
description: Setup HTTP
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: no
|
||||
master_password:
|
||||
description: kerberos master password (normally autogenerated)
|
||||
required: no
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
reverse_zones:
|
||||
description: The reverse DNS zones to use
|
||||
required: yes
|
||||
http_cert_files:
|
||||
description:
|
||||
File containing the Apache Server SSL certificate and private key
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_hbac_allow:
|
||||
description: Don't install allow_all HBAC rule
|
||||
required: yes
|
||||
no_ui_redirect:
|
||||
description: Do not automatically redirect to the Web UI
|
||||
required: yes
|
||||
external_cert_files:
|
||||
description:
|
||||
File containing the IPA CA certificate and the external CA certificate
|
||||
chain
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: yes
|
||||
_subject_base:
|
||||
description: The installer _subject_base setting
|
||||
required: yes
|
||||
ca_subject:
|
||||
description: The installer ca_subject setting
|
||||
required: yes
|
||||
_ca_subject:
|
||||
description: The installer _ca_subject setting
|
||||
required: yes
|
||||
idstart:
|
||||
description: The starting value for the IDs range (default random)
|
||||
required: no
|
||||
idmax:
|
||||
description: The max value for the IDs range (default: idstart+199999)
|
||||
required: no
|
||||
domainlevel:
|
||||
description: The domain level
|
||||
required: yes
|
||||
dirsrv_config_file:
|
||||
description:
|
||||
The path to LDIF file that will be used to modify configuration of
|
||||
dse.ldif during installation of the directory server instance
|
||||
required: yes
|
||||
dirsrv_cert_files:
|
||||
description:
|
||||
Files containing the Directory Server SSL certificate and private key
|
||||
required: yes
|
||||
no_reverse:
|
||||
description: Do not create new reverse DNS zone
|
||||
required: yes
|
||||
auto_forwarders:
|
||||
description: Use DNS forwarders configured in /etc/resolv.conf
|
||||
required: yes
|
||||
_dirsrv_pkcs12_info:
|
||||
description: The installer _dirsrv_pkcs12_info setting
|
||||
required: yes
|
||||
_http_pkcs12_info:
|
||||
description: The installer _http_pkcs12_info setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,11 +148,17 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, sysrestore, paths,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
api_Backend_ldap2, redirect_stdout, ds_init_info,
|
||||
krbinstance, httpinstance, ca, service, tasks
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
password=dict(required=True, no_log=True),
|
||||
@@ -90,8 +197,10 @@ def main():
|
||||
no_reverse=dict(required=False, type='bool', default=False),
|
||||
auto_forwarders=dict(required=False, type='bool', default=False),
|
||||
|
||||
#_update_hosts_file=dict(required=False, type='bool', default=False),
|
||||
# _update_hosts_file=dict(required=False, type='bool',
|
||||
# default=False),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
_http_pkcs12_info=dict(required=False),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -135,12 +244,16 @@ def main():
|
||||
options.idstart = ansible_module.params.get('idstart')
|
||||
options.idmax = ansible_module.params.get('idmax')
|
||||
options.domainlevel = ansible_module.params.get('domainlevel')
|
||||
options.dirsrv_config_file = ansible_module.params.get('dirsrv_config_file')
|
||||
options.dirsrv_config_file = ansible_module.params.get(
|
||||
'dirsrv_config_file')
|
||||
options.dirsrv_cert_files = ansible_module.params.get('dirsrv_cert_files')
|
||||
|
||||
#options._update_hosts_file = ansible_module.params.get('_update_hosts_file')
|
||||
# options._update_hosts_file = ansible_module.params.get(
|
||||
# '_update_hosts_file')
|
||||
options._dirsrv_pkcs12_info = ansible_module.params.get(
|
||||
'_dirsrv_pkcs12_info')
|
||||
options._http_pkcs12_info = ansible_module.params.get(
|
||||
'_http_pkcs12_info')
|
||||
|
||||
# init ##################################################################
|
||||
|
||||
@@ -173,13 +286,16 @@ def main():
|
||||
with redirect_stdout(ansible_log):
|
||||
if options.http_cert_files:
|
||||
http.create_instance(
|
||||
options.realm_name, options.host_name, options.domain_name, options.dm_password,
|
||||
pkcs12_info=options._http_pkcs12_info, subject_base=options.subject_base,
|
||||
options.realm_name, options.host_name, options.domain_name,
|
||||
options.dm_password,
|
||||
pkcs12_info=options._http_pkcs12_info,
|
||||
subject_base=options.subject_base,
|
||||
auto_redirect=not options.no_ui_redirect,
|
||||
ca_is_configured=options.setup_ca)
|
||||
else:
|
||||
http.create_instance(
|
||||
options.realm_name, options.host_name, options.domain_name, options.dm_password,
|
||||
options.realm_name, options.host_name, options.domain_name,
|
||||
options.dm_password,
|
||||
subject_base=options.subject_base,
|
||||
auto_redirect=not options.no_ui_redirect,
|
||||
ca_is_configured=options.setup_ca)
|
||||
@@ -204,5 +320,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -32,10 +32,28 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: setup_kra
|
||||
short description:
|
||||
description:
|
||||
module: ipaserver_setup_kra
|
||||
short description: Setup KRA
|
||||
description: Setup KRA
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: no
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: no
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
pki_config_override:
|
||||
description: Path to ini file with config overrides
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,11 +65,15 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options,
|
||||
api_Backend_ldap2, redirect_stdout, api, custodiainstance, kra
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
hostname=dict(required=True),
|
||||
@@ -78,18 +100,17 @@ def main():
|
||||
|
||||
# init ##########################################################
|
||||
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
|
||||
|
||||
# setup kra #####################################################
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
if hasattr(custodiainstance, "get_custodia_instance"):
|
||||
custodia = custodiainstance.get_custodia_instance(
|
||||
options, custodiainstance.CustodiaModes.MASTER_PEER)
|
||||
custodia.create_instance()
|
||||
if hasattr(custodiainstance.CustodiaModes, "FIRST_MASTER"):
|
||||
mode = custodiainstance.CustodiaModes.FIRST_MASTER
|
||||
else:
|
||||
mode = custodiainstance.CustodiaModes.MASTER_PEER
|
||||
custodia = custodiainstance.get_custodia_instance(options, mode)
|
||||
|
||||
kra.install(api, None, options, custodia=custodia)
|
||||
else:
|
||||
@@ -99,5 +120,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -32,10 +32,83 @@ ANSIBLE_METADATA = {
|
||||
|
||||
DOCUMENTATION = '''
|
||||
---
|
||||
module: setup_ds
|
||||
short description:
|
||||
description:
|
||||
module: ipaserver_setup_krb
|
||||
short description: Setup KRB
|
||||
description: Setup KRB
|
||||
options:
|
||||
dm_password:
|
||||
description: Directory Manager password
|
||||
required: no
|
||||
password:
|
||||
description: Admin user kerberos password
|
||||
required: no
|
||||
master_password:
|
||||
description: kerberos master password (normally autogenerated)
|
||||
required: no
|
||||
domain:
|
||||
description: Primary DNS domain of the IPA deployment
|
||||
required: no
|
||||
realm:
|
||||
description: Kerberos realm name of the IPA deployment
|
||||
required: no
|
||||
hostname:
|
||||
description: Fully qualified name of this host
|
||||
required: yes
|
||||
ip_addresses:
|
||||
description: List of Master Server IP Addresses
|
||||
required: yes
|
||||
reverse_zones:
|
||||
description: The reverse DNS zones to use
|
||||
required: yes
|
||||
setup_adtrust:
|
||||
description: Configure AD trust capability
|
||||
required: yes
|
||||
setup_kra:
|
||||
description: Configure a dogtag KRA
|
||||
required: yes
|
||||
setup_dns:
|
||||
description: Configure bind with our zone
|
||||
required: yes
|
||||
setup_ca:
|
||||
description: Configure a dogtag CA
|
||||
required: yes
|
||||
no_host_dns:
|
||||
description: Do not use DNS for hostname lookup during installation
|
||||
required: yes
|
||||
no_pkinit:
|
||||
description: Disable pkinit setup steps
|
||||
required: yes
|
||||
no_hbac_allow:
|
||||
description: Don't install allow_all HBAC rule
|
||||
required: yes
|
||||
external_cert_files:
|
||||
description:
|
||||
File containing the IPA CA certificate and the external CA certificate
|
||||
chain
|
||||
required: yes
|
||||
subject_base:
|
||||
description:
|
||||
The certificate subject base (default O=<realm-name>).
|
||||
RDNs are in LDAP order (most specific RDN first).
|
||||
required: yes
|
||||
ca_subject:
|
||||
description: The installer ca_subject setting
|
||||
required: yes
|
||||
idstart:
|
||||
description: The starting value for the IDs range (default random)
|
||||
required: no
|
||||
idmax:
|
||||
description: The max value for the IDs range (default: idstart+199999)
|
||||
required: no
|
||||
no_reverse:
|
||||
description: Do not create new reverse DNS zone
|
||||
required: yes
|
||||
auto_forwarders:
|
||||
description: Use DNS forwarders configured in /etc/resolv.conf
|
||||
required: yes
|
||||
_pkinit_pkcs12_info:
|
||||
description: The installer _pkinit_pkcs12_info setting
|
||||
required: yes
|
||||
author:
|
||||
- Thomas Woerner
|
||||
'''
|
||||
@@ -47,11 +120,16 @@ RETURN = '''
|
||||
'''
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import *
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
AnsibleModuleLog, options, sysrestore, paths,
|
||||
ansible_module_get_parsed_ip_addresses,
|
||||
api_Backend_ldap2, redirect_stdout, krbinstance
|
||||
)
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
argument_spec=dict(
|
||||
# basic
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
password=dict(required=True, no_log=True),
|
||||
@@ -125,7 +203,8 @@ def main():
|
||||
options._pkinit_pkcs12_info = ansible_module.params.get(
|
||||
'_pkinit_pkcs12_info')
|
||||
|
||||
#options._update_hosts_file = ansible_module.params.get('update_hosts_file')
|
||||
# options._update_hosts_file = ansible_module.params.get(
|
||||
# 'update_hosts_file')
|
||||
|
||||
# init ##################################################################
|
||||
|
||||
@@ -152,5 +231,6 @@ def main():
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user