mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-05-14 13:32:10 +00:00
Compare commits
1 Commits
v0.2.0
...
fix-role-r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
dd6dd1fd84 |
@@ -1,23 +0,0 @@
|
|||||||
exclude_paths:
|
|
||||||
- roles
|
|
||||||
- .tox
|
|
||||||
- .venv
|
|
||||||
|
|
||||||
parseable: true
|
|
||||||
|
|
||||||
quiet: false
|
|
||||||
|
|
||||||
skip_list:
|
|
||||||
- '201' # Trailing whitespace
|
|
||||||
- '204' # Lines should be no longer than 160 chars
|
|
||||||
- '206' # Variables should have spaces before and after: {{ var_name }}'
|
|
||||||
- '208' # File permissions not mentioned
|
|
||||||
- '301' # Commands should not change things if nothing needs doing'
|
|
||||||
- '305' # Use shell only when shell functionality is required'
|
|
||||||
- '306' # Shells that use pipes should set the pipefail option'
|
|
||||||
- '502' # All tasks should be named
|
|
||||||
- '505' # Referenced missing file
|
|
||||||
|
|
||||||
use_default_rules: true
|
|
||||||
|
|
||||||
verbosity: 1
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
srpm:
|
|
||||||
# Setup development environment
|
|
||||||
echo "Installing base development environment"
|
|
||||||
dnf install -y dnf-plugins-core git-all
|
|
||||||
echo "Call SRPM build Script"
|
|
||||||
./utils/build-srpm.sh
|
|
||||||
if [[ "${outdir}" != "" ]]; then \
|
|
||||||
mv /builddir/build/SRPMS/* ${outdir}; \
|
|
||||||
fi
|
|
||||||
33
.github/workflows/lint.yml
vendored
33
.github/workflows/lint.yml
vendored
@@ -1,33 +0,0 @@
|
|||||||
---
|
|
||||||
name: Run Linters
|
|
||||||
on:
|
|
||||||
- push
|
|
||||||
- pull_request
|
|
||||||
jobs:
|
|
||||||
linters:
|
|
||||||
name: Run Linters
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
steps:
|
|
||||||
- uses: actions/checkout@v2
|
|
||||||
- uses: actions/setup-python@v2
|
|
||||||
with:
|
|
||||||
python-version: "3.6"
|
|
||||||
|
|
||||||
- name: Run ansible-lint
|
|
||||||
uses: ansible/ansible-lint-action@master
|
|
||||||
with:
|
|
||||||
targets: |
|
|
||||||
tests/*.yml
|
|
||||||
tests/*/*.yml
|
|
||||||
tests/*/*/*.yml
|
|
||||||
playbooks/*.yml
|
|
||||||
playbooks/*/*.yml
|
|
||||||
env:
|
|
||||||
ANSIBLE_MODULE_UTILS: plugins/module_utils
|
|
||||||
ANSIBLE_LIBRARY: plugins/modules
|
|
||||||
|
|
||||||
- name: Run yaml-lint
|
|
||||||
uses: ibiqlik/action-yamllint@v1
|
|
||||||
|
|
||||||
- name: Run Python linters
|
|
||||||
uses: rjeffman/python-lint-action@master
|
|
||||||
6
.gitignore
vendored
6
.gitignore
vendored
@@ -1,8 +1,2 @@
|
|||||||
*.pyc
|
*.pyc
|
||||||
*.retry
|
*.retry
|
||||||
|
|
||||||
# ignore virtual environments
|
|
||||||
/.tox/
|
|
||||||
/.venv/
|
|
||||||
|
|
||||||
tests/logs/
|
|
||||||
|
|||||||
28
.yamllint
28
.yamllint
@@ -1,28 +0,0 @@
|
|||||||
---
|
|
||||||
ignore: |
|
|
||||||
/.tox/
|
|
||||||
/.venv/
|
|
||||||
/.github/
|
|
||||||
|
|
||||||
extends: default
|
|
||||||
|
|
||||||
rules:
|
|
||||||
braces:
|
|
||||||
max-spaces-inside: 1
|
|
||||||
level: error
|
|
||||||
brackets:
|
|
||||||
max-spaces-inside: 1
|
|
||||||
level: error
|
|
||||||
truthy:
|
|
||||||
allowed-values: ["yes", "no", "true", "false", "True", "False"]
|
|
||||||
level: error
|
|
||||||
# Disabled rules
|
|
||||||
document-start: disable
|
|
||||||
indentation: disable
|
|
||||||
line-length: disable
|
|
||||||
colons: disable
|
|
||||||
empty-lines: disable
|
|
||||||
comments: disable
|
|
||||||
comments-indentation: disable
|
|
||||||
trailing-spaces: disable
|
|
||||||
new-line-at-end-of-file: disable
|
|
||||||
@@ -19,7 +19,6 @@ Supported FreeIPA Versions
|
|||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipaconfig module.
|
FreeIPA versions 4.4.0 and up are supported by the ipaconfig module.
|
||||||
|
|
||||||
Some variables are only supported on newer versions of FreeIPA. Check `Variables` section for details.
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
@@ -92,7 +91,7 @@ Variable | Description | Required
|
|||||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | 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
|
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||||
`maxusername` \| `ipamaxusernamelength` | Set the maximum username length (1 to 255) | no
|
`maxusername` \| `ipamaxusernamelength` | Set the maximum username length (1 to 255) | no
|
||||||
`maxhostname` \| `ipamaxhostnamelength` | Set the maximum hostname length between 64-255. Only usable with IPA versions 4.8.0 and up. | no
|
`maxhostname` \| `ipamaxhostnamelength` | Set the maximum hostname length between 64-255 | no
|
||||||
`homedirectory` \| `ipahomesrootdir` | Set the default location of home directories | no
|
`homedirectory` \| `ipahomesrootdir` | Set the default location of home directories | no
|
||||||
`defaultshell` \| `ipadefaultloginshell` | Set the default shell for new users | no
|
`defaultshell` \| `ipadefaultloginshell` | Set the default shell for new users | no
|
||||||
`defaultgroup` \| `ipadefaultprimarygroup` | Set the default group for new users | no
|
`defaultgroup` \| `ipadefaultprimarygroup` | Set the default group for new users | no
|
||||||
|
|||||||
@@ -1,157 +0,0 @@
|
|||||||
Delegation module
|
|
||||||
=================
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The delegation module allows to ensure presence, absence of delegations and delegation attributes.
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
* Delegation management
|
|
||||||
|
|
||||||
|
|
||||||
Supported FreeIPA Versions
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipadelegation 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 make sure delegation "basic manager attributes" is present:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA delegation.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
permission: read
|
|
||||||
attribute:
|
|
||||||
- businesscategory
|
|
||||||
- employeetype
|
|
||||||
group: managers
|
|
||||||
membergroup: employees
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure delegation "basic manager attributes" is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA delegation.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure "basic manager attributes" member attributes employeetype and employeenumber are present:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA delegation.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- employeenumber
|
|
||||||
- employeetype
|
|
||||||
action: member
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure "basic manager attributes" member attributes employeetype and employeenumber are absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA delegation.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- employeenumber
|
|
||||||
- employeetype
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure delegation "basic manager attributes" is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA delegation.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Variables
|
|
||||||
---------
|
|
||||||
|
|
||||||
ipadelegation
|
|
||||||
-------
|
|
||||||
|
|
||||||
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` \| `aciname` | The list of delegation name strings. | yes
|
|
||||||
`permission` \| `permissions` | The permission to grant `read`, `read,write`, `write`]. Default is `write`. | no
|
|
||||||
`attribute` \| `attrs` | The attribute list to which the delegation applies. | no
|
|
||||||
`membergroup` \| `memberof` | The user group to apply delegation to. | no
|
|
||||||
`group` | User group ACI grants access to. | no
|
|
||||||
`action` | Work on delegation or member level. It can be on of `member` or `delegation` and defaults to `delegation`. | no
|
|
||||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
|
||||||
|
|
||||||
|
|
||||||
Authors
|
|
||||||
=======
|
|
||||||
|
|
||||||
Thomas Woerner
|
|
||||||
@@ -152,46 +152,6 @@ Example playbook to remove a zone:
|
|||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Example playbook to create a zone for reverse DNS lookup, from an IP address:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
|
|
||||||
---
|
|
||||||
- name: dnszone present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure zone for reverse DNS lookup is present.
|
|
||||||
ipadnszone:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name_from_ip: 192.168.1.2
|
|
||||||
state: present
|
|
||||||
```
|
|
||||||
|
|
||||||
Note that, on the previous example the zone created with `name_from_ip` might be "1.168.192.in-addr.arpa.", "168.192.in-addr.arpa.", or "192.in-addr.arpa.", depending on the DNS response the system get while querying for zones, and for this reason, when creating a zone using `name_from_ip`, the inferred zone name is returned to the controller, in the attribute `dnszone.name`. Since the zone inferred might not be what a user expects, `name_from_ip` can only be used with `state: present`. To have more control over the zone name, the prefix length for the IP address can be provided.
|
|
||||||
|
|
||||||
Example playbook to create a zone for reverse DNS lookup, from an IP address, given the prefix length and displaying the resulting zone name:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
|
|
||||||
---
|
|
||||||
- name: dnszone present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure zone for reverse DNS lookup is present.
|
|
||||||
ipadnszone:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name_from_ip: 192.168.1.2/24
|
|
||||||
state: present
|
|
||||||
register: result
|
|
||||||
- name: Display inferred zone name.
|
|
||||||
debug:
|
|
||||||
msg: "Zone name: {{ result.dnszone.name }}"
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Variables
|
Variables
|
||||||
=========
|
=========
|
||||||
@@ -203,8 +163,7 @@ Variable | Description | Required
|
|||||||
-------- | ----------- | --------
|
-------- | ----------- | --------
|
||||||
`ipaadmin_principal` | The admin principal is a string and defaults to `admin` | 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
|
`ipaadmin_password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||||
`name` \| `zone_name` | The zone name string or list of strings. | no
|
`name` \| `zone_name` | The zone name string. | yes
|
||||||
`name_from_ip` | Derive zone name from reverse of IP (PTR). Can only be used with `state: present`. | no
|
|
||||||
`forwarders` | The list of forwarders dicts. Each `forwarders` dict entry has:| no
|
`forwarders` | The list of forwarders dicts. Each `forwarders` dict entry has:| no
|
||||||
| `ip_address` - The IPv4 or IPv6 address of the DNS server. | yes
|
| `ip_address` - The IPv4 or IPv6 address of the DNS server. | yes
|
||||||
| `port` - The custom port that should be used on this server. | no
|
| `port` - The custom port that should be used on this server. | no
|
||||||
@@ -230,17 +189,6 @@ Variable | Description | Required
|
|||||||
`skip_nameserver_check` | Force DNS zone creation even if nameserver is not resolvable | no
|
`skip_nameserver_check` | Force DNS zone creation even if nameserver is not resolvable | no
|
||||||
|
|
||||||
|
|
||||||
Return Values
|
|
||||||
=============
|
|
||||||
|
|
||||||
ipadnszone
|
|
||||||
----------
|
|
||||||
|
|
||||||
Variable | Description | Returned When
|
|
||||||
-------- | ----------- | -------------
|
|
||||||
`dnszone` | DNS Zone dict with zone name infered from `name_from_ip`. <br>Options: | If `state` is `present`, `name_from_ip` is used, and a zone was created.
|
|
||||||
| `name` - The name of the zone created, inferred from `name_from_ip`. | Always
|
|
||||||
|
|
||||||
Authors
|
Authors
|
||||||
=======
|
=======
|
||||||
|
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ Supported FreeIPA Versions
|
|||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipagroup module.
|
FreeIPA versions 4.4.0 and up are supported by the ipagroup module.
|
||||||
|
|
||||||
Some variables are only supported on newer versions of FreeIPA. Check `Variables` section for details.
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
|
|||||||
@@ -19,8 +19,6 @@ Supported FreeIPA Versions
|
|||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipahostgroup module.
|
FreeIPA versions 4.4.0 and up are supported by the ipahostgroup module.
|
||||||
|
|
||||||
Some variables are only supported on newer versions of FreeIPA. Check `Variables` section for details.
|
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
------------
|
------------
|
||||||
@@ -107,23 +105,6 @@ Example playbook to make sure hosts and hostgroups are absent in databases hostg
|
|||||||
state: absent
|
state: absent
|
||||||
```
|
```
|
||||||
|
|
||||||
Example playbook to rename an existing playbook:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to handle hostgroups
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
# Ensure host-group databases is absent
|
|
||||||
- ipahostgroup:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: databases
|
|
||||||
rename: datalake
|
|
||||||
state: renamed
|
|
||||||
```
|
|
||||||
|
|
||||||
Example playbook to make sure host-group databases is absent:
|
Example playbook to make sure host-group databases is absent:
|
||||||
|
|
||||||
```yaml
|
```yaml
|
||||||
@@ -140,6 +121,7 @@ Example playbook to make sure host-group databases is absent:
|
|||||||
state: absent
|
state: absent
|
||||||
```
|
```
|
||||||
|
|
||||||
|
|
||||||
Variables
|
Variables
|
||||||
=========
|
=========
|
||||||
|
|
||||||
@@ -157,9 +139,8 @@ Variable | Description | Required
|
|||||||
`hostgroup` | List of hostgroup name strings assigned to this hostgroup. | no
|
`hostgroup` | List of hostgroup name strings assigned to this hostgroup. | no
|
||||||
`membermanager_user` | List of member manager users assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no
|
`membermanager_user` | List of member manager users assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no
|
||||||
`membermanager_group` | List of member manager groups assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no
|
`membermanager_group` | List of member manager groups assigned to this hostgroup. Only usable with IPA versions 4.8.4 and up. | no
|
||||||
`rename` \| `new_name` | Rename hostgroup to the provided name. Only usable with IPA versions 4.8.7 and up. | no
|
|
||||||
`action` | Work on hostgroup or member level. It can be on of `member` or `hostgroup` and defaults to `hostgroup`. | no
|
`action` | Work on hostgroup or member level. It can be on of `member` or `hostgroup` and defaults to `hostgroup`. | no
|
||||||
`state` | The state to ensure. It can be one of `present`, `absent` or `renamed`, default: `present`. | no
|
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | no
|
||||||
|
|
||||||
|
|
||||||
Authors
|
Authors
|
||||||
|
|||||||
@@ -1,92 +0,0 @@
|
|||||||
Location module
|
|
||||||
===============
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The location module allows to ensure presence and absence of locations.
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
* Location management
|
|
||||||
|
|
||||||
|
|
||||||
Supported FreeIPA Versions
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipalocation 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 make sure location "my_location1" is present:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA location.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipalocation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: my_location1
|
|
||||||
description: My Location 1
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure location "my_location1" is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA location.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipalocation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: my_location1
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Variables
|
|
||||||
---------
|
|
||||||
|
|
||||||
ipalocation
|
|
||||||
-------
|
|
||||||
|
|
||||||
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` \| `idnsname` | The list of location name strings. | yes
|
|
||||||
`description` | The IPA location string | false
|
|
||||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
|
||||||
|
|
||||||
|
|
||||||
Authors
|
|
||||||
=======
|
|
||||||
|
|
||||||
Thomas Woerner
|
|
||||||
@@ -1,147 +0,0 @@
|
|||||||
Privilege module
|
|
||||||
================
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The privilege module allows to ensure presence and absence of privileges and privilege members.
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
* Privilege management
|
|
||||||
|
|
||||||
|
|
||||||
Supported FreeIPA Versions
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipaprivilege 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 make sure privilege "Broad Privilege" is present:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA privilege.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
description: Broad Privilege
|
|
||||||
```
|
|
||||||
|
|
||||||
Example playbook to make sure privilege "Broad Privilege" member permission has multiple values:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA privilege permission member.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
permission:
|
|
||||||
- "Write IPA Configuration"
|
|
||||||
- "System: Write DNS Configuration"
|
|
||||||
- "System: Update DNS Entries"
|
|
||||||
action: member
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure privilege "Broad Privilege" member permission 'Write IPA Configuration' is absent:
|
|
||||||
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA privilege permission member.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
permission:
|
|
||||||
- "Write IPA Configuration"
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
Example playbook to rename privilege "Broad Privilege" to "DNS Special Privilege":
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA privilege.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
rename: DNS Special Privilege
|
|
||||||
state: renamed
|
|
||||||
```
|
|
||||||
|
|
||||||
Example playbook to make sure privilege "DNS Special Privilege" is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA privilege.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
- name: Ensure privilege Broad Privilege is absent
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: DNS Special Privilege
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Variables
|
|
||||||
---------
|
|
||||||
|
|
||||||
ipaprivilege
|
|
||||||
------------
|
|
||||||
|
|
||||||
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 privilege name strings. | yes
|
|
||||||
`description` | Privilege description. | no
|
|
||||||
`rename` \| `new_name` | Rename the privilege object. | no
|
|
||||||
`permission` | Permissions to be added to the privilege. | no
|
|
||||||
`action` | Work on privilege or member level. It can be one of `member` or `privilege` and defaults to `privilege`. | no
|
|
||||||
`state` | The state to ensure. It can be one of `present`, `absent` or `renamed`, default: `present`. | no
|
|
||||||
|
|
||||||
|
|
||||||
Authors
|
|
||||||
=======
|
|
||||||
|
|
||||||
Rafael Guterres Jeffman
|
|
||||||
@@ -1,151 +0,0 @@
|
|||||||
Selfservice module
|
|
||||||
=================
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The selfservice module allows to ensure presence, absence of selfservices and selfservice attributes.
|
|
||||||
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
* Selfservice management
|
|
||||||
|
|
||||||
|
|
||||||
Supported FreeIPA Versions
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipaselfservice 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 make sure selfservice "Users can manage their own name details" is present:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA selfservice.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
permission: read
|
|
||||||
attribute:
|
|
||||||
- title
|
|
||||||
- initials
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure selfservice "Users can manage their own name details" is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA selfservice.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure "Users can manage their own name details" member attribute initials is present:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA selfservice.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
attribute:
|
|
||||||
- initials
|
|
||||||
action: member
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure "Users can manage their own name details" member attribute initials is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA selfservice.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
attribute:
|
|
||||||
- initials
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Example playbook to make sure selfservice "Users can manage their own name details" is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to manage IPA selfservice.
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
Variables
|
|
||||||
---------
|
|
||||||
|
|
||||||
ipaselfservice
|
|
||||||
-------
|
|
||||||
|
|
||||||
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` \| `aciname` | The list of selfservice name strings. | yes
|
|
||||||
`permission` \| `permissions` | The permission to grant `read`, `read,write`, `write`]. Default is `write`. | no
|
|
||||||
`attribute` \| `attrs` | The attribute list to which the selfservice applies. | no
|
|
||||||
`action` | Work on selfservice or member level. It can be on of `member` or `selfservice` and defaults to `selfservice`. | no
|
|
||||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
|
||||||
|
|
||||||
|
|
||||||
Authors
|
|
||||||
=======
|
|
||||||
|
|
||||||
Thomas Woerner
|
|
||||||
@@ -18,7 +18,7 @@ Supported FreeIPA Versions
|
|||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipaservice module.
|
FreeIPA versions 4.4.0 and up are supported by the ipaservice module.
|
||||||
|
|
||||||
Some variables are only supported on newer versions of FreeIPA. Check `Variables` section for details.
|
Option `skip_host_check` requires FreeIPA version 4.7.0 or later.
|
||||||
|
|
||||||
|
|
||||||
Requirements
|
Requirements
|
||||||
@@ -56,7 +56,7 @@ Example playbook to make sure service is present:
|
|||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
certificate: |
|
certificate:
|
||||||
- MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAw
|
- MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAw
|
||||||
DzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDT
|
DzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDT
|
||||||
ALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpH
|
ALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpH
|
||||||
@@ -77,7 +77,7 @@ Example playbook to make sure service is present:
|
|||||||
requires_pre_auth: false
|
requires_pre_auth: false
|
||||||
ok_as_delegate: false
|
ok_as_delegate: false
|
||||||
ok_to_auth_as_delegate: false
|
ok_to_auth_as_delegate: false
|
||||||
skip_host_check: true
|
skip-host-check: true
|
||||||
force: true
|
force: true
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -167,7 +167,7 @@ Example playbook to ensure service has a certificate:
|
|||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
certificate: |
|
certificate:
|
||||||
- MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAw
|
- MIIC/zCCAeegAwIBAgIUMNHIbn+hhrOVew/2WbkteisV29QwDQYJKoZIhvcNAQELBQAw
|
||||||
DzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDT
|
DzENMAsGA1UEAwwEdGVzdDAeFw0yMDAyMDQxNDQxMDhaFw0zMDAyMDExNDQxMDhaMA8xDT
|
||||||
ALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpH
|
ALBgNVBAMMBHRlc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC+XVVGFYpH
|
||||||
@@ -298,7 +298,7 @@ Variable | Description | Required
|
|||||||
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service. Default to true. (bool) | no
|
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service. Default to true. (bool) | no
|
||||||
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service. Default to false. (bool) | no
|
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service. Default to false. (bool) | no
|
||||||
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client. Default to false. (bool) | no
|
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client. Default to false. (bool) | no
|
||||||
`skip_host_check` | Force service to be created even when host object does not exist to manage it. Only usable with IPA versions 4.7.0 and up. Default to false. (bool)| no
|
`skip_host_check` | Force service to be created even when host object does not exist to manage it. Default to false. (bool)| no
|
||||||
`force` | Force principal name even if host not in DNS. Default to false. (bool) | no
|
`force` | Force principal name even if host not in DNS. Default to false. (bool) | no
|
||||||
`host` \| `managedby_host`| Hosts that can manage the service. | no
|
`host` \| `managedby_host`| Hosts that can manage the service. | no
|
||||||
`principal` \| `krbprincipalname` | List of principal aliases for the service. | no
|
`principal` \| `krbprincipalname` | List of principal aliases for the service. | no
|
||||||
|
|||||||
119
README-trust.md
119
README-trust.md
@@ -1,119 +0,0 @@
|
|||||||
Trust module
|
|
||||||
============
|
|
||||||
|
|
||||||
Description
|
|
||||||
-----------
|
|
||||||
|
|
||||||
The trust module allows to ensure presence and absence of a domain trust.
|
|
||||||
|
|
||||||
Features
|
|
||||||
--------
|
|
||||||
|
|
||||||
* Trust management
|
|
||||||
|
|
||||||
Supported FreeIPA Versions
|
|
||||||
--------------------------
|
|
||||||
|
|
||||||
FreeIPA versions 4.4.0 and up are supported by the ipatrust module.
|
|
||||||
|
|
||||||
Requirements
|
|
||||||
------------
|
|
||||||
|
|
||||||
**Controller**
|
|
||||||
|
|
||||||
* Ansible version: 2.8+
|
|
||||||
|
|
||||||
**Node**
|
|
||||||
|
|
||||||
* Supported FreeIPA version (see above)
|
|
||||||
* samba-4
|
|
||||||
* ipa-server-trust-ad
|
|
||||||
|
|
||||||
Usage
|
|
||||||
=====
|
|
||||||
|
|
||||||
Example inventory file
|
|
||||||
|
|
||||||
```ini
|
|
||||||
[ipaserver]
|
|
||||||
ipaserver.test.local
|
|
||||||
```
|
|
||||||
|
|
||||||
Example playbook to ensure a one-way trust is present:
|
|
||||||
Omitting the two_way option implies the default of one-way
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to ensure a one-way trust is present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: ensure the one-way trust present
|
|
||||||
ipatrust:
|
|
||||||
realm: ad.example.test
|
|
||||||
admin: Administrator
|
|
||||||
password: secret_password
|
|
||||||
state: present
|
|
||||||
```
|
|
||||||
|
|
||||||
Example playbook to ensure a two-way trust is present using a shared-secret:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to ensure a two-way trust is present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: ensure the two-way trust is present
|
|
||||||
ipatrust:
|
|
||||||
realm: ad.example.test
|
|
||||||
trust_secret: my_share_Secret
|
|
||||||
two_way: True
|
|
||||||
state: present
|
|
||||||
```
|
|
||||||
|
|
||||||
Example playbook to ensure a trust is absent:
|
|
||||||
|
|
||||||
```yaml
|
|
||||||
---
|
|
||||||
- name: Playbook to ensure a trust is absent
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: ensure the trust is absent
|
|
||||||
ipatrust:
|
|
||||||
realm: ad.example.test
|
|
||||||
state: absent
|
|
||||||
```
|
|
||||||
|
|
||||||
This will only delete the ipa-side of the trust and it does NOT delete the id-range that matches the trust,
|
|
||||||
|
|
||||||
Variables
|
|
||||||
=========
|
|
||||||
|
|
||||||
ipatrust
|
|
||||||
-------
|
|
||||||
|
|
||||||
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
|
|
||||||
`realm` | The realm name string. | yes
|
|
||||||
`admin` | Active Directory domain administrator string. | no
|
|
||||||
`password` | Active Directory domain administrator's password string. | no
|
|
||||||
`server` | Domain controller for the Active Directory domain string. | no
|
|
||||||
`trust_secret` | Shared secret for the trust string. | no
|
|
||||||
`base_id` | First posix id for the trusted domain integer. | no
|
|
||||||
`range_size` | Size of the ID range reserved for the trusted domain integer. | no
|
|
||||||
`range_type` | Type of trusted domain ID range, It can be one of `ipa-ad-trust` or `ipa-ad-trust-posix`and defaults to `ipa-ad-trust`. | no
|
|
||||||
`two_way` | Establish bi-directional trust. By default trust is inbound one-way only. (bool) | no
|
|
||||||
`external` | Establish external trust to a domain in another forest. The trust is not transitive beyond the domain. (bool) | no
|
|
||||||
`state` | The state to ensure. It can be one of `present` or `absent`, default: `present`. | yes
|
|
||||||
|
|
||||||
Authors
|
|
||||||
=======
|
|
||||||
|
|
||||||
Rob Verduijn
|
|
||||||
@@ -437,7 +437,7 @@ There are only return values if one or more random passwords have been generated
|
|||||||
|
|
||||||
Variable | Description | Returned When
|
Variable | Description | Returned When
|
||||||
-------- | ----------- | -------------
|
-------- | ----------- | -------------
|
||||||
`user` | User dict with random password. (dict) <br>Options: | If random is yes and user did not exist or update_password is yes
|
`host` | Host dict with random password. (dict) <br>Options: | If random is yes and user did not exist or update_password is yes
|
||||||
| `randompassword` - The generated random password | If only one user is handled by the module
|
| `randompassword` - The generated random password | If only one user is handled by the module
|
||||||
| `name` - The user name of the user that got a new random password. (dict) <br> Options: <br> `randompassword` - The generated random password | If several users are handled by the module
|
| `name` - The user name of the user that got a new random password. (dict) <br> Options: <br> `randompassword` - The generated random password | If several users are handled by the module
|
||||||
|
|
||||||
|
|||||||
@@ -197,7 +197,7 @@ Example playbook to make sure vault is absent:
|
|||||||
state: absent
|
state: absent
|
||||||
register: result
|
register: result
|
||||||
- debug:
|
- debug:
|
||||||
msg: "{{ result.vault.data }}"
|
msg: "{{ result.data }}"
|
||||||
```
|
```
|
||||||
|
|
||||||
Variables
|
Variables
|
||||||
@@ -246,8 +246,7 @@ There is only a return value if `state` is `retrieved`.
|
|||||||
|
|
||||||
Variable | Description | Returned When
|
Variable | Description | Returned When
|
||||||
-------- | ----------- | -------------
|
-------- | ----------- | -------------
|
||||||
`vault` | Vault dict with archived data. (dict) <br>Options: | If `state` is `retrieved` and `out` is not defined.
|
`data` | The data stored in the vault. | If `state` is `retrieved`.
|
||||||
| `data` - The vault data. | Always
|
|
||||||
|
|
||||||
|
|
||||||
Notes
|
Notes
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ Features
|
|||||||
* Modules for sudocmdgroup management
|
* Modules for sudocmdgroup management
|
||||||
* Modules for sudorule management
|
* Modules for sudorule management
|
||||||
* Modules for topology management
|
* Modules for topology management
|
||||||
* Modules fot trust management
|
|
||||||
* Modules for user management
|
* Modules for user management
|
||||||
* Modules for vault management
|
* Modules for vault management
|
||||||
|
|
||||||
@@ -430,7 +429,6 @@ Modules in plugin/modules
|
|||||||
* [ipasudorule](README-sudorule.md)
|
* [ipasudorule](README-sudorule.md)
|
||||||
* [ipatopologysegment](README-topology.md)
|
* [ipatopologysegment](README-topology.md)
|
||||||
* [ipatopologysuffix](README-topology.md)
|
* [ipatopologysuffix](README-topology.md)
|
||||||
* [ipatrust](README-trust.md)
|
|
||||||
* [ipauser](README-user.md)
|
* [ipauser](README-user.md)
|
||||||
* [ipavault](README-vault.md)
|
* [ipavault](README-vault.md)
|
||||||
|
|
||||||
|
|||||||
22
azure-pipelines.yml
Normal file
22
azure-pipelines.yml
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
trigger:
|
||||||
|
- master
|
||||||
|
|
||||||
|
pool:
|
||||||
|
vmImage: 'ubuntu-18.04'
|
||||||
|
|
||||||
|
steps:
|
||||||
|
- task: UsePythonVersion@0
|
||||||
|
inputs:
|
||||||
|
versionSpec: '3.6'
|
||||||
|
|
||||||
|
- script: python -m pip install --upgrade pip setuptools wheel
|
||||||
|
displayName: Install tools
|
||||||
|
|
||||||
|
- script: pip install pydocstyle flake8
|
||||||
|
displayName: Install dependencies
|
||||||
|
|
||||||
|
- script: flake8 .
|
||||||
|
displayName: Run flake8 checks
|
||||||
|
|
||||||
|
- script: pydocstyle .
|
||||||
|
displayName: Verify docstings
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
driver:
|
|
||||||
name: docker
|
|
||||||
platforms:
|
|
||||||
- name: centos-7-build
|
|
||||||
image: centos/systemd
|
|
||||||
pre_build_image: true
|
|
||||||
hostname: ipaserver.test.local
|
|
||||||
dns_servers:
|
|
||||||
- 8.8.8.8
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
command: /usr/sbin/init
|
|
||||||
privileged: true
|
|
||||||
provisioner:
|
|
||||||
name: ansible
|
|
||||||
playbooks:
|
|
||||||
prepare: ../resources/playbooks/prepare-build.yml
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
driver:
|
|
||||||
name: docker
|
|
||||||
platforms:
|
|
||||||
- name: centos-7
|
|
||||||
image: quay.io/ansible-freeipa/upstream-tests:centos-7
|
|
||||||
pre_build_image: true
|
|
||||||
hostname: ipaserver.test.local
|
|
||||||
dns_servers:
|
|
||||||
- 127.0.0.1
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
command: /usr/sbin/init
|
|
||||||
privileged: true
|
|
||||||
provisioner:
|
|
||||||
name: ansible
|
|
||||||
playbooks:
|
|
||||||
prepare: ../resources/playbooks/prepare.yml
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
driver:
|
|
||||||
name: docker
|
|
||||||
platforms:
|
|
||||||
- name: centos-8-build
|
|
||||||
image: centos:8
|
|
||||||
pre_build_image: true
|
|
||||||
hostname: ipaserver.test.local
|
|
||||||
dns_servers:
|
|
||||||
- 8.8.8.8
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
command: /usr/sbin/init
|
|
||||||
privileged: true
|
|
||||||
provisioner:
|
|
||||||
name: ansible
|
|
||||||
playbooks:
|
|
||||||
prepare: ../resources/playbooks/prepare-build.yml
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
driver:
|
|
||||||
name: docker
|
|
||||||
platforms:
|
|
||||||
- name: centos-8
|
|
||||||
image: quay.io/ansible-freeipa/upstream-tests:centos-8
|
|
||||||
pre_build_image: true
|
|
||||||
hostname: ipaserver.test.local
|
|
||||||
dns_servers:
|
|
||||||
- 127.0.0.1
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
command: /usr/sbin/init
|
|
||||||
privileged: true
|
|
||||||
provisioner:
|
|
||||||
name: ansible
|
|
||||||
playbooks:
|
|
||||||
prepare: ../resources/playbooks/prepare.yml
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
centos-8
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
FROM fedora:latest
|
|
||||||
ENV container=docker
|
|
||||||
|
|
||||||
RUN rm -fv /var/cache/dnf/metadata_lock.pid; \
|
|
||||||
dnf makecache; \
|
|
||||||
dnf --assumeyes install \
|
|
||||||
/usr/bin/python3 \
|
|
||||||
/usr/bin/python3-config \
|
|
||||||
/usr/bin/dnf-3 \
|
|
||||||
sudo \
|
|
||||||
bash \
|
|
||||||
systemd \
|
|
||||||
procps-ng \
|
|
||||||
iproute && \
|
|
||||||
dnf clean all; \
|
|
||||||
(cd /lib/systemd/system/sysinit.target.wants/; for i in *; do [ $i == systemd-tmpfiles-setup.service ] || rm -f $i; done); \
|
|
||||||
rm -f /lib/systemd/system/multi-user.target.wants/*;\
|
|
||||||
rm -f /etc/systemd/system/*.wants/*;\
|
|
||||||
rm -f /lib/systemd/system/local-fs.target.wants/*; \
|
|
||||||
rm -f /lib/systemd/system/sockets.target.wants/*udev*; \
|
|
||||||
rm -f /lib/systemd/system/sockets.target.wants/*initctl*; \
|
|
||||||
rm -f /lib/systemd/system/basic.target.wants/*;\
|
|
||||||
rm -f /lib/systemd/system/anaconda.target.wants/*; \
|
|
||||||
rm -rf /var/cache/dnf/;
|
|
||||||
|
|
||||||
STOPSIGNAL RTMIN+3
|
|
||||||
|
|
||||||
VOLUME ["/sys/fs/cgroup"]
|
|
||||||
|
|
||||||
CMD ["/usr/sbin/init"]
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
driver:
|
|
||||||
name: docker
|
|
||||||
platforms:
|
|
||||||
- name: fedora-latest-build
|
|
||||||
image: fedora-latest
|
|
||||||
dockerfile: Dockerfile
|
|
||||||
hostname: ipaserver.test.local
|
|
||||||
dns_servers:
|
|
||||||
- 8.8.8.8
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
command: /usr/sbin/init
|
|
||||||
privileged: true
|
|
||||||
provisioner:
|
|
||||||
name: ansible
|
|
||||||
playbooks:
|
|
||||||
prepare: ../resources/playbooks/prepare-build.yml
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
---
|
|
||||||
driver:
|
|
||||||
name: docker
|
|
||||||
platforms:
|
|
||||||
- name: fedora-latest
|
|
||||||
image: quay.io/ansible-freeipa/upstream-tests:fedora-latest
|
|
||||||
pre_build_image: true
|
|
||||||
hostname: ipaserver.test.local
|
|
||||||
dns_servers:
|
|
||||||
- 127.0.0.1
|
|
||||||
volumes:
|
|
||||||
- /sys/fs/cgroup:/sys/fs/cgroup:ro
|
|
||||||
command: /usr/sbin/init
|
|
||||||
privileged: true
|
|
||||||
provisioner:
|
|
||||||
name: ansible
|
|
||||||
playbooks:
|
|
||||||
prepare: ../resources/playbooks/prepare.yml
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../plugins/modules/
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../plugins/module_utils/
|
|
||||||
@@ -1,27 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Converge
|
|
||||||
hosts: all
|
|
||||||
tasks:
|
|
||||||
- include_tasks: prepare-common.yml
|
|
||||||
|
|
||||||
- name: Ensure sudo package is installed
|
|
||||||
package:
|
|
||||||
name: sudo
|
|
||||||
|
|
||||||
- name: Ensure nss package is updated
|
|
||||||
package:
|
|
||||||
name: nss
|
|
||||||
state: latest # noqa 403
|
|
||||||
|
|
||||||
- include_role:
|
|
||||||
name: ipaserver
|
|
||||||
vars:
|
|
||||||
ipaserver_setup_dns: yes
|
|
||||||
ipaserver_setup_kra: yes
|
|
||||||
ipaserver_auto_forwarders: yes
|
|
||||||
ipaserver_no_dnssec_validation: yes
|
|
||||||
ipaserver_auto_reverse: yes
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
ipadm_password: SomeDMpassword
|
|
||||||
ipaserver_domain: test.local
|
|
||||||
ipaserver_realm: TEST.LOCAL
|
|
||||||
@@ -1,33 +0,0 @@
|
|||||||
# IPA depends on IPv6 and without it dirsrv service won't start.
|
|
||||||
- name: Ensure IPv6 is ENABLED
|
|
||||||
sysctl:
|
|
||||||
name: "{{ item.name }}"
|
|
||||||
value: "{{ item.value }}"
|
|
||||||
sysctl_set: yes
|
|
||||||
state: present
|
|
||||||
reload: yes
|
|
||||||
with_items :
|
|
||||||
- name: net.ipv6.conf.all.disable_ipv6
|
|
||||||
value: 0
|
|
||||||
- name: net.ipv6.conf.lo.disable_ipv6
|
|
||||||
value: 0
|
|
||||||
- name: net.ipv6.conf.eth0.disable_ipv6
|
|
||||||
value: 1
|
|
||||||
|
|
||||||
# Set fs.protected_regular to 0
|
|
||||||
# This is needed in some IPA versions in order to get KRA enabled.
|
|
||||||
# See https://pagure.io/freeipa/issue/7906 for more information.
|
|
||||||
- name: stat protected_regular
|
|
||||||
stat:
|
|
||||||
path: /proc/sys/fs/protected_regular
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- name: Ensure fs.protected_regular is disabled
|
|
||||||
sysctl:
|
|
||||||
name: fs.protected_regular
|
|
||||||
value: 0
|
|
||||||
sysctl_set: yes
|
|
||||||
state: present
|
|
||||||
reload: yes
|
|
||||||
when: result.stat.exists
|
|
||||||
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Converge
|
|
||||||
hosts: all
|
|
||||||
tasks:
|
|
||||||
- include_tasks: prepare-common.yml
|
|
||||||
|
|
||||||
# In some distros DS won't start up after reboot
|
|
||||||
# This is due to a problem in 389-ds. See tickets:
|
|
||||||
# * https://pagure.io/389-ds-base/issue/47429
|
|
||||||
# * https://pagure.io/389-ds-base/issue/51039
|
|
||||||
#
|
|
||||||
# To avoid this problem we create the directories before starting IPA.
|
|
||||||
- name: Ensure lock dirs for DS exists
|
|
||||||
file:
|
|
||||||
state: directory
|
|
||||||
owner: dirsrv
|
|
||||||
group: dirsrv
|
|
||||||
path: "{{ item }}"
|
|
||||||
loop:
|
|
||||||
- /var/lock/dirsrv/
|
|
||||||
- /var/lock/dirsrv/slapd-TEST-LOCAL/
|
|
||||||
|
|
||||||
- name: Ensure IPA server is up an running
|
|
||||||
service:
|
|
||||||
name: ipa
|
|
||||||
state: started
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
../../../roles/
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation absent
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" is absent
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
state: absent
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation member absent
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" member attributes employeenumber and employeetype are absent
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- employeenumber
|
|
||||||
- employeetype
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation member present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" member attribute departmentnumber is present
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- departmentnumber
|
|
||||||
action: member
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" is present
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
permission: read
|
|
||||||
attribute:
|
|
||||||
- businesscategory
|
|
||||||
group: managers
|
|
||||||
membergroup: employees
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Playbook to manage DNS forward zone
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
gather_facts: false
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
# Ensure DNS zone is present
|
|
||||||
- ipadnsforwardzone:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
state: absent
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Playbook to manage DNS forward zone
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
gather_facts: false
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
# Ensure DNS zone is present
|
|
||||||
- ipadnsforwardzone:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: example.com
|
|
||||||
forwarders:
|
|
||||||
- ip_address: 8.8.8.8
|
|
||||||
forwardpolicy: first
|
|
||||||
skip_overlap_check: true
|
|
||||||
permission: yes
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Playbook to manage DNS forward zone
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
gather_facts: false
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
# Ensure DNS zone is present
|
|
||||||
- ipadnsforwardzone:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: example.com
|
|
||||||
forwarders:
|
|
||||||
- ip_address: 192.168.100.123
|
|
||||||
port: 8063
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Playbook to ensure DNS zone exist
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure zone exist, finding zone name from IP address.
|
|
||||||
ipadnszone:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name_from_ip: 10.1.2.3/24
|
|
||||||
register: result
|
|
||||||
|
|
||||||
- name: Zone name inferred from `name_from_ip`
|
|
||||||
debug:
|
|
||||||
msg: "Zone created: {{ result.dnszone.name }}"
|
|
||||||
@@ -4,7 +4,7 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- ipahost:
|
ipahost:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: host01.exmaple.com
|
name: host01.exmaple.com
|
||||||
managedby_host: server.exmaple.com
|
managedby_host: server.exmaple.com
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- ipahost:
|
ipahost:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: host01.exmaple.com
|
name: host01.exmaple.com
|
||||||
managedby_host: server.exmaple.com
|
managedby_host: server.exmaple.com
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- ipahost:
|
ipahost:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
name: host01.exmaple.com
|
name: host01.exmaple.com
|
||||||
managedby_host: server.exmaple.com
|
managedby_host: server.exmaple.com
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Ensure hosts manadegby_host is absent.
|
|
||||||
ipahost:
|
ipahost:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
hosts:
|
hosts:
|
||||||
|
|||||||
@@ -4,7 +4,6 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- name: Ensure hosts manadegby_host is absent.
|
|
||||||
ipahost:
|
ipahost:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
hosts:
|
hosts:
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
become: true
|
become: true
|
||||||
|
|
||||||
tasks:
|
tasks:
|
||||||
- ipahost:
|
ipahost:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
hosts:
|
hosts:
|
||||||
- name: host01.exmaple.com
|
- name: host01.exmaple.com
|
||||||
|
|||||||
@@ -23,3 +23,4 @@
|
|||||||
- name: Print generated random password for host02.example.com
|
- name: Print generated random password for host02.example.com
|
||||||
debug:
|
debug:
|
||||||
var: ipahost.host["host02.example.com"].randompassword
|
var: ipahost.host["host02.example.com"].randompassword
|
||||||
|
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Playbook to handle hostgroups
|
|
||||||
hosts: ipaserver
|
|
||||||
become: yes
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name : Rename host-group from `databases` to `datalake`
|
|
||||||
ipahostgroup:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: databases
|
|
||||||
rename: datalake
|
|
||||||
state: renamed
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Location absent test
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure location my_location1 is absent
|
|
||||||
ipalocation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: my_location1
|
|
||||||
state: absent
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Location present test
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure location my_location1 is present
|
|
||||||
ipalocation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: my_location1
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Privilege absent example
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure privilege "Broad Privilege" is absent
|
|
||||||
ipaprivilege:
|
|
||||||
name: Broad Privilege
|
|
||||||
state: absent
|
|
||||||
@@ -1,14 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Privilege absent example
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure privilege "Broad Privilege" permission is absent
|
|
||||||
ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
permission:
|
|
||||||
- "System: Write IPA Configuration"
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Privilege member present example
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure privilege "Broad Privilege" permissions are present
|
|
||||||
ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
permission:
|
|
||||||
- "System: Write IPA Configuration"
|
|
||||||
- "System: Write DNS Configuration"
|
|
||||||
- "System: Update DNS Entries"
|
|
||||||
action: member
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Privilege present example
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure privilege Broad Privilege is present
|
|
||||||
ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
description: Broad Privilege
|
|
||||||
@@ -1,11 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation absent
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" is absent
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
state: absent
|
|
||||||
@@ -1,15 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation member absent
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" member attributes employeenumber and employeetype are absent
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- employeenumber
|
|
||||||
- employeetype
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation member present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" member attribute departmentnumber is present
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- departmentnumber
|
|
||||||
action: member
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Delegation present
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: Ensure delegation "basic manager attributes" is present
|
|
||||||
ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
permission: read
|
|
||||||
attribute:
|
|
||||||
- businesscategory
|
|
||||||
@@ -7,7 +7,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure management host is absent.
|
# Ensure management host is absent.
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
host: "{{ groups.ipaserver[0] }}"
|
host: "{{ groups.ipaserver[0] }}"
|
||||||
action: member
|
action: member
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure management host is present.
|
# Ensure management host is present.
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
host: "{{ groups.ipaserver[0] }}"
|
host: "{{ groups.ipaserver[0] }}"
|
||||||
action: member
|
action: member
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service is absent
|
# Ensure service is absent
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
state: absent
|
state: absent
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service is disabled
|
# Ensure service is disabled
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
state: disabled
|
state: disabled
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service is present
|
# Ensure service is present
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
certificate:
|
certificate:
|
||||||
- MIICBjCCAW8CFHnm32VcXaUDGfEGdDL/erPSijUAMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjAwMTIzMDA1NjQ2WhcNMjEwMTIyMDA1NjQ2WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYrdVmsr7iT3f67DM5bb1osSEe5/c91UUMEIcFq5wrgBhzVfs8iIMDVC1yiUGTsDLJNJc4nb1tUxeR9K5fh25E6n/eWDBP75NStotjAXRU4Ahi3FNRhWFOKesds5xNqgDk5/dY8UekJv2yUblQuZzeF8b2XFrmHuCaYuFctzPfWwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACF+5RS8Ce0HRixGPu4Xd51i+Kzblg++lx8fDJ8GW5G16/Z1AsB72Hc7etJL2PksHlue/xCq6SA9fIfHc4TBNCiWjPSP1NhHJeYyoPiSkcYsqXuxWyoyRLbnAhBVvhoiqZbUt3u3tGB0uMMA0yJvj07mP7Nea2KdBYVH8X1pM0V+
|
- MIICBjCCAW8CFHnm32VcXaUDGfEGdDL/erPSijUAMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjAwMTIzMDA1NjQ2WhcNMjEwMTIyMDA1NjQ2WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYrdVmsr7iT3f67DM5bb1osSEe5/c91UUMEIcFq5wrgBhzVfs8iIMDVC1yiUGTsDLJNJc4nb1tUxeR9K5fh25E6n/eWDBP75NStotjAXRU4Ahi3FNRhWFOKesds5xNqgDk5/dY8UekJv2yUblQuZzeF8b2XFrmHuCaYuFctzPfWwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACF+5RS8Ce0HRixGPu4Xd51i+Kzblg++lx8fDJ8GW5G16/Z1AsB72Hc7etJL2PksHlue/xCq6SA9fIfHc4TBNCiWjPSP1NhHJeYyoPiSkcYsqXuxWyoyRLbnAhBVvhoiqZbUt3u3tGB0uMMA0yJvj07mP7Nea2KdBYVH8X1pM0V+
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service is present
|
# Ensure service is present
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/ihavenodns.info
|
name: HTTP/ihavenodns.info
|
||||||
force: yes
|
force: yes
|
||||||
# state: absent
|
# state: absent
|
||||||
|
|||||||
@@ -7,6 +7,6 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service is present
|
# Ensure service is present
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.ansible.com
|
name: HTTP/www.ansible.com
|
||||||
skip_host_check: yes
|
skip_host_check: yes
|
||||||
|
|||||||
@@ -7,5 +7,5 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service is present
|
# Ensure service is present
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Service HTTP/www.example.com members allow_create_keytab absent for users, groups, hosts and hostgroups
|
- name: Service HTTP/www.example.com members allow_create_keytab absent for users, groups, hosts and hostgroups
|
||||||
ipaservice:
|
ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
allow_create_keytab_user:
|
allow_create_keytab_user:
|
||||||
- user01
|
- user01
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Service HTTP/www.example.com members allow_create_keytab present for users, groups, hosts and hostgroups
|
- name: Service HTTP/www.example.com members allow_create_keytab present for users, groups, hosts and hostgroups
|
||||||
ipaservice:
|
ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
allow_create_keytab_user:
|
allow_create_keytab_user:
|
||||||
- user01
|
- user01
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Service HTTP/www.example.com members allow_retrieve_keytab absent for users, groups, hosts and hostgroups
|
- name: Service HTTP/www.example.com members allow_retrieve_keytab absent for users, groups, hosts and hostgroups
|
||||||
ipaservice:
|
ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
allow_retrieve_keytab_user:
|
allow_retrieve_keytab_user:
|
||||||
- user01
|
- user01
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Service HTTP/www.example.com members allow_retrieve_keytab present for users, groups, hosts and hostgroups
|
- name: Service HTTP/www.example.com members allow_retrieve_keytab present for users, groups, hosts and hostgroups
|
||||||
ipaservice:
|
ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
allow_retrieve_keytab_user:
|
allow_retrieve_keytab_user:
|
||||||
- user01
|
- user01
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service certificate is absent
|
# Ensure service certificate is absent
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
|
|
||||||
certificate:
|
certificate:
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
# Ensure service certificate is present
|
# Ensure service certificate is present
|
||||||
- ipaservice:
|
- ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
certificate:
|
certificate:
|
||||||
- MIICBjCCAW8CFHnm32VcXaUDGfEGdDL/erPSijUAMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjAwMTIzMDA1NjQ2WhcNMjEwMTIyMDA1NjQ2WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYrdVmsr7iT3f67DM5bb1osSEe5/c91UUMEIcFq5wrgBhzVfs8iIMDVC1yiUGTsDLJNJc4nb1tUxeR9K5fh25E6n/eWDBP75NStotjAXRU4Ahi3FNRhWFOKesds5xNqgDk5/dY8UekJv2yUblQuZzeF8b2XFrmHuCaYuFctzPfWwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACF+5RS8Ce0HRixGPu4Xd51i+Kzblg++lx8fDJ8GW5G16/Z1AsB72Hc7etJL2PksHlue/xCq6SA9fIfHc4TBNCiWjPSP1NhHJeYyoPiSkcYsqXuxWyoyRLbnAhBVvhoiqZbUt3u3tGB0uMMA0yJvj07mP7Nea2KdBYVH8X1pM0V+
|
- MIICBjCCAW8CFHnm32VcXaUDGfEGdDL/erPSijUAMA0GCSqGSIb3DQEBCwUAMEIxCzAJBgNVBAYTAlhYMRUwEwYDVQQHDAxEZWZhdWx0IENpdHkxHDAaBgNVBAoME0RlZmF1bHQgQ29tcGFueSBMdGQwHhcNMjAwMTIzMDA1NjQ2WhcNMjEwMTIyMDA1NjQ2WjBCMQswCQYDVQQGEwJYWDEVMBMGA1UEBwwMRGVmYXVsdCBDaXR5MRwwGgYDVQQKDBNEZWZhdWx0IENvbXBhbnkgTHRkMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDYrdVmsr7iT3f67DM5bb1osSEe5/c91UUMEIcFq5wrgBhzVfs8iIMDVC1yiUGTsDLJNJc4nb1tUxeR9K5fh25E6n/eWDBP75NStotjAXRU4Ahi3FNRhWFOKesds5xNqgDk5/dY8UekJv2yUblQuZzeF8b2XFrmHuCaYuFctzPfWwIDAQABMA0GCSqGSIb3DQEBCwUAA4GBACF+5RS8Ce0HRixGPu4Xd51i+Kzblg++lx8fDJ8GW5G16/Z1AsB72Hc7etJL2PksHlue/xCq6SA9fIfHc4TBNCiWjPSP1NhHJeYyoPiSkcYsqXuxWyoyRLbnAhBVvhoiqZbUt3u3tGB0uMMA0yJvj07mP7Nea2KdBYVH8X1pM0V+
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Service HTTP/www.exmaple.com member principals host/test.exmaple.com absent
|
- name: Service HTTP/www.exmaple.com member principals host/test.exmaple.com absent
|
||||||
ipaservice:
|
ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
principal:
|
principal:
|
||||||
- host/test.exmaple.com
|
- host/test.exmaple.com
|
||||||
|
|||||||
@@ -6,7 +6,7 @@
|
|||||||
tasks:
|
tasks:
|
||||||
- name: Service HTTP/www.exmaple.com member principals host/test.exmaple.com present
|
- name: Service HTTP/www.exmaple.com member principals host/test.exmaple.com present
|
||||||
ipaservice:
|
ipaservice:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: MyPassword123
|
||||||
name: HTTP/www.example.com
|
name: HTTP/www.example.com
|
||||||
principal:
|
principal:
|
||||||
- host/test.exmaple.com
|
- host/test.exmaple.com
|
||||||
|
|||||||
@@ -1,12 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Playbook to create a trust
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: ensure the trust is present
|
|
||||||
ipatrust:
|
|
||||||
realm: windows.local
|
|
||||||
admin: Administrator
|
|
||||||
password: secret_password
|
|
||||||
state: present
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
- name: Playbook to delete trust
|
|
||||||
hosts: ipaserver
|
|
||||||
become: true
|
|
||||||
|
|
||||||
tasks:
|
|
||||||
- name: ensure the trust is absent
|
|
||||||
ipatrust:
|
|
||||||
realm: windows.local
|
|
||||||
state: absent
|
|
||||||
@@ -14,4 +14,4 @@
|
|||||||
state: retrieved
|
state: retrieved
|
||||||
register: result
|
register: result
|
||||||
- debug:
|
- debug:
|
||||||
msg: "Data: {{ result.vault.data }}"
|
msg: "Data: {{ result.data }}"
|
||||||
|
|||||||
@@ -14,4 +14,4 @@
|
|||||||
state: retrieved
|
state: retrieved
|
||||||
register: result
|
register: result
|
||||||
- debug:
|
- debug:
|
||||||
msg: "{{ result.vault.data }}"
|
msg: "{{ result.data | b64decode }}"
|
||||||
|
|||||||
@@ -506,7 +506,7 @@ class FreeIPABaseModule(AnsibleModule):
|
|||||||
# when needed.
|
# when needed.
|
||||||
self.ipa_params = AnsibleFreeIPAParams(self)
|
self.ipa_params = AnsibleFreeIPAParams(self)
|
||||||
|
|
||||||
def get_ipa_command_args(self, **kwargs):
|
def get_ipa_command_args(self):
|
||||||
"""
|
"""
|
||||||
Return a dict to be passed to an IPA command.
|
Return a dict to be passed to an IPA command.
|
||||||
|
|
||||||
@@ -538,7 +538,7 @@ class FreeIPABaseModule(AnsibleModule):
|
|||||||
elif hasattr(self, param_name):
|
elif hasattr(self, param_name):
|
||||||
method = getattr(self, param_name)
|
method = getattr(self, param_name)
|
||||||
if callable(method):
|
if callable(method):
|
||||||
value = method(**kwargs)
|
value = method()
|
||||||
|
|
||||||
# We don't have a way to guess the value so fail.
|
# We don't have a way to guess the value so fail.
|
||||||
else:
|
else:
|
||||||
@@ -610,16 +610,13 @@ class FreeIPABaseModule(AnsibleModule):
|
|||||||
exit the module with proper arguments.
|
exit the module with proper arguments.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
# TODO: shouldn't we also disconnect from api backend?
|
|
||||||
temp_kdestroy(self.ccache_dir, self.ccache_name)
|
|
||||||
|
|
||||||
if exc_type == SystemExit:
|
|
||||||
raise
|
|
||||||
|
|
||||||
if exc_val:
|
if exc_val:
|
||||||
self.fail_json(msg=str(exc_val))
|
self.fail_json(msg=str(exc_val))
|
||||||
|
|
||||||
self.exit_json(changed=self.changed, **self.exit_args)
|
# TODO: shouldn't we also disconnect from api backend?
|
||||||
|
temp_kdestroy(self.ccache_dir, self.ccache_name)
|
||||||
|
|
||||||
|
self.exit_json(changed=self.changed, user=self.exit_args)
|
||||||
|
|
||||||
def get_command_errors(self, command, result):
|
def get_command_errors(self, command, result):
|
||||||
"""Look for erros into command results."""
|
"""Look for erros into command results."""
|
||||||
@@ -658,22 +655,14 @@ class FreeIPABaseModule(AnsibleModule):
|
|||||||
except Exception as excpt:
|
except Exception as excpt:
|
||||||
self.fail_json(msg="%s: %s: %s" % (command, name, str(excpt)))
|
self.fail_json(msg="%s: %s: %s" % (command, name, str(excpt)))
|
||||||
else:
|
else:
|
||||||
self.process_command_result(name, command, args, result)
|
if "completed" in result:
|
||||||
|
if result["completed"] > 0:
|
||||||
|
self.changed = True
|
||||||
|
else:
|
||||||
|
self.changed = True
|
||||||
|
|
||||||
self.get_command_errors(command, result)
|
self.get_command_errors(command, result)
|
||||||
|
|
||||||
def process_command_result(self, name, command, args, result):
|
|
||||||
"""
|
|
||||||
Process an API command result.
|
|
||||||
|
|
||||||
This method can be overriden in subclasses, and change self.exit_values
|
|
||||||
to return data in the result for the controller.
|
|
||||||
"""
|
|
||||||
if "completed" in result:
|
|
||||||
if result["completed"] > 0:
|
|
||||||
self.changed = True
|
|
||||||
else:
|
|
||||||
self.changed = True
|
|
||||||
|
|
||||||
def require_ipa_attrs_change(self, command_args, ipa_attrs):
|
def require_ipa_attrs_change(self, command_args, ipa_attrs):
|
||||||
"""
|
"""
|
||||||
Compare given args with current object attributes.
|
Compare given args with current object attributes.
|
||||||
|
|||||||
@@ -1,340 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Authors:
|
|
||||||
# Thomas Woerner <twoerner@redhat.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2020 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: ipadelegation
|
|
||||||
short description: Manage FreeIPA delegations
|
|
||||||
description: Manage FreeIPA delegations and delegation attributes
|
|
||||||
options:
|
|
||||||
ipaadmin_principal:
|
|
||||||
description: The admin principal.
|
|
||||||
default: admin
|
|
||||||
ipaadmin_password:
|
|
||||||
description: The admin password.
|
|
||||||
required: false
|
|
||||||
name:
|
|
||||||
description: The list of delegation name strings.
|
|
||||||
required: true
|
|
||||||
aliases: ["aciname"]
|
|
||||||
permission:
|
|
||||||
description: Permissions to grant (read, write). Default is write.
|
|
||||||
required: false
|
|
||||||
aliases: ["permissions"]
|
|
||||||
attribute:
|
|
||||||
description: Attribute list to which the delegation applies
|
|
||||||
required: false
|
|
||||||
aliases: ["attrs"]
|
|
||||||
membergroup
|
|
||||||
description: User group to apply delegation to
|
|
||||||
required: false
|
|
||||||
aliases: ["memberof"]
|
|
||||||
group:
|
|
||||||
description: User group ACI grants access to
|
|
||||||
required: false
|
|
||||||
action:
|
|
||||||
description: Work on delegation or member level.
|
|
||||||
choices: ["delegation", "member"]
|
|
||||||
default: delegation
|
|
||||||
required: false
|
|
||||||
state:
|
|
||||||
description: The state to ensure.
|
|
||||||
choices: ["present", "absent"]
|
|
||||||
default: present
|
|
||||||
required: true
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = """
|
|
||||||
# Ensure delegation "basic manager attributes" is present
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
permission: read
|
|
||||||
attribute:
|
|
||||||
- businesscategory
|
|
||||||
- employeetype
|
|
||||||
group: managers
|
|
||||||
membergroup: employees
|
|
||||||
|
|
||||||
# Ensure delegation "basic manager attributes" member attribute
|
|
||||||
# departmentnumber is present
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- departmentnumber
|
|
||||||
action: member
|
|
||||||
|
|
||||||
# Ensure delegation "basic manager attributes" member attributes
|
|
||||||
# employeetype and employeenumber are present
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
attribute:
|
|
||||||
- employeenumber
|
|
||||||
- employeetype
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
# Ensure delegation "basic manager attributes" is absent
|
|
||||||
- ipadelegation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "basic manager attributes"
|
|
||||||
state: absent
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = """
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
from ansible.module_utils.ansible_freeipa_module import \
|
|
||||||
temp_kinit, temp_kdestroy, valid_creds, api_connect, api_command, \
|
|
||||||
compare_args_ipa, module_params_get
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
unicode = str
|
|
||||||
|
|
||||||
|
|
||||||
def find_delegation(module, name):
|
|
||||||
"""Find if a delegation with the given name already exist."""
|
|
||||||
try:
|
|
||||||
_result = api_command(module, "delegation_show", name, {"all": True})
|
|
||||||
except Exception: # pylint: disable=broad-except
|
|
||||||
# An exception is raised if delegation name is not found.
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return _result["result"]
|
|
||||||
|
|
||||||
|
|
||||||
def gen_args(permission, attribute, membergroup, group):
|
|
||||||
_args = {}
|
|
||||||
if permission is not None:
|
|
||||||
_args["permissions"] = permission
|
|
||||||
if attribute is not None:
|
|
||||||
_args["attrs"] = attribute
|
|
||||||
if membergroup is not None:
|
|
||||||
_args["memberof"] = membergroup
|
|
||||||
if group is not None:
|
|
||||||
_args["group"] = group
|
|
||||||
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=["aciname"], default=None,
|
|
||||||
required=True),
|
|
||||||
# present
|
|
||||||
permission=dict(required=False, type='list',
|
|
||||||
aliases=["permissions"], default=None),
|
|
||||||
attribute=dict(required=False, type='list', aliases=["attrs"],
|
|
||||||
default=None),
|
|
||||||
membergroup=dict(type="str", aliases=["memberof"], default=None),
|
|
||||||
group=dict(type="str", default=None),
|
|
||||||
action=dict(type="str", default="delegation",
|
|
||||||
choices=["member", "delegation"]),
|
|
||||||
# state
|
|
||||||
state=dict(type="str", default="present",
|
|
||||||
choices=["present", "absent"]),
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
ansible_module._ansible_debug = True
|
|
||||||
|
|
||||||
# Get parameters
|
|
||||||
|
|
||||||
# general
|
|
||||||
ipaadmin_principal = module_params_get(ansible_module,
|
|
||||||
"ipaadmin_principal")
|
|
||||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
|
||||||
names = module_params_get(ansible_module, "name")
|
|
||||||
|
|
||||||
# present
|
|
||||||
permission = module_params_get(ansible_module, "permission")
|
|
||||||
attribute = module_params_get(ansible_module, "attribute")
|
|
||||||
membergroup = module_params_get(ansible_module, "membergroup")
|
|
||||||
group = module_params_get(ansible_module, "group")
|
|
||||||
action = module_params_get(ansible_module, "action")
|
|
||||||
# state
|
|
||||||
state = module_params_get(ansible_module, "state")
|
|
||||||
|
|
||||||
# Check parameters
|
|
||||||
|
|
||||||
if state == "present":
|
|
||||||
if len(names) != 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Only one delegation be added at a time.")
|
|
||||||
if action == "member":
|
|
||||||
invalid = ["permission", "membergroup", "group"]
|
|
||||||
for x in invalid:
|
|
||||||
if vars()[x] is not None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Argument '%s' can not be used with action "
|
|
||||||
"'%s' and state '%s'" % (x, action, state))
|
|
||||||
|
|
||||||
if state == "absent":
|
|
||||||
if len(names) < 1:
|
|
||||||
ansible_module.fail_json(msg="No name given.")
|
|
||||||
invalid = ["permission", "membergroup", "group"]
|
|
||||||
if action == "delegation":
|
|
||||||
invalid.append("attribute")
|
|
||||||
for x in invalid:
|
|
||||||
if vars()[x] is not None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Argument '%s' can not be used with action "
|
|
||||||
"'%s' and state '%s'" % (x, action, state))
|
|
||||||
|
|
||||||
if permission is not None:
|
|
||||||
perm = [p for p in permission if p not in ("read", "write")]
|
|
||||||
if perm:
|
|
||||||
ansible_module.fail_json(msg="Invalid permission '%s'" % perm)
|
|
||||||
if len(set(permission)) != len(permission):
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Invalid permission '%s', items are not unique" %
|
|
||||||
repr(permission))
|
|
||||||
|
|
||||||
if attribute is not None:
|
|
||||||
if len(set(attribute)) != len(attribute):
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Invalid attribute '%s', items are not unique" %
|
|
||||||
repr(attribute))
|
|
||||||
|
|
||||||
# Init
|
|
||||||
|
|
||||||
changed = False
|
|
||||||
exit_args = {}
|
|
||||||
ccache_dir = None
|
|
||||||
ccache_name = None
|
|
||||||
try:
|
|
||||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
|
||||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
|
||||||
ipaadmin_password)
|
|
||||||
api_connect()
|
|
||||||
|
|
||||||
commands = []
|
|
||||||
for name in names:
|
|
||||||
# Make sure delegation exists
|
|
||||||
res_find = find_delegation(ansible_module, name)
|
|
||||||
|
|
||||||
# Create command
|
|
||||||
if state == "present":
|
|
||||||
|
|
||||||
# Generate args
|
|
||||||
args = gen_args(permission, attribute, membergroup, group)
|
|
||||||
|
|
||||||
if action == "delegation":
|
|
||||||
# Found the delegation
|
|
||||||
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, "delegation_mod", args])
|
|
||||||
else:
|
|
||||||
commands.append([name, "delegation_add", args])
|
|
||||||
|
|
||||||
elif action == "member":
|
|
||||||
if res_find is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No delegation '%s'" % name)
|
|
||||||
|
|
||||||
if attribute is None:
|
|
||||||
ansible_module.fail_json(msg="No attributes given")
|
|
||||||
|
|
||||||
# New attribute list (add given ones to find result)
|
|
||||||
# Make list with unique entries
|
|
||||||
attrs = list(set(list(res_find["attrs"]) + attribute))
|
|
||||||
if len(attrs) > len(res_find["attrs"]):
|
|
||||||
commands.append([name, "delegation_mod",
|
|
||||||
{"attrs": attrs}])
|
|
||||||
|
|
||||||
elif state == "absent":
|
|
||||||
if action == "delegation":
|
|
||||||
if res_find is not None:
|
|
||||||
commands.append([name, "delegation_del", {}])
|
|
||||||
|
|
||||||
elif action == "member":
|
|
||||||
if res_find is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No delegation '%s'" % name)
|
|
||||||
|
|
||||||
if attribute is None:
|
|
||||||
ansible_module.fail_json(msg="No attributes given")
|
|
||||||
|
|
||||||
# New attribute list (remove given ones from find result)
|
|
||||||
# Make list with unique entries
|
|
||||||
attrs = list(set(res_find["attrs"]) - set(attribute))
|
|
||||||
if len(attrs) < 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="At minimum one attribute is needed.")
|
|
||||||
|
|
||||||
# Entries New number of attributes is smaller
|
|
||||||
if len(attrs) < len(res_find["attrs"]):
|
|
||||||
commands.append([name, "delegation_mod",
|
|
||||||
{"attrs": attrs}])
|
|
||||||
|
|
||||||
else:
|
|
||||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
|
||||||
|
|
||||||
# Execute commands
|
|
||||||
|
|
||||||
for name, command, args in commands:
|
|
||||||
try:
|
|
||||||
result = api_command(ansible_module, command, name,
|
|
||||||
args)
|
|
||||||
if "completed" in result:
|
|
||||||
if result["completed"] > 0:
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
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()
|
|
||||||
@@ -106,7 +106,6 @@ RETURN = '''
|
|||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
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, \
|
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||||
module_params_get
|
module_params_get
|
||||||
@@ -151,7 +150,7 @@ def forwarder_list(forwarders):
|
|||||||
formatter = "{ip_address} port {port}"
|
formatter = "{ip_address} port {port}"
|
||||||
else:
|
else:
|
||||||
formatter = "{ip_address}"
|
formatter = "{ip_address}"
|
||||||
fwd_list.append(to_text(formatter.format(**forwarder)))
|
fwd_list.append(formatter.format(**forwarder))
|
||||||
return fwd_list
|
return fwd_list
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -41,14 +41,8 @@ options:
|
|||||||
name:
|
name:
|
||||||
description: The zone name string.
|
description: The zone name string.
|
||||||
required: true
|
required: true
|
||||||
type: list
|
|
||||||
alises: ["zone_name"]
|
|
||||||
name_from_ip:
|
|
||||||
description: |
|
|
||||||
Derive zone name from reverse of IP (PTR).
|
|
||||||
Can only be used with `state: present`.
|
|
||||||
required: false
|
|
||||||
type: str
|
type: str
|
||||||
|
alises: ["zone_name"]
|
||||||
forwarders:
|
forwarders:
|
||||||
description: The list of global DNS forwarders.
|
description: The list of global DNS forwarders.
|
||||||
required: false
|
required: false
|
||||||
@@ -194,14 +188,6 @@ EXAMPLES = """
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = """
|
||||||
dnszone:
|
|
||||||
description: DNS Zone dict with zone name infered from `name_from_ip`.
|
|
||||||
returned:
|
|
||||||
If `state` is `present`, `name_from_ip` is used, and a zone was created.
|
|
||||||
options:
|
|
||||||
name:
|
|
||||||
description: The name of the zone created, inferred from `name_from_ip`.
|
|
||||||
returned: always
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from ipapython.dnsutil import DNSName # noqa: E402
|
from ipapython.dnsutil import DNSName # noqa: E402
|
||||||
@@ -211,12 +197,6 @@ from ansible.module_utils.ansible_freeipa_module import (
|
|||||||
is_ipv6_addr,
|
is_ipv6_addr,
|
||||||
is_valid_port,
|
is_valid_port,
|
||||||
) # noqa: E402
|
) # noqa: E402
|
||||||
import netaddr
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
unicode = str
|
|
||||||
|
|
||||||
|
|
||||||
class DNSZoneModule(FreeIPABaseModule):
|
class DNSZoneModule(FreeIPABaseModule):
|
||||||
@@ -288,7 +268,7 @@ class DNSZoneModule(FreeIPABaseModule):
|
|||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
def get_ipa_nsec3paramrecord(self, **kwargs):
|
def get_ipa_nsec3paramrecord(self):
|
||||||
nsec3param_rec = self.ipa_params.nsec3param_rec
|
nsec3param_rec = self.ipa_params.nsec3param_rec
|
||||||
if nsec3param_rec is not None:
|
if nsec3param_rec is not None:
|
||||||
error_msg = (
|
error_msg = (
|
||||||
@@ -300,7 +280,7 @@ class DNSZoneModule(FreeIPABaseModule):
|
|||||||
self.fail_json(msg=error_msg)
|
self.fail_json(msg=error_msg)
|
||||||
return nsec3param_rec
|
return nsec3param_rec
|
||||||
|
|
||||||
def get_ipa_idnsforwarders(self, **kwargs):
|
def get_ipa_idnsforwarders(self):
|
||||||
if self.ipa_params.forwarders is not None:
|
if self.ipa_params.forwarders is not None:
|
||||||
forwarders = []
|
forwarders = []
|
||||||
for forwarder in self.ipa_params.forwarders:
|
for forwarder in self.ipa_params.forwarders:
|
||||||
@@ -324,14 +304,14 @@ class DNSZoneModule(FreeIPABaseModule):
|
|||||||
|
|
||||||
return forwarders
|
return forwarders
|
||||||
|
|
||||||
def get_ipa_idnsallowtransfer(self, **kwargs):
|
def get_ipa_idnsallowtransfer(self):
|
||||||
if self.ipa_params.allow_transfer is not None:
|
if self.ipa_params.allow_transfer is not None:
|
||||||
error_msg = "Invalid ip_address for DNS allow_transfer: %s"
|
error_msg = "Invalid ip_address for DNS allow_transfer: %s"
|
||||||
self.validate_ips(self.ipa_params.allow_transfer, error_msg)
|
self.validate_ips(self.ipa_params.allow_transfer, error_msg)
|
||||||
|
|
||||||
return (";".join(self.ipa_params.allow_transfer) or "none") + ";"
|
return (";".join(self.ipa_params.allow_transfer) or "none") + ";"
|
||||||
|
|
||||||
def get_ipa_idnsallowquery(self, **kwargs):
|
def get_ipa_idnsallowquery(self):
|
||||||
if self.ipa_params.allow_query is not None:
|
if self.ipa_params.allow_query is not None:
|
||||||
error_msg = "Invalid ip_address for DNS allow_query: %s"
|
error_msg = "Invalid ip_address for DNS allow_query: %s"
|
||||||
self.validate_ips(self.ipa_params.allow_query, error_msg)
|
self.validate_ips(self.ipa_params.allow_query, error_msg)
|
||||||
@@ -354,141 +334,81 @@ class DNSZoneModule(FreeIPABaseModule):
|
|||||||
|
|
||||||
return ".".join((name, domain))
|
return ".".join((name, domain))
|
||||||
|
|
||||||
def get_ipa_idnssoarname(self, **kwargs):
|
def get_ipa_idnssoarname(self):
|
||||||
if self.ipa_params.admin_email is not None:
|
if self.ipa_params.admin_email is not None:
|
||||||
return DNSName(
|
return DNSName(
|
||||||
self._replace_at_symbol_in_rname(self.ipa_params.admin_email)
|
self._replace_at_symbol_in_rname(self.ipa_params.admin_email)
|
||||||
)
|
)
|
||||||
|
|
||||||
def get_ipa_idnssoamname(self, **kwargs):
|
def get_ipa_idnssoamname(self):
|
||||||
if self.ipa_params.name_server is not None:
|
if self.ipa_params.name_server is not None:
|
||||||
return DNSName(self.ipa_params.name_server)
|
return DNSName(self.ipa_params.name_server)
|
||||||
|
|
||||||
def get_ipa_skip_overlap_check(self, **kwargs):
|
def get_ipa_skip_overlap_check(self):
|
||||||
zone = kwargs.get('zone')
|
if not self.zone and self.ipa_params.skip_overlap_check is not None:
|
||||||
if not zone and self.ipa_params.skip_overlap_check is not None:
|
|
||||||
return self.ipa_params.skip_overlap_check
|
return self.ipa_params.skip_overlap_check
|
||||||
|
|
||||||
def get_ipa_skip_nameserver_check(self, **kwargs):
|
def get_ipa_skip_nameserver_check(self):
|
||||||
zone = kwargs.get('zone')
|
if not self.zone and self.ipa_params.skip_nameserver_check is not None:
|
||||||
if not zone and self.ipa_params.skip_nameserver_check is not None:
|
|
||||||
return self.ipa_params.skip_nameserver_check
|
return self.ipa_params.skip_nameserver_check
|
||||||
|
|
||||||
def __reverse_zone_name(self, ipaddress):
|
|
||||||
"""
|
|
||||||
Infer reverse zone name from an ip address.
|
|
||||||
|
|
||||||
This function uses the same heuristics as FreeIPA to infer the zone
|
|
||||||
name from ip.
|
|
||||||
"""
|
|
||||||
try:
|
|
||||||
ip = netaddr.IPAddress(str(ipaddress))
|
|
||||||
except (netaddr.AddrFormatError, ValueError):
|
|
||||||
net = netaddr.IPNetwork(ipaddress)
|
|
||||||
items = net.ip.reverse_dns.split('.')
|
|
||||||
prefixlen = net.prefixlen
|
|
||||||
ip_version = net.version
|
|
||||||
else:
|
|
||||||
items = ip.reverse_dns.split('.')
|
|
||||||
prefixlen = 24 if ip.version == 4 else 64
|
|
||||||
ip_version = ip.version
|
|
||||||
if ip_version == 4:
|
|
||||||
return u'.'.join(items[4 - prefixlen // 8:])
|
|
||||||
elif ip_version == 6:
|
|
||||||
return u'.'.join(items[32 - prefixlen // 4:])
|
|
||||||
else:
|
|
||||||
self.fail_json(msg="Invalid IP version for reverse zone.")
|
|
||||||
|
|
||||||
def get_zone(self, zone_name):
|
def get_zone(self, zone_name):
|
||||||
get_zone_args = {"idnsname": zone_name, "all": True}
|
get_zone_args = {"idnsname": zone_name, "all": True}
|
||||||
response = self.api_command("dnszone_find", args=get_zone_args)
|
response = self.api_command("dnszone_find", args=get_zone_args)
|
||||||
|
|
||||||
zone = None
|
|
||||||
is_zone_active = False
|
|
||||||
|
|
||||||
if response["count"] == 1:
|
if response["count"] == 1:
|
||||||
zone = response["result"][0]
|
self.zone = response["result"][0]
|
||||||
is_zone_active = zone.get("idnszoneactive") == ["TRUE"]
|
self.is_zone_active = self.zone.get("idnszoneactive") == ["TRUE"]
|
||||||
|
return self.zone
|
||||||
|
|
||||||
return zone, is_zone_active
|
# Zone doesn't exist yet
|
||||||
|
self.zone = None
|
||||||
|
self.is_zone_active = False
|
||||||
|
|
||||||
def get_zone_names(self):
|
@property
|
||||||
zone_names = self.__get_zone_names_from_params()
|
def zone_name(self):
|
||||||
if len(zone_names) > 1 and self.ipa_params.state != "absent":
|
|
||||||
self.fail_json(
|
|
||||||
msg=("Please provide a single name. Multiple values for 'name'"
|
|
||||||
"can only be supplied for state 'absent'.")
|
|
||||||
)
|
|
||||||
|
|
||||||
return zone_names
|
|
||||||
|
|
||||||
def __get_zone_names_from_params(self):
|
|
||||||
if not self.ipa_params.name:
|
|
||||||
return [self.__reverse_zone_name(self.ipa_params.name_from_ip)]
|
|
||||||
return self.ipa_params.name
|
return self.ipa_params.name
|
||||||
|
|
||||||
def check_ipa_params(self):
|
|
||||||
if not self.ipa_params.name and not self.ipa_params.name_from_ip:
|
|
||||||
self.fail_json(
|
|
||||||
msg="Either `name` or `name_from_ip` must be provided."
|
|
||||||
)
|
|
||||||
if self.ipa_params.state != "present" and self.ipa_params.name_from_ip:
|
|
||||||
self.fail_json(
|
|
||||||
msg=(
|
|
||||||
"Cannot use argument `name_from_ip` with state `%s`."
|
|
||||||
% self.ipa_params.state
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
def define_ipa_commands(self):
|
def define_ipa_commands(self):
|
||||||
for zone_name in self.get_zone_names():
|
# Look for existing zone in IPA
|
||||||
# Look for existing zone in IPA
|
self.get_zone(self.zone_name)
|
||||||
zone, is_zone_active = self.get_zone(zone_name)
|
args = self.get_ipa_command_args()
|
||||||
args = self.get_ipa_command_args(zone=zone)
|
just_added = False
|
||||||
just_added = False
|
|
||||||
|
|
||||||
if self.ipa_params.state in ["present", "enabled", "disabled"]:
|
if self.ipa_params.state in ["present", "enabled", "disabled"]:
|
||||||
if not zone:
|
if not self.zone:
|
||||||
# Since the zone doesn't exist we just create it
|
# Since the zone doesn't exist we just create it
|
||||||
# with given args
|
# with given args
|
||||||
self.add_ipa_command("dnszone_add", zone_name, args)
|
self.add_ipa_command("dnszone_add", self.zone_name, args)
|
||||||
is_zone_active = True
|
self.is_zone_active = True
|
||||||
just_added = True
|
just_added = True
|
||||||
|
|
||||||
else:
|
else:
|
||||||
# Zone already exist so we need to verify if given args
|
# Zone already exist so we need to verify if given args
|
||||||
# matches the current config. If not we updated it.
|
# matches the current config. If not we updated it.
|
||||||
if self.require_ipa_attrs_change(args, zone):
|
if self.require_ipa_attrs_change(args, self.zone):
|
||||||
self.add_ipa_command("dnszone_mod", zone_name, args)
|
self.add_ipa_command("dnszone_mod", self.zone_name, args)
|
||||||
|
|
||||||
if self.ipa_params.state == "enabled" and not is_zone_active:
|
if self.ipa_params.state == "enabled" and not self.is_zone_active:
|
||||||
self.add_ipa_command("dnszone_enable", zone_name)
|
self.add_ipa_command("dnszone_enable", self.zone_name)
|
||||||
|
|
||||||
if self.ipa_params.state == "disabled" and is_zone_active:
|
if self.ipa_params.state == "disabled" and self.is_zone_active:
|
||||||
self.add_ipa_command("dnszone_disable", zone_name)
|
self.add_ipa_command("dnszone_disable", self.zone_name)
|
||||||
|
|
||||||
if self.ipa_params.state == "absent":
|
if self.ipa_params.state == "absent":
|
||||||
if zone:
|
if self.zone:
|
||||||
self.add_ipa_command("dnszone_del", zone_name)
|
self.add_ipa_command("dnszone_del", self.zone_name)
|
||||||
|
|
||||||
# Due to a bug in FreeIPA dnszone-add won't set
|
# Due to a bug in FreeIPA dnszone-add won't set
|
||||||
# SOA Serial. The good news is that dnszone-mod does the job.
|
# SOA Serial. The good news is that dnszone-mod does the job.
|
||||||
# See: https://pagure.io/freeipa/issue/8227
|
# See: https://pagure.io/freeipa/issue/8227
|
||||||
# Because of that, if the zone was just added with a given serial
|
# Because of that, if the zone was just added with a given serial
|
||||||
# we run mod just after to workaround the bug
|
# we run mod just after to workaround the bug
|
||||||
if just_added and self.ipa_params.serial is not None:
|
if just_added and self.ipa_params.serial is not None:
|
||||||
args = {
|
args = {
|
||||||
"idnssoaserial": self.ipa_params.serial,
|
"idnssoaserial": self.ipa_params.serial,
|
||||||
}
|
}
|
||||||
self.add_ipa_command("dnszone_mod", zone_name, args)
|
self.add_ipa_command("dnszone_mod", self.zone_name, args)
|
||||||
|
|
||||||
def process_command_result(self, name, command, args, result):
|
|
||||||
super(DNSZoneModule, self).process_command_result(
|
|
||||||
name, command, args, result
|
|
||||||
)
|
|
||||||
if command == "dnszone_add" and self.ipa_params.name_from_ip:
|
|
||||||
dnszone_exit_args = self.exit_args.setdefault('dnszone', {})
|
|
||||||
dnszone_exit_args['name'] = name
|
|
||||||
|
|
||||||
|
|
||||||
def get_argument_spec():
|
def get_argument_spec():
|
||||||
@@ -506,9 +426,8 @@ def get_argument_spec():
|
|||||||
ipaadmin_principal=dict(type="str", default="admin"),
|
ipaadmin_principal=dict(type="str", default="admin"),
|
||||||
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
ipaadmin_password=dict(type="str", required=False, no_log=True),
|
||||||
name=dict(
|
name=dict(
|
||||||
type="list", default=None, required=False, aliases=["zone_name"]
|
type="str", default=None, required=True, aliases=["zone_name"]
|
||||||
),
|
),
|
||||||
name_from_ip=dict(type="str", default=None, required=False),
|
|
||||||
forwarders=dict(
|
forwarders=dict(
|
||||||
type="list",
|
type="list",
|
||||||
default=None,
|
default=None,
|
||||||
@@ -548,11 +467,7 @@ def get_argument_spec():
|
|||||||
|
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
DNSZoneModule(
|
DNSZoneModule(argument_spec=get_argument_spec()).ipa_run()
|
||||||
argument_spec=get_argument_spec(),
|
|
||||||
mutually_exclusive=[["name", "name_from_ip"]],
|
|
||||||
required_one_of=[["name", "name_from_ip"]],
|
|
||||||
).ipa_run()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
|||||||
@@ -70,12 +70,6 @@ options:
|
|||||||
- Only usable with IPA versions 4.8.4 and up.
|
- Only usable with IPA versions 4.8.4 and up.
|
||||||
required: false
|
required: false
|
||||||
type: list
|
type: list
|
||||||
rename:
|
|
||||||
description:
|
|
||||||
- Rename hostgroup to the given name.
|
|
||||||
- Only usable with IPA versions 4.8.7 and up.
|
|
||||||
required: false
|
|
||||||
aliases: ["new_name"]
|
|
||||||
action:
|
action:
|
||||||
description: Work on hostgroup or member level
|
description: Work on hostgroup or member level
|
||||||
default: hostgroup
|
default: hostgroup
|
||||||
@@ -83,7 +77,7 @@ options:
|
|||||||
state:
|
state:
|
||||||
description: State to ensure
|
description: State to ensure
|
||||||
default: present
|
default: present
|
||||||
choices: ["present", "absent", "renamed"]
|
choices: ["present", "absent"]
|
||||||
author:
|
author:
|
||||||
- Thomas Woerner
|
- Thomas Woerner
|
||||||
"""
|
"""
|
||||||
@@ -122,12 +116,6 @@ EXAMPLES = """
|
|||||||
action: member
|
action: member
|
||||||
state: absent
|
state: absent
|
||||||
|
|
||||||
# Rename hostgroup
|
|
||||||
- ipahostgroup:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: databases
|
|
||||||
rename: datalake
|
|
||||||
|
|
||||||
# Ensure host-group databases is absent
|
# Ensure host-group databases is absent
|
||||||
- ipahostgroup:
|
- ipahostgroup:
|
||||||
ipaadmin_password: SomeADMINpassword
|
ipaadmin_password: SomeADMINpassword
|
||||||
@@ -141,7 +129,7 @@ RETURN = """
|
|||||||
from ansible.module_utils.basic import AnsibleModule
|
from ansible.module_utils.basic import AnsibleModule
|
||||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||||
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
temp_kdestroy, valid_creds, api_connect, api_command, compare_args_ipa, \
|
||||||
module_params_get, gen_add_del_lists, api_check_command, api_check_param
|
module_params_get, gen_add_del_lists, api_check_command
|
||||||
|
|
||||||
|
|
||||||
def find_hostgroup(module, name):
|
def find_hostgroup(module, name):
|
||||||
@@ -161,14 +149,12 @@ def find_hostgroup(module, name):
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
def gen_args(description, nomembers, rename):
|
def gen_args(description, nomembers):
|
||||||
_args = {}
|
_args = {}
|
||||||
if description is not None:
|
if description is not None:
|
||||||
_args["description"] = description
|
_args["description"] = description
|
||||||
if nomembers is not None:
|
if nomembers is not None:
|
||||||
_args["nomembers"] = nomembers
|
_args["nomembers"] = nomembers
|
||||||
if rename is not None:
|
|
||||||
_args["rename"] = rename
|
|
||||||
|
|
||||||
return _args
|
return _args
|
||||||
|
|
||||||
@@ -200,13 +186,11 @@ def main():
|
|||||||
membermanager_user=dict(required=False, type='list', default=None),
|
membermanager_user=dict(required=False, type='list', default=None),
|
||||||
membermanager_group=dict(required=False, type='list',
|
membermanager_group=dict(required=False, type='list',
|
||||||
default=None),
|
default=None),
|
||||||
rename=dict(required=False, type='str', default=None,
|
|
||||||
aliases=["new_name"]),
|
|
||||||
action=dict(type="str", default="hostgroup",
|
action=dict(type="str", default="hostgroup",
|
||||||
choices=["member", "hostgroup"]),
|
choices=["member", "hostgroup"]),
|
||||||
# state
|
# state
|
||||||
state=dict(type="str", default="present",
|
state=dict(type="str", default="present",
|
||||||
choices=["present", "absent", "renamed"]),
|
choices=["present", "absent"]),
|
||||||
),
|
),
|
||||||
supports_check_mode=True,
|
supports_check_mode=True,
|
||||||
)
|
)
|
||||||
@@ -231,7 +215,6 @@ def main():
|
|||||||
"membermanager_user")
|
"membermanager_user")
|
||||||
membermanager_group = module_params_get(ansible_module,
|
membermanager_group = module_params_get(ansible_module,
|
||||||
"membermanager_group")
|
"membermanager_group")
|
||||||
rename = module_params_get(ansible_module, "rename")
|
|
||||||
action = module_params_get(ansible_module, "action")
|
action = module_params_get(ansible_module, "action")
|
||||||
# state
|
# state
|
||||||
state = module_params_get(ansible_module, "state")
|
state = module_params_get(ansible_module, "state")
|
||||||
@@ -242,38 +225,19 @@ def main():
|
|||||||
if len(names) != 1:
|
if len(names) != 1:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="Only one hostgroup can be added at a time.")
|
msg="Only one hostgroup can be added at a time.")
|
||||||
invalid = ["rename"]
|
|
||||||
if action == "member":
|
if action == "member":
|
||||||
invalid.extend(["description", "nomembers"])
|
invalid = ["description", "nomembers"]
|
||||||
for x in invalid:
|
for x in invalid:
|
||||||
if vars()[x] is not None:
|
if vars()[x] is not None:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="Argument '%s' can not be used with action "
|
msg="Argument '%s' can not be used with action "
|
||||||
"'%s'" % (x, action))
|
"'%s'" % (x, action))
|
||||||
|
|
||||||
if state == "renamed":
|
|
||||||
if len(names) != 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Only one hostgroup can be added at a time.")
|
|
||||||
if action == "member":
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Action '%s' can not be used with state '%s'" %
|
|
||||||
(action, state))
|
|
||||||
invalid = [
|
|
||||||
"description", "nomembers", "host", "hostgroup",
|
|
||||||
"membermanager_user", "membermanager_group"
|
|
||||||
]
|
|
||||||
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))
|
|
||||||
|
|
||||||
if state == "absent":
|
if state == "absent":
|
||||||
if len(names) < 1:
|
if len(names) < 1:
|
||||||
ansible_module.fail_json(
|
ansible_module.fail_json(
|
||||||
msg="No name given.")
|
msg="No name given.")
|
||||||
invalid = ["description", "nomembers", "rename"]
|
invalid = ["description", "nomembers"]
|
||||||
if action == "hostgroup":
|
if action == "hostgroup":
|
||||||
invalid.extend(["host", "hostgroup"])
|
invalid.extend(["host", "hostgroup"])
|
||||||
for x in invalid:
|
for x in invalid:
|
||||||
@@ -302,10 +266,6 @@ def main():
|
|||||||
msg="Managing a membermanager user or group is not supported "
|
msg="Managing a membermanager user or group is not supported "
|
||||||
"by your IPA version"
|
"by your IPA version"
|
||||||
)
|
)
|
||||||
has_mod_rename = api_check_param("hostgroup_mod", "rename")
|
|
||||||
if not has_mod_rename and rename is not None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Renaming hostgroups is not supported by your IPA version")
|
|
||||||
|
|
||||||
commands = []
|
commands = []
|
||||||
|
|
||||||
@@ -316,7 +276,7 @@ def main():
|
|||||||
# Create command
|
# Create command
|
||||||
if state == "present":
|
if state == "present":
|
||||||
# Generate args
|
# Generate args
|
||||||
args = gen_args(description, nomembers, rename)
|
args = gen_args(description, nomembers)
|
||||||
|
|
||||||
if action == "hostgroup":
|
if action == "hostgroup":
|
||||||
# Found the hostgroup
|
# Found the hostgroup
|
||||||
@@ -415,22 +375,6 @@ def main():
|
|||||||
}]
|
}]
|
||||||
)
|
)
|
||||||
|
|
||||||
elif state == "renamed":
|
|
||||||
if res_find is not None:
|
|
||||||
if rename != name:
|
|
||||||
commands.append(
|
|
||||||
[name, "hostgroup_mod", {"rename": rename}]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
# If a hostgroup with the desired name exists, do nothing.
|
|
||||||
new_find = find_hostgroup(ansible_module, rename)
|
|
||||||
if new_find is None:
|
|
||||||
# Fail only if the either hostsgroups do not exist.
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Attribute `rename` can not be used, unless "
|
|
||||||
"hostgroup exists."
|
|
||||||
)
|
|
||||||
|
|
||||||
elif state == "absent":
|
elif state == "absent":
|
||||||
if action == "hostgroup":
|
if action == "hostgroup":
|
||||||
if res_find is not None:
|
if res_find is not None:
|
||||||
|
|||||||
@@ -1,220 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Authors:
|
|
||||||
# Thomas Woerner <twoerner@redhat.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2020 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: ipalocation
|
|
||||||
short description: Manage FreeIPA location
|
|
||||||
description: Manage FreeIPA location
|
|
||||||
options:
|
|
||||||
ipaadmin_principal:
|
|
||||||
description: The admin principal.
|
|
||||||
default: admin
|
|
||||||
ipaadmin_password:
|
|
||||||
description: The admin password.
|
|
||||||
required: false
|
|
||||||
name:
|
|
||||||
description: The list of location name strings.
|
|
||||||
required: true
|
|
||||||
aliases: ["idnsname"]
|
|
||||||
description:
|
|
||||||
description: The IPA location string
|
|
||||||
required: false
|
|
||||||
state:
|
|
||||||
description: The state to ensure.
|
|
||||||
choices: ["present", "absent"]
|
|
||||||
default: present
|
|
||||||
required: true
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = """
|
|
||||||
# Ensure location my_location1 is present
|
|
||||||
- ipalocation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: my_location1
|
|
||||||
description: My location 1
|
|
||||||
|
|
||||||
# Ensure location my_location1 is absent
|
|
||||||
- ipalocation:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: my_location1
|
|
||||||
state: absent
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = """
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
from ansible.module_utils.ansible_freeipa_module import \
|
|
||||||
temp_kinit, temp_kdestroy, valid_creds, api_connect, api_command, \
|
|
||||||
compare_args_ipa, module_params_get
|
|
||||||
import six
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
unicode = str
|
|
||||||
|
|
||||||
|
|
||||||
def find_location(module, name):
|
|
||||||
"""Find if a location with the given name already exist."""
|
|
||||||
try:
|
|
||||||
_result = api_command(module, "location_show", name, {"all": True})
|
|
||||||
except Exception: # pylint: disable=broad-except
|
|
||||||
# An exception is raised if location name is not found.
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return _result["result"]
|
|
||||||
|
|
||||||
|
|
||||||
def gen_args(description):
|
|
||||||
_args = {}
|
|
||||||
if description is not None:
|
|
||||||
_args["description"] = description
|
|
||||||
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=["idnsname"],
|
|
||||||
default=None, required=True),
|
|
||||||
# present
|
|
||||||
description=dict(required=False, type='str', default=None),
|
|
||||||
# state
|
|
||||||
state=dict(type="str", default="present",
|
|
||||||
choices=["present", "absent"]),
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
ansible_module._ansible_debug = True
|
|
||||||
|
|
||||||
# Get parameters
|
|
||||||
|
|
||||||
# general
|
|
||||||
ipaadmin_principal = module_params_get(ansible_module,
|
|
||||||
"ipaadmin_principal")
|
|
||||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
|
||||||
names = module_params_get(ansible_module, "name")
|
|
||||||
|
|
||||||
# present
|
|
||||||
description = module_params_get(ansible_module, "description")
|
|
||||||
|
|
||||||
# state
|
|
||||||
state = module_params_get(ansible_module, "state")
|
|
||||||
|
|
||||||
# Check parameters
|
|
||||||
|
|
||||||
if state == "present":
|
|
||||||
if len(names) != 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Only one location be added at a time.")
|
|
||||||
|
|
||||||
if state == "absent":
|
|
||||||
if len(names) < 1:
|
|
||||||
ansible_module.fail_json(msg="No name given.")
|
|
||||||
invalid = ["description"]
|
|
||||||
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(ansible_module, ipaadmin_principal):
|
|
||||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
|
||||||
ipaadmin_password)
|
|
||||||
api_connect()
|
|
||||||
|
|
||||||
commands = []
|
|
||||||
for name in names:
|
|
||||||
# Make sure location exists
|
|
||||||
res_find = find_location(ansible_module, name)
|
|
||||||
|
|
||||||
# Create command
|
|
||||||
if state == "present":
|
|
||||||
|
|
||||||
# Generate args
|
|
||||||
args = gen_args(description)
|
|
||||||
|
|
||||||
# Found the location
|
|
||||||
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, "location_mod", args])
|
|
||||||
else:
|
|
||||||
commands.append([name, "location_add", args])
|
|
||||||
|
|
||||||
elif state == "absent":
|
|
||||||
if res_find is not None:
|
|
||||||
commands.append([name, "location_del", {}])
|
|
||||||
|
|
||||||
else:
|
|
||||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
|
||||||
|
|
||||||
# Execute commands
|
|
||||||
|
|
||||||
for name, command, args in commands:
|
|
||||||
try:
|
|
||||||
result = api_command(ansible_module, command, name,
|
|
||||||
args)
|
|
||||||
if "completed" in result:
|
|
||||||
if result["completed"] > 0:
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
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,357 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Authors:
|
|
||||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2020 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-freeipa module to manage FreeIPA privileges."""
|
|
||||||
|
|
||||||
|
|
||||||
ANSIBLE_METADATA = {
|
|
||||||
"metadata_version": "1.0",
|
|
||||||
"supported_by": "community",
|
|
||||||
"status": ["preview"],
|
|
||||||
}
|
|
||||||
|
|
||||||
DOCUMENTATION = """
|
|
||||||
---
|
|
||||||
module: ipaprivilege
|
|
||||||
short description: Manage FreeIPA privilege
|
|
||||||
description: Manage FreeIPA privilege and privilege members
|
|
||||||
options:
|
|
||||||
ipaadmin_principal:
|
|
||||||
description: The admin principal.
|
|
||||||
default: admin
|
|
||||||
ipaadmin_password:
|
|
||||||
description: The admin password.
|
|
||||||
required: false
|
|
||||||
name:
|
|
||||||
description: The list of privilege name strings.
|
|
||||||
required: true
|
|
||||||
aliases: ["cn"]
|
|
||||||
description:
|
|
||||||
description: Privilege description
|
|
||||||
required: false
|
|
||||||
rename:
|
|
||||||
description: Rename the privilege object.
|
|
||||||
required: false
|
|
||||||
aliases: ["new_name"]
|
|
||||||
permission:
|
|
||||||
description: Permissions to be added to the privilege.
|
|
||||||
required: false
|
|
||||||
action:
|
|
||||||
description: Work on privilege or member level.
|
|
||||||
choices: ["privilege", "member"]
|
|
||||||
default: privilege
|
|
||||||
required: false
|
|
||||||
state:
|
|
||||||
description: The state to ensure.
|
|
||||||
choices: ["present", "absent", "renamed"]
|
|
||||||
default: present
|
|
||||||
required: true
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = """
|
|
||||||
# Ensure privilege "Broad Privilege" is present
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
description: Broad Privilege
|
|
||||||
|
|
||||||
# Ensure privilege "Broad Privilege" has permissions set
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
permission:
|
|
||||||
- "Write IPA Configuration"
|
|
||||||
- "System: Write DNS Configuration"
|
|
||||||
- "System: Update DNS Entries"
|
|
||||||
action: member
|
|
||||||
|
|
||||||
# Ensure privilege member permission 'Write IPA Configuration' is absent
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
permission:
|
|
||||||
- "Write IPA Configuration"
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
# Rename privilege "Broad Privilege" to "DNS Special Privilege"
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: Broad Privilege
|
|
||||||
rename: DNS Special Privilege
|
|
||||||
state: renamed
|
|
||||||
|
|
||||||
# Ensure privilege "DNS Special Privilege" is absent
|
|
||||||
- ipaprivilege:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: DNS Special Privilege
|
|
||||||
state: absent
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = """
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
from ansible.module_utils.ansible_freeipa_module import \
|
|
||||||
temp_kinit, temp_kdestroy, valid_creds, api_connect, api_command, \
|
|
||||||
compare_args_ipa, module_params_get, gen_add_del_lists
|
|
||||||
import six
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
unicode = str
|
|
||||||
|
|
||||||
|
|
||||||
def find_privilege(module, name):
|
|
||||||
"""Find if a privilege with the given name already exist."""
|
|
||||||
try:
|
|
||||||
_result = api_command(module, "privilege_show", name, {"all": True})
|
|
||||||
except Exception: # pylint: disable=broad-except
|
|
||||||
# An exception is raised if privilege name is not found.
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return _result["result"]
|
|
||||||
|
|
||||||
|
|
||||||
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(required=False, type='str', default=None),
|
|
||||||
rename=dict(required=False, type='str', default=None,
|
|
||||||
aliases=["new_name"], ),
|
|
||||||
permission=dict(required=False, type='list', default=None),
|
|
||||||
action=dict(type="str", default="privilege",
|
|
||||||
choices=["member", "privilege"]),
|
|
||||||
# state
|
|
||||||
state=dict(type="str", default="present",
|
|
||||||
choices=["present", "absent", "renamed"]),
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
ansible_module._ansible_debug = True
|
|
||||||
|
|
||||||
# Get parameters
|
|
||||||
|
|
||||||
# general
|
|
||||||
ipaadmin_principal = module_params_get(ansible_module,
|
|
||||||
"ipaadmin_principal")
|
|
||||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
|
||||||
names = module_params_get(ansible_module, "name")
|
|
||||||
|
|
||||||
# present
|
|
||||||
description = module_params_get(ansible_module, "description")
|
|
||||||
permission = module_params_get(ansible_module, "permission")
|
|
||||||
rename = module_params_get(ansible_module, "rename")
|
|
||||||
action = module_params_get(ansible_module, "action")
|
|
||||||
|
|
||||||
# state
|
|
||||||
state = module_params_get(ansible_module, "state")
|
|
||||||
|
|
||||||
# Check parameters
|
|
||||||
invalid = []
|
|
||||||
|
|
||||||
if state == "present":
|
|
||||||
if len(names) != 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Only one privilege be added at a time.")
|
|
||||||
if action == "member":
|
|
||||||
invalid = ["description"]
|
|
||||||
|
|
||||||
if state == "absent":
|
|
||||||
if len(names) < 1:
|
|
||||||
ansible_module.fail_json(msg="No name given.")
|
|
||||||
invalid = ["description", "rename"]
|
|
||||||
if action == "privilege":
|
|
||||||
invalid.append("permission")
|
|
||||||
|
|
||||||
if state == "renamed":
|
|
||||||
if len(names) != 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Only one privilege be added at a time.")
|
|
||||||
invalid = ["description", "permission"]
|
|
||||||
if action != "privilege":
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Action '%s' can not be used with state '%s'"
|
|
||||||
% (action, state))
|
|
||||||
|
|
||||||
for x in invalid:
|
|
||||||
if vars()[x] is not None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Argument '%s' can not be used with action "
|
|
||||||
"'%s' and state '%s'" % (x, action, state))
|
|
||||||
|
|
||||||
# Init
|
|
||||||
|
|
||||||
changed = False
|
|
||||||
exit_args = {}
|
|
||||||
ccache_dir = None
|
|
||||||
ccache_name = None
|
|
||||||
try:
|
|
||||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
|
||||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
|
||||||
ipaadmin_password)
|
|
||||||
api_connect()
|
|
||||||
|
|
||||||
commands = []
|
|
||||||
for name in names:
|
|
||||||
# Make sure privilege exists
|
|
||||||
res_find = find_privilege(ansible_module, name)
|
|
||||||
|
|
||||||
# Create command
|
|
||||||
if state == "present":
|
|
||||||
|
|
||||||
args = {}
|
|
||||||
if description:
|
|
||||||
args['description'] = description
|
|
||||||
|
|
||||||
if action == "privilege":
|
|
||||||
# Found the privilege
|
|
||||||
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, "privilege_mod", args])
|
|
||||||
else:
|
|
||||||
commands.append([name, "privilege_add", args])
|
|
||||||
|
|
||||||
member_args = {}
|
|
||||||
if permission:
|
|
||||||
member_args['permission'] = permission
|
|
||||||
|
|
||||||
if not compare_args_ipa(ansible_module, member_args,
|
|
||||||
res_find):
|
|
||||||
|
|
||||||
# Generate addition and removal lists
|
|
||||||
permission_add, permission_del = gen_add_del_lists(
|
|
||||||
permission, res_find.get("member_permission"))
|
|
||||||
|
|
||||||
# Add members
|
|
||||||
if len(permission_add) > 0:
|
|
||||||
commands.append([name, "privilege_add_permission",
|
|
||||||
{
|
|
||||||
"permission": permission_add,
|
|
||||||
}])
|
|
||||||
# Remove members
|
|
||||||
if len(permission_del) > 0:
|
|
||||||
commands.append([
|
|
||||||
name,
|
|
||||||
"privilege_remove_permission",
|
|
||||||
{"permission": permission_del}
|
|
||||||
])
|
|
||||||
|
|
||||||
elif action == "member":
|
|
||||||
if res_find is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No privilege '%s'" % name)
|
|
||||||
|
|
||||||
if permission is None:
|
|
||||||
ansible_module.fail_json(msg="No permission given")
|
|
||||||
|
|
||||||
commands.append([name, "privilege_add_permission",
|
|
||||||
{"permission": permission}])
|
|
||||||
|
|
||||||
elif state == "absent":
|
|
||||||
if action == "privilege":
|
|
||||||
if res_find is not None:
|
|
||||||
commands.append([name, "privilege_del", {}])
|
|
||||||
|
|
||||||
elif action == "member":
|
|
||||||
if res_find is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No privilege '%s'" % name)
|
|
||||||
|
|
||||||
if permission is None:
|
|
||||||
ansible_module.fail_json(msg="No permission given")
|
|
||||||
|
|
||||||
commands.append([name, "privilege_remove_permission",
|
|
||||||
{
|
|
||||||
"permission": permission,
|
|
||||||
}])
|
|
||||||
|
|
||||||
elif state == "renamed":
|
|
||||||
if not rename:
|
|
||||||
ansible_module.fail_json(msg="No rename value given.")
|
|
||||||
|
|
||||||
if res_find is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No privilege found to be renamed: '%s'" % (name))
|
|
||||||
|
|
||||||
if name != rename:
|
|
||||||
commands.append(
|
|
||||||
[name, "privilege_mod", {"rename": rename}])
|
|
||||||
|
|
||||||
else:
|
|
||||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
|
||||||
|
|
||||||
# Execute commands
|
|
||||||
|
|
||||||
for name, command, args in commands:
|
|
||||||
try:
|
|
||||||
result = api_command(ansible_module, command, name,
|
|
||||||
args)
|
|
||||||
if "completed" in result:
|
|
||||||
if result["completed"] > 0:
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
changed = True
|
|
||||||
except Exception as e:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="%s: %s: %s" % (command, name, str(e)))
|
|
||||||
# Get all errors
|
|
||||||
# All "already a member" and "not a member" failures in the
|
|
||||||
# result are ignored. All others are reported.
|
|
||||||
errors = []
|
|
||||||
for failed_item in result.get("failed", []):
|
|
||||||
failed = result["failed"][failed_item]
|
|
||||||
for member_type in failed:
|
|
||||||
for member, failure in failed[member_type]:
|
|
||||||
if "already a member" in failure \
|
|
||||||
or "not a member" in failure:
|
|
||||||
continue
|
|
||||||
errors.append("%s: %s %s: %s" % (
|
|
||||||
command, member_type, member, failure))
|
|
||||||
if len(errors) > 0:
|
|
||||||
ansible_module.fail_json(msg=", ".join(errors))
|
|
||||||
|
|
||||||
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()
|
|
||||||
@@ -30,9 +30,9 @@ ANSIBLE_METADATA = {
|
|||||||
|
|
||||||
DOCUMENTATION = """
|
DOCUMENTATION = """
|
||||||
---
|
---
|
||||||
module: iparole
|
module: ipaservice
|
||||||
short description: Manage FreeIPA role
|
short description: Manage FreeIPA service
|
||||||
description: Manage FreeIPA role
|
description: Manage FreeIPA service
|
||||||
options:
|
options:
|
||||||
ipaadmin_principal:
|
ipaadmin_principal:
|
||||||
description: The admin principal.
|
description: The admin principal.
|
||||||
@@ -66,7 +66,7 @@ options:
|
|||||||
description: List of services.
|
description: List of services.
|
||||||
required: false
|
required: false
|
||||||
action:
|
action:
|
||||||
description: Work on role or member level.
|
description: Work on service or member level.
|
||||||
choices: ["role", "member"]
|
choices: ["role", "member"]
|
||||||
default: role
|
default: role
|
||||||
required: false
|
required: false
|
||||||
|
|||||||
@@ -1,323 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Authors:
|
|
||||||
# Thomas Woerner <twoerner@redhat.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2020 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: ipaselfservice
|
|
||||||
short description: Manage FreeIPA selfservices
|
|
||||||
description: Manage FreeIPA selfservices and selfservice attributes
|
|
||||||
options:
|
|
||||||
ipaadmin_principal:
|
|
||||||
description: The admin principal.
|
|
||||||
default: admin
|
|
||||||
ipaadmin_password:
|
|
||||||
description: The admin password.
|
|
||||||
required: false
|
|
||||||
name:
|
|
||||||
description: The list of selfservice name strings.
|
|
||||||
required: true
|
|
||||||
aliases: ["aciname"]
|
|
||||||
permission:
|
|
||||||
description: Permissions to grant (read, write). Default is write.
|
|
||||||
required: false
|
|
||||||
aliases: ["permissions"]
|
|
||||||
attribute:
|
|
||||||
description: Attribute list to which the selfservice applies
|
|
||||||
required: false
|
|
||||||
aliases: ["attrs"]
|
|
||||||
action:
|
|
||||||
description: Work on selfservice or member level.
|
|
||||||
choices: ["selfservice", "member"]
|
|
||||||
default: selfservice
|
|
||||||
required: false
|
|
||||||
state:
|
|
||||||
description: The state to ensure.
|
|
||||||
choices: ["present", "absent"]
|
|
||||||
default: present
|
|
||||||
required: true
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = """
|
|
||||||
# Ensure selfservice "Users can manage their own name details" is present
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
permission: read
|
|
||||||
attribute:
|
|
||||||
- title
|
|
||||||
- initials
|
|
||||||
|
|
||||||
# Ensure selfservice "Users can manage their own name details" member
|
|
||||||
# attribute departmentnumber is present
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
attribute:
|
|
||||||
- initials
|
|
||||||
action: member
|
|
||||||
|
|
||||||
# Ensure selfservice "Users can manage their own name details" member
|
|
||||||
# attributes employeetype and employeenumber are present
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
attribute:
|
|
||||||
- title
|
|
||||||
- initials
|
|
||||||
action: member
|
|
||||||
state: absent
|
|
||||||
|
|
||||||
# Ensure selfservice "Users can manage their own name details" is absent
|
|
||||||
- ipaselfservice:
|
|
||||||
ipaadmin_password: SomeADMINpassword
|
|
||||||
name: "Users can manage their own name details"
|
|
||||||
state: absent
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = """
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
from ansible.module_utils.ansible_freeipa_module import \
|
|
||||||
temp_kinit, temp_kdestroy, valid_creds, api_connect, api_command, \
|
|
||||||
compare_args_ipa, module_params_get
|
|
||||||
import six
|
|
||||||
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
unicode = str
|
|
||||||
|
|
||||||
|
|
||||||
def find_selfservice(module, name):
|
|
||||||
"""Find if a selfservice with the given name already exist."""
|
|
||||||
try:
|
|
||||||
_result = api_command(module, "selfservice_show", name, {"all": True})
|
|
||||||
except Exception: # pylint: disable=broad-except
|
|
||||||
# An exception is raised if selfservice name is not found.
|
|
||||||
return None
|
|
||||||
else:
|
|
||||||
return _result["result"]
|
|
||||||
|
|
||||||
|
|
||||||
def gen_args(permission, attribute):
|
|
||||||
_args = {}
|
|
||||||
if permission is not None:
|
|
||||||
_args["permissions"] = permission
|
|
||||||
if attribute is not None:
|
|
||||||
_args["attrs"] = attribute
|
|
||||||
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=["aciname"], default=None,
|
|
||||||
required=True),
|
|
||||||
# present
|
|
||||||
permission=dict(required=False, type='list',
|
|
||||||
aliases=["permissions"], default=None),
|
|
||||||
attribute=dict(required=False, type='list', aliases=["attrs"],
|
|
||||||
default=None),
|
|
||||||
action=dict(type="str", default="selfservice",
|
|
||||||
choices=["member", "selfservice"]),
|
|
||||||
# state
|
|
||||||
state=dict(type="str", default="present",
|
|
||||||
choices=["present", "absent"]),
|
|
||||||
),
|
|
||||||
supports_check_mode=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
ansible_module._ansible_debug = True
|
|
||||||
|
|
||||||
# Get parameters
|
|
||||||
|
|
||||||
# general
|
|
||||||
ipaadmin_principal = module_params_get(ansible_module,
|
|
||||||
"ipaadmin_principal")
|
|
||||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
|
||||||
names = module_params_get(ansible_module, "name")
|
|
||||||
|
|
||||||
# present
|
|
||||||
permission = module_params_get(ansible_module, "permission")
|
|
||||||
attribute = module_params_get(ansible_module, "attribute")
|
|
||||||
action = module_params_get(ansible_module, "action")
|
|
||||||
# state
|
|
||||||
state = module_params_get(ansible_module, "state")
|
|
||||||
|
|
||||||
# Check parameters
|
|
||||||
|
|
||||||
if state == "present":
|
|
||||||
if len(names) != 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Only one selfservice be added at a time.")
|
|
||||||
if action == "member":
|
|
||||||
invalid = ["permission"]
|
|
||||||
for x in invalid:
|
|
||||||
if vars()[x] is not None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Argument '%s' can not be used with action "
|
|
||||||
"'%s' and state '%s'" % (x, action, state))
|
|
||||||
|
|
||||||
if state == "absent":
|
|
||||||
if len(names) < 1:
|
|
||||||
ansible_module.fail_json(msg="No name given.")
|
|
||||||
invalid = ["permission"]
|
|
||||||
if action == "selfservice":
|
|
||||||
invalid.append("attribute")
|
|
||||||
for x in invalid:
|
|
||||||
if vars()[x] is not None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Argument '%s' can not be used with action "
|
|
||||||
"'%s' and state '%s'" % (x, action, state))
|
|
||||||
|
|
||||||
if permission is not None:
|
|
||||||
perm = [p for p in permission if p not in ("read", "write")]
|
|
||||||
if perm:
|
|
||||||
ansible_module.fail_json(msg="Invalid permission '%s'" % perm)
|
|
||||||
if len(set(permission)) != len(permission):
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Invalid permission '%s', items are not unique" %
|
|
||||||
repr(permission))
|
|
||||||
|
|
||||||
if attribute is not None:
|
|
||||||
if len(set(attribute)) != len(attribute):
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="Invalid attribute '%s', items are not unique" %
|
|
||||||
repr(attribute))
|
|
||||||
|
|
||||||
# Init
|
|
||||||
|
|
||||||
changed = False
|
|
||||||
exit_args = {}
|
|
||||||
ccache_dir = None
|
|
||||||
ccache_name = None
|
|
||||||
try:
|
|
||||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
|
||||||
ccache_dir, ccache_name = temp_kinit(ipaadmin_principal,
|
|
||||||
ipaadmin_password)
|
|
||||||
api_connect()
|
|
||||||
|
|
||||||
commands = []
|
|
||||||
for name in names:
|
|
||||||
# Make sure selfservice exists
|
|
||||||
res_find = find_selfservice(ansible_module, name)
|
|
||||||
|
|
||||||
# Create command
|
|
||||||
if state == "present":
|
|
||||||
|
|
||||||
# Generate args
|
|
||||||
args = gen_args(permission, attribute)
|
|
||||||
|
|
||||||
if action == "selfservice":
|
|
||||||
# Found the selfservice
|
|
||||||
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, "selfservice_mod", args])
|
|
||||||
else:
|
|
||||||
commands.append([name, "selfservice_add", args])
|
|
||||||
|
|
||||||
elif action == "member":
|
|
||||||
if res_find is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No selfservice '%s'" % name)
|
|
||||||
|
|
||||||
if attribute is None:
|
|
||||||
ansible_module.fail_json(msg="No attributes given")
|
|
||||||
|
|
||||||
# New attribute list (add given ones to find result)
|
|
||||||
# Make list with unique entries
|
|
||||||
attrs = list(set(list(res_find["attrs"]) + attribute))
|
|
||||||
if len(attrs) > len(res_find["attrs"]):
|
|
||||||
commands.append([name, "selfservice_mod",
|
|
||||||
{"attrs": attrs}])
|
|
||||||
|
|
||||||
elif state == "absent":
|
|
||||||
if action == "selfservice":
|
|
||||||
if res_find is not None:
|
|
||||||
commands.append([name, "selfservice_del", {}])
|
|
||||||
|
|
||||||
elif action == "member":
|
|
||||||
if res_find is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="No selfservice '%s'" % name)
|
|
||||||
|
|
||||||
if attribute is None:
|
|
||||||
ansible_module.fail_json(msg="No attributes given")
|
|
||||||
|
|
||||||
# New attribute list (remove given ones from find result)
|
|
||||||
# Make list with unique entries
|
|
||||||
attrs = list(set(res_find["attrs"]) - set(attribute))
|
|
||||||
if len(attrs) < 1:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="At minimum one attribute is needed.")
|
|
||||||
|
|
||||||
# Entries New number of attributes is smaller
|
|
||||||
if len(attrs) < len(res_find["attrs"]):
|
|
||||||
commands.append([name, "selfservice_mod",
|
|
||||||
{"attrs": attrs}])
|
|
||||||
|
|
||||||
else:
|
|
||||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
|
||||||
|
|
||||||
# Execute commands
|
|
||||||
|
|
||||||
for name, command, args in commands:
|
|
||||||
try:
|
|
||||||
result = api_command(ansible_module, command, name,
|
|
||||||
args)
|
|
||||||
if "completed" in result:
|
|
||||||
if result["completed"] > 0:
|
|
||||||
changed = True
|
|
||||||
else:
|
|
||||||
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()
|
|
||||||
@@ -460,7 +460,7 @@ def main():
|
|||||||
allow_retrieve_keytab_group = module_params_get(
|
allow_retrieve_keytab_group = module_params_get(
|
||||||
ansible_module, "allow_retrieve_keytab_group")
|
ansible_module, "allow_retrieve_keytab_group")
|
||||||
allow_retrieve_keytab_host = module_params_get(
|
allow_retrieve_keytab_host = module_params_get(
|
||||||
ansible_module, "allow_retrieve_keytab_host")
|
ansible_module, "allow_create_keytab_host")
|
||||||
allow_retrieve_keytab_hostgroup = module_params_get(
|
allow_retrieve_keytab_hostgroup = module_params_get(
|
||||||
ansible_module, "allow_retrieve_keytab_hostgroup")
|
ansible_module, "allow_retrieve_keytab_hostgroup")
|
||||||
delete_continue = module_params_get(ansible_module, "delete_continue")
|
delete_continue = module_params_get(ansible_module, "delete_continue")
|
||||||
@@ -727,7 +727,7 @@ def main():
|
|||||||
# Allow retrieve keytab
|
# Allow retrieve keytab
|
||||||
if len(allow_retrieve_keytab_user_add) > 0 or \
|
if len(allow_retrieve_keytab_user_add) > 0 or \
|
||||||
len(allow_retrieve_keytab_group_add) > 0 or \
|
len(allow_retrieve_keytab_group_add) > 0 or \
|
||||||
len(allow_retrieve_keytab_host_add) > 0 or \
|
len(allow_retrieve_keytab_hostgroup_add) > 0 or \
|
||||||
len(allow_retrieve_keytab_hostgroup_add) > 0:
|
len(allow_retrieve_keytab_hostgroup_add) > 0:
|
||||||
commands.append(
|
commands.append(
|
||||||
[name, "service_allow_retrieve_keytab",
|
[name, "service_allow_retrieve_keytab",
|
||||||
|
|||||||
@@ -1,274 +0,0 @@
|
|||||||
#!/usr/bin/python
|
|
||||||
# -*- coding: utf-8 -*-
|
|
||||||
|
|
||||||
# Authors:
|
|
||||||
# Rob Verduijn <rob.verduijn@gmail.com>
|
|
||||||
#
|
|
||||||
# Copyright (C) 2019 By Rob Verduijn
|
|
||||||
# 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/>.
|
|
||||||
|
|
||||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
|
||||||
temp_kdestroy, valid_creds, api_connect, api_command, module_params_get
|
|
||||||
from ansible.module_utils.basic import AnsibleModule
|
|
||||||
ANSIBLE_METADATA = {'metadata_version': '1.1',
|
|
||||||
'supported_by': 'community',
|
|
||||||
'status': ['preview'],
|
|
||||||
}
|
|
||||||
|
|
||||||
DOCUMENTATION = """
|
|
||||||
---
|
|
||||||
module: ipatrust
|
|
||||||
short_description: Manage FreeIPA Domain Trusts.
|
|
||||||
description: Manage FreeIPA Domain Trusts.
|
|
||||||
options:
|
|
||||||
realm:
|
|
||||||
description:
|
|
||||||
- Realm name
|
|
||||||
required: true
|
|
||||||
trust_type:
|
|
||||||
description:
|
|
||||||
- Trust type (ad for Active Directory, default)
|
|
||||||
default: ad
|
|
||||||
required: true
|
|
||||||
admin:
|
|
||||||
description:
|
|
||||||
- Active Directory domain administrator
|
|
||||||
required: false
|
|
||||||
password:
|
|
||||||
description:
|
|
||||||
- Active Directory domain administrator's password
|
|
||||||
required: false
|
|
||||||
server:
|
|
||||||
description:
|
|
||||||
- Domain controller for the Active Directory domain (optional)
|
|
||||||
required: false
|
|
||||||
trust_secret:
|
|
||||||
description:
|
|
||||||
- Shared secret for the trust
|
|
||||||
required: false
|
|
||||||
base_id:
|
|
||||||
description:
|
|
||||||
- First Posix ID of the range reserved for the trusted domain
|
|
||||||
required: false
|
|
||||||
range_size:
|
|
||||||
description:
|
|
||||||
- Size of the ID range reserved for the trusted domain
|
|
||||||
range_type:
|
|
||||||
description:
|
|
||||||
- Type of trusted domain ID range, one of ipa-ad-trust, ipa-ad-trust-posix
|
|
||||||
default: ipa-ad-trust
|
|
||||||
required: false
|
|
||||||
two_way:
|
|
||||||
description:
|
|
||||||
- Establish bi-directional trust. By default trust is inbound one-way only.
|
|
||||||
default: false
|
|
||||||
required: false
|
|
||||||
choices: ["true", "false"]
|
|
||||||
external:
|
|
||||||
description:
|
|
||||||
- Establish external trust to a domain in another forest.
|
|
||||||
- The trust is not transitive beyond the domain.
|
|
||||||
default: false
|
|
||||||
required: false
|
|
||||||
choices: ["true", "false"]
|
|
||||||
state:
|
|
||||||
description: State to ensure
|
|
||||||
default: present
|
|
||||||
required: true
|
|
||||||
choices: ["present", "absent"]
|
|
||||||
|
|
||||||
author:
|
|
||||||
- Rob Verduijn
|
|
||||||
"""
|
|
||||||
|
|
||||||
EXAMPLES = """
|
|
||||||
# add ad-trust
|
|
||||||
- ipatrust:
|
|
||||||
realm: ad.example.test
|
|
||||||
trust_type: ad
|
|
||||||
admin: Administrator
|
|
||||||
password: Welcome2020!
|
|
||||||
state: present
|
|
||||||
|
|
||||||
# delete ad-trust
|
|
||||||
- ipatrust:
|
|
||||||
realm: ad.example.test
|
|
||||||
state: absent
|
|
||||||
"""
|
|
||||||
|
|
||||||
RETURN = """
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
def find_trust(module, realm):
|
|
||||||
_args = {
|
|
||||||
"all": True,
|
|
||||||
"cn": realm,
|
|
||||||
}
|
|
||||||
|
|
||||||
_result = api_command(module, "trust_find", realm, _args)
|
|
||||||
|
|
||||||
if len(_result["result"]) > 1:
|
|
||||||
module.fail_json(msg="There is more than one realm '%s'" % (realm))
|
|
||||||
elif len(_result["result"]) == 1:
|
|
||||||
return _result["result"][0]
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def del_trust(module, realm):
|
|
||||||
_args = {}
|
|
||||||
|
|
||||||
_result = api_command(module, "trust_del", realm, _args)
|
|
||||||
if len(_result["result"]["failed"]) > 0:
|
|
||||||
module.fail_json(
|
|
||||||
msg="Trust deletion has failed for '%s'" % (realm))
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def add_trust(module, realm, args):
|
|
||||||
_args = args
|
|
||||||
|
|
||||||
_result = api_command(module, "trust_add", realm, _args)
|
|
||||||
|
|
||||||
if "cn" not in _result["result"]:
|
|
||||||
module.fail_json(
|
|
||||||
msg="Trust add has failed for '%s'" % (realm))
|
|
||||||
else:
|
|
||||||
return None
|
|
||||||
|
|
||||||
|
|
||||||
def gen_args(trust_type, admin, password, server, trust_secret, base_id,
|
|
||||||
range_size, range_type, two_way, external):
|
|
||||||
_args = {}
|
|
||||||
if trust_type is not None:
|
|
||||||
_args["trust_type"] = trust_type
|
|
||||||
if admin is not None:
|
|
||||||
_args["realm_admin"] = admin
|
|
||||||
if password is not None:
|
|
||||||
_args["realm_passwd"] = password
|
|
||||||
if server is not None:
|
|
||||||
_args["realm_server"] = server
|
|
||||||
if trust_secret is not None:
|
|
||||||
_args["trust_secret"] = trust_secret
|
|
||||||
if base_id is not None:
|
|
||||||
_args["base_id"] = base_id
|
|
||||||
if range_size is not None:
|
|
||||||
_args["range_size"] = range_size
|
|
||||||
if two_way is not None:
|
|
||||||
_args["bidirectional"] = two_way
|
|
||||||
if external is not None:
|
|
||||||
_args["external"] = external
|
|
||||||
|
|
||||||
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),
|
|
||||||
realm=dict(type="str", default=None, required=True),
|
|
||||||
# state
|
|
||||||
state=dict(type="str", default="present",
|
|
||||||
choices=["present", "absent"]),
|
|
||||||
# present
|
|
||||||
trust_type=dict(type="str", default="ad", required=False),
|
|
||||||
admin=dict(type="str", default=None, required=False),
|
|
||||||
password=dict(type="str", default=None,
|
|
||||||
required=False, no_log=True),
|
|
||||||
server=dict(type="str", default=None, required=False),
|
|
||||||
trust_secret=dict(type="str", default=None,
|
|
||||||
required=False, no_log=True),
|
|
||||||
base_id=dict(type="int", default=None, required=False),
|
|
||||||
range_size=dict(type="int", default=200000, required=False),
|
|
||||||
range_type=dict(type="str", default="ipa-ad-trust",
|
|
||||||
required=False, choices=["ipa-ad-trust-posix",
|
|
||||||
"ipa-ad-trust"]),
|
|
||||||
two_way=dict(type="bool", default=False, required=False),
|
|
||||||
external=dict(type="bool", default=False, required=False),
|
|
||||||
),
|
|
||||||
mutually_exclusive=[["trust_secret", "admin"]],
|
|
||||||
required_together=[["admin", "password"]],
|
|
||||||
supports_check_mode=True
|
|
||||||
)
|
|
||||||
|
|
||||||
ansible_module._ansible_debug = True
|
|
||||||
|
|
||||||
# general
|
|
||||||
ipaadmin_principal = module_params_get(
|
|
||||||
ansible_module, "ipaadmin_principal")
|
|
||||||
ipaadmin_password = module_params_get(ansible_module, "ipaadmin_password")
|
|
||||||
realm = module_params_get(ansible_module, "realm")
|
|
||||||
|
|
||||||
# state
|
|
||||||
state = module_params_get(ansible_module, "state")
|
|
||||||
|
|
||||||
# trust
|
|
||||||
trust_type = module_params_get(ansible_module, "trust_type")
|
|
||||||
admin = module_params_get(ansible_module, "admin")
|
|
||||||
password = module_params_get(ansible_module, "password")
|
|
||||||
server = module_params_get(ansible_module, "server")
|
|
||||||
trust_secret = module_params_get(ansible_module, "trust_secret")
|
|
||||||
base_id = module_params_get(ansible_module, "base_id")
|
|
||||||
range_size = module_params_get(ansible_module, "range_size")
|
|
||||||
range_type = module_params_get(ansible_module, "range_type")
|
|
||||||
two_way = module_params_get(ansible_module, "two_way")
|
|
||||||
external = module_params_get(ansible_module, "external")
|
|
||||||
|
|
||||||
changed = False
|
|
||||||
exit_args = {}
|
|
||||||
ccache_dir = None
|
|
||||||
ccache_name = None
|
|
||||||
try:
|
|
||||||
if not valid_creds(ansible_module, ipaadmin_principal):
|
|
||||||
ccache_dir, ccache_name = temp_kinit(
|
|
||||||
ipaadmin_principal, ipaadmin_password)
|
|
||||||
api_connect()
|
|
||||||
res_find = find_trust(ansible_module, realm)
|
|
||||||
|
|
||||||
if state == "absent":
|
|
||||||
if res_find is not None:
|
|
||||||
del_trust(ansible_module, realm)
|
|
||||||
changed = True
|
|
||||||
elif res_find is None:
|
|
||||||
if admin is None and trust_secret is None:
|
|
||||||
ansible_module.fail_json(
|
|
||||||
msg="one of admin or trust_secret is required when state "
|
|
||||||
"is present")
|
|
||||||
else:
|
|
||||||
args = gen_args(trust_type, admin, password, server,
|
|
||||||
trust_secret, base_id, range_size, range_type,
|
|
||||||
two_way, external)
|
|
||||||
|
|
||||||
add_trust(ansible_module, realm, args)
|
|
||||||
changed = True
|
|
||||||
|
|
||||||
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()
|
|
||||||
@@ -243,7 +243,7 @@ EXAMPLES = """
|
|||||||
state: retrieved
|
state: retrieved
|
||||||
register: result
|
register: result
|
||||||
- debug:
|
- debug:
|
||||||
msg: "{{ result.vault.data }}"
|
msg: "{{ result.data }}"
|
||||||
|
|
||||||
# Change password of a symmetric vault
|
# Change password of a symmetric vault
|
||||||
- ipavault:
|
- ipavault:
|
||||||
@@ -267,7 +267,7 @@ EXAMPLES = """
|
|||||||
username: user01
|
username: user01
|
||||||
description: An asymmetric vault
|
description: An asymmetric vault
|
||||||
vault_type: asymmetric
|
vault_type: asymmetric
|
||||||
public_key: |
|
public_key:
|
||||||
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR
|
LS0tLS1CRUdJTiBQVUJMSUMgS0VZLS0tLS0KTUlHZk1BMEdDU3FHU0liM0RRRUJBUVVBQTR
|
||||||
HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi
|
HTkFEQ0JpUUtCZ1FDdGFudjRkK3ptSTZ0T3ova1RXdGowY3AxRAowUENoYy8vR0pJMTUzTi
|
||||||
9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM
|
9CN3UrN0h3SXlRVlZoNUlXZG1UcCtkWXYzd09yeVpPbzYvbHN5eFJaZ2pZRDRwQ3VGCjlxM
|
||||||
@@ -303,15 +303,10 @@ EXAMPLES = """
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
RETURN = """
|
RETURN = """
|
||||||
vault:
|
user:
|
||||||
description: Vault dict with archived data.
|
description: The vault data.
|
||||||
returned: If state is `retrieved`.
|
returned: If state is retrieved.
|
||||||
type: dict
|
type: string
|
||||||
options:
|
|
||||||
data:
|
|
||||||
description: The vault data.
|
|
||||||
returned: always
|
|
||||||
type: string
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
@@ -494,10 +489,8 @@ def check_encryption_params(module, state, action, vault_type, salt,
|
|||||||
new_password, new_password_file, res_find):
|
new_password, new_password_file, res_find):
|
||||||
vault_type_invalid = []
|
vault_type_invalid = []
|
||||||
|
|
||||||
if vault_type is None and res_find is not None:
|
if res_find is not None:
|
||||||
vault_type = res_find['ipavaulttype']
|
vault_type = res_find['ipavaulttype']
|
||||||
if isinstance(vault_type, (tuple, list)):
|
|
||||||
vault_type = vault_type[0]
|
|
||||||
|
|
||||||
if vault_type == "standard":
|
if vault_type == "standard":
|
||||||
vault_type_invalid = ['public_key', 'public_key_file', 'password',
|
vault_type_invalid = ['public_key', 'public_key_file', 'password',
|
||||||
@@ -517,16 +510,6 @@ def check_encryption_params(module, state, action, vault_type, salt,
|
|||||||
module.fail_json(
|
module.fail_json(
|
||||||
msg="Cannot modify password of inexistent vault.")
|
msg="Cannot modify password of inexistent vault.")
|
||||||
|
|
||||||
if (
|
|
||||||
salt is not None
|
|
||||||
and not(
|
|
||||||
any([password, password_file])
|
|
||||||
and any([new_password, new_password_file])
|
|
||||||
)
|
|
||||||
):
|
|
||||||
module.fail_json(
|
|
||||||
msg="Vault `salt` can only change when changing the password.")
|
|
||||||
|
|
||||||
if vault_type == "asymmetric":
|
if vault_type == "asymmetric":
|
||||||
vault_type_invalid = [
|
vault_type_invalid = [
|
||||||
'password', 'password_file', 'new_password', 'new_password_file'
|
'password', 'password_file', 'new_password', 'new_password_file'
|
||||||
@@ -756,7 +739,7 @@ def main():
|
|||||||
res_vault_type = res_find.get('ipavaulttype')[0]
|
res_vault_type = res_find.get('ipavaulttype')[0]
|
||||||
args['ipavaulttype'] = vault_type = res_vault_type
|
args['ipavaulttype'] = vault_type = res_vault_type
|
||||||
else:
|
else:
|
||||||
args['ipavaulttype'] = vault_type = u"symmetric"
|
args['ipavaulttype'] = vault_type = "symmetric"
|
||||||
|
|
||||||
# Create command
|
# Create command
|
||||||
if state == "present":
|
if state == "present":
|
||||||
@@ -778,12 +761,7 @@ def main():
|
|||||||
commands.append([name, "vault_mod_internal", args])
|
commands.append([name, "vault_mod_internal", args])
|
||||||
|
|
||||||
else:
|
else:
|
||||||
if vault_type == 'symmetric' \
|
|
||||||
and 'ipavaultsalt' not in args:
|
|
||||||
args['ipavaultsalt'] = os.urandom(32)
|
|
||||||
|
|
||||||
commands.append([name, "vault_add_internal", args])
|
commands.append([name, "vault_add_internal", args])
|
||||||
|
|
||||||
if vault_type != 'standard' and vault_data is None:
|
if vault_type != 'standard' and vault_data is None:
|
||||||
vault_data = ''
|
vault_data = ''
|
||||||
|
|
||||||
@@ -841,6 +819,14 @@ def main():
|
|||||||
commands.append(
|
commands.append(
|
||||||
[name, 'vault_remove_owner', owner_del_args])
|
[name, 'vault_remove_owner', owner_del_args])
|
||||||
|
|
||||||
|
if vault_type == 'symmetric' \
|
||||||
|
and 'ipavaultsalt' not in args:
|
||||||
|
args['ipavaultsalt'] = os.urandom(32)
|
||||||
|
|
||||||
|
if vault_type == 'symmetric' \
|
||||||
|
and 'ipavaultsalt' not in args:
|
||||||
|
args['ipavaultsalt'] = os.urandom(32)
|
||||||
|
|
||||||
elif action in "member":
|
elif action in "member":
|
||||||
# Add users and groups
|
# Add users and groups
|
||||||
if any([users, groups, services]):
|
if any([users, groups, services]):
|
||||||
@@ -923,12 +909,12 @@ def main():
|
|||||||
elif command == 'vault_retrieve':
|
elif command == 'vault_retrieve':
|
||||||
if 'result' not in result:
|
if 'result' not in result:
|
||||||
raise Exception("No result obtained.")
|
raise Exception("No result obtained.")
|
||||||
if "data" in result["result"]:
|
if 'data' in result['result']:
|
||||||
data_return = exit_args.setdefault("vault", {})
|
exit_args['data'] = result['result']['data']
|
||||||
data_return["data"] = result["result"]["data"]
|
elif 'vault_data' in result['result']:
|
||||||
|
exit_args['data'] = result['result']['vault_data']
|
||||||
else:
|
else:
|
||||||
if not datafile_out:
|
raise Exception("No data retrieved.")
|
||||||
raise Exception("No data retrieved.")
|
|
||||||
changed = False
|
changed = False
|
||||||
else:
|
else:
|
||||||
if "completed" in result:
|
if "completed" in result:
|
||||||
|
|||||||
@@ -1,6 +1,2 @@
|
|||||||
[pytest]
|
[pytest]
|
||||||
python_files = test_*.py
|
python_files = test_*.py
|
||||||
junit_family = xunit1
|
|
||||||
markers=
|
|
||||||
source_order: mark test as order bound
|
|
||||||
playbook: playbook tests
|
|
||||||
|
|||||||
@@ -1,2 +0,0 @@
|
|||||||
-r requirements-tests.txt
|
|
||||||
ipdb
|
|
||||||
@@ -1,7 +0,0 @@
|
|||||||
-r requirements.txt
|
|
||||||
pytest>=2.7
|
|
||||||
pytest-sourceorder>=0.5
|
|
||||||
pytest-split-tests>=1.0.3
|
|
||||||
testinfra>=5.0
|
|
||||||
jmespath>=0.9 # needed for the `json_query` filter
|
|
||||||
pyyaml>=3
|
|
||||||
9
roles/ipaclient/files/py3test.py
Normal file
9
roles/ipaclient/files/py3test.py
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
#!/usr/bin/python3
|
||||||
|
|
||||||
|
# Test ipaclient python3 binding
|
||||||
|
from ipaclient.install.client import SECURE_PATH # noqa: F401
|
||||||
|
|
||||||
|
# Check ipapython version to be >= 4.6
|
||||||
|
from ipapython.version import NUM_VERSION, VERSION
|
||||||
|
if NUM_VERSION < 40600:
|
||||||
|
raise Exception("ipa %s not usable with python3" % VERSION)
|
||||||
@@ -37,12 +37,12 @@ description:
|
|||||||
options:
|
options:
|
||||||
domain:
|
domain:
|
||||||
description: Primary DNS domain of the IPA deployment
|
description: Primary DNS domain of the IPA deployment
|
||||||
required: yes
|
required: no
|
||||||
firefox_dir:
|
firefox_dir:
|
||||||
description:
|
description:
|
||||||
Specify directory where Firefox is installed (for example
|
Specify directory where Firefox is installed (for example
|
||||||
'/usr/lib/firefox')
|
'/usr/lib/firefox')
|
||||||
required: no
|
required: yes
|
||||||
author:
|
author:
|
||||||
- Thomas Woerner
|
- Thomas Woerner
|
||||||
'''
|
'''
|
||||||
|
|||||||
@@ -107,12 +107,9 @@ if NUM_VERSION >= 40400:
|
|||||||
from ipalib import api, errors, x509
|
from ipalib import api, errors, x509
|
||||||
from ipalib import constants
|
from ipalib import constants
|
||||||
try:
|
try:
|
||||||
from ipalib import sysrestore
|
from ipalib.install import sysrestore
|
||||||
except ImportError:
|
except ImportError:
|
||||||
try:
|
from ipapython import sysrestore
|
||||||
from ipalib.install import sysrestore
|
|
||||||
except ImportError:
|
|
||||||
from ipapython import sysrestore
|
|
||||||
try:
|
try:
|
||||||
from ipalib.install import certmonger
|
from ipalib.install import certmonger
|
||||||
except ImportError:
|
except ImportError:
|
||||||
|
|||||||
@@ -7,6 +7,9 @@
|
|||||||
state: present
|
state: present
|
||||||
when: ipaclient_install_packages | bool
|
when: ipaclient_install_packages | bool
|
||||||
|
|
||||||
|
#- name: Install - Include Python2/3 import test
|
||||||
|
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||||
|
|
||||||
- name: Install - Set ipaclient_servers
|
- name: Install - Set ipaclient_servers
|
||||||
set_fact:
|
set_fact:
|
||||||
ipaclient_servers: "{{ groups['ipaservers'] | list }}"
|
ipaclient_servers: "{{ groups['ipaservers'] | list }}"
|
||||||
@@ -110,6 +113,10 @@
|
|||||||
fail: msg="Keytab or password is required for getting otp"
|
fail: msg="Keytab or password is required for getting otp"
|
||||||
when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
|
when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
|
||||||
|
|
||||||
|
#- name: Install - Include Python2/3 import test
|
||||||
|
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||||
|
# delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||||
|
|
||||||
- name: Install - Get One-Time Password for client enrollment
|
- name: Install - Get One-Time Password for client enrollment
|
||||||
no_log: yes
|
no_log: yes
|
||||||
ipaclient_get_otp:
|
ipaclient_get_otp:
|
||||||
@@ -343,7 +350,6 @@
|
|||||||
- name: Install - Configure firefox
|
- name: Install - Configure firefox
|
||||||
ipaclient_setup_firefox:
|
ipaclient_setup_firefox:
|
||||||
firefox_dir: "{{ ipaclient_firefox_dir | default(omit) }}"
|
firefox_dir: "{{ ipaclient_firefox_dir | default(omit) }}"
|
||||||
domain: "{{ result_ipaclient_test.domain }}"
|
|
||||||
when: ipaclient_configure_firefox | bool
|
when: ipaclient_configure_firefox | bool
|
||||||
|
|
||||||
- name: Install - Configure NIS
|
- name: Install - Configure NIS
|
||||||
|
|||||||
18
roles/ipaclient/tasks/python_2_3_test.yml
Normal file
18
roles/ipaclient/tasks/python_2_3_test.yml
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
---
|
||||||
|
- block:
|
||||||
|
- name: Verify Python3 import
|
||||||
|
script: py3test.py
|
||||||
|
register: result_py3test
|
||||||
|
failed_when: False
|
||||||
|
changed_when: False
|
||||||
|
check_mode: no
|
||||||
|
|
||||||
|
- name: Set python interpreter to 3
|
||||||
|
set_fact:
|
||||||
|
ansible_python_interpreter: "/usr/bin/python3"
|
||||||
|
when: result_py3test.rc == 0
|
||||||
|
|
||||||
|
- name: Set python interpreter to 2
|
||||||
|
set_fact:
|
||||||
|
ansible_python_interpreter: "/usr/bin/python2"
|
||||||
|
when: result_py3test.failed or result_py3test.rc != 0
|
||||||
@@ -1,6 +1,9 @@
|
|||||||
---
|
---
|
||||||
# tasks to uninstall IPA client
|
# tasks to uninstall IPA client
|
||||||
|
|
||||||
|
# - name: Uninstall - Include Python2/3 import test
|
||||||
|
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||||
|
|
||||||
- name: Uninstall - Uninstall IPA client
|
- name: Uninstall - Uninstall IPA client
|
||||||
command: >
|
command: >
|
||||||
/usr/sbin/ipa-client-install
|
/usr/sbin/ipa-client-install
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user