mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-27 05:43:05 +00:00
Compare commits
1 Commits
master
...
validate_e
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
22700620c6 |
18
.github/workflows/docs.yml
vendored
18
.github/workflows/docs.yml
vendored
@@ -5,7 +5,7 @@ on:
|
||||
- pull_request
|
||||
jobs:
|
||||
check_docs_oldest_supported:
|
||||
name: Check Ansible Documentation with ansible-core 2.16.
|
||||
name: Check Ansible Documentation with ansible-core 2.13.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.1
|
||||
@@ -14,15 +14,15 @@ jobs:
|
||||
- uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.16
|
||||
- name: Install Ansible 2.13
|
||||
run: |
|
||||
python -m pip install "ansible-core >=2.16,<2.17"
|
||||
python -m pip install "ansible-core >=2.13,<2.14"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
check_docs_previous:
|
||||
name: Check Ansible Documentation with ansible-core 2.18.
|
||||
name: Check Ansible Documentation with ansible-core 2.14.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.1
|
||||
@@ -31,15 +31,15 @@ jobs:
|
||||
- uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.18
|
||||
- name: Install Ansible 2.14
|
||||
run: |
|
||||
python -m pip install "ansible-core >=2.18,<2.19"
|
||||
python -m pip install "ansible-core >=2.14,<2.15"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
check_docs_current:
|
||||
name: Check Ansible Documentation with ansible-core 2.19.
|
||||
name: Check Ansible Documentation with ansible-core 2.15.
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4.1.1
|
||||
@@ -48,9 +48,9 @@ jobs:
|
||||
- uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: '3.x'
|
||||
- name: Install Ansible 2.20
|
||||
- name: Install Ansible 2.15
|
||||
run: |
|
||||
python -m pip install "ansible-core <2.20"
|
||||
python -m pip install "ansible-core >=2.15,<2.16"
|
||||
- name: Run ansible-doc-test
|
||||
run: |
|
||||
ANSIBLE_LIBRARY="." ANSIBLE_DOC_FRAGMENT_PLUGINS="." python utils/ansible-doc-test -v roles plugins
|
||||
|
||||
6
.github/workflows/lint.yml
vendored
6
.github/workflows/lint.yml
vendored
@@ -13,12 +13,12 @@ jobs:
|
||||
fetch-depth: 0
|
||||
- uses: actions/setup-python@v5.1.0
|
||||
with:
|
||||
python-version: "3.13"
|
||||
python-version: "3.x"
|
||||
- name: Run ansible-lint
|
||||
run: |
|
||||
pip install "ansible-core>=2.16,<2.17" 'ansible-lint==6.22'
|
||||
utils/build-collection.sh -ki rpm
|
||||
cd .collection-build
|
||||
utils/build-galaxy-release.sh -ki
|
||||
cd .galaxy-build
|
||||
ansible-lint --profile production --exclude tests/integration/ --exclude tests/unit/ --parseable --nocolor
|
||||
|
||||
yamllint:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
repos:
|
||||
- repo: https://github.com/ansible/ansible-lint.git
|
||||
rev: v25.9.2
|
||||
rev: v24.5.0
|
||||
hooks:
|
||||
- id: ansible-lint
|
||||
always_run: false
|
||||
@@ -21,16 +21,16 @@ repos:
|
||||
--parseable
|
||||
--nocolor
|
||||
- repo: https://github.com/adrienverge/yamllint.git
|
||||
rev: v1.37.1
|
||||
rev: v1.35.1
|
||||
hooks:
|
||||
- id: yamllint
|
||||
files: \.(yaml|yml)$
|
||||
- repo: https://github.com/pycqa/flake8
|
||||
rev: 7.3.0
|
||||
rev: 7.0.0
|
||||
hooks:
|
||||
- id: flake8
|
||||
- repo: https://github.com/pycqa/pylint
|
||||
rev: v4.0.2
|
||||
rev: v3.2.2
|
||||
hooks:
|
||||
- id: pylint
|
||||
args:
|
||||
|
||||
@@ -145,7 +145,7 @@ Variable | Description | Required
|
||||
`selinuxusermaporder` \| `ipaselinuxusermaporder`| Set ordered list in increasing priority of SELinux users | no
|
||||
`selinuxusermapdefault`\| `ipaselinuxusermapdefault` | Set default SELinux user when no match is found in SELinux map rule | no
|
||||
`pac_type` \| `ipakrbauthzdata` | set default types of PAC supported for services (choices: `MS-PAC`, `PAD`, `nfs:NONE`). Use `""` to clear this variable. | no
|
||||
`user_auth_type` \| `ipauserauthtype` | set default types of supported user authentication (choices: `password`, `radius`, `otp`, `pkinit`, `hardened`, `idp`, `passkey`, `disabled`, `""`). An additional check ensures that only types can be used that are supported by the IPA version. Use `""` to clear this variable. | no
|
||||
`user_auth_type` \| `ipauserauthtype` | set default types of supported user authentication (choices: `password`, `radius`, `otp`, `pkinit`, `hardened`, `idp`, `disabled`, `""`). An additional check ensures that only types can be used that are supported by the IPA version. Use `""` to clear this variable. | no
|
||||
`domain_resolution_order` \| `ipadomainresolutionorder` | Set list of domains used for short name qualification | no
|
||||
`ca_renewal_master_server` \| `ipacarenewalmasterserver`| Renewal master for IPA certificate authority. | no
|
||||
`enable_sid` | New users and groups automatically get a SID assigned. Cannot be deactivated once activated. Requires IPA 4.9.8+. (bool) | no
|
||||
|
||||
@@ -354,7 +354,7 @@ Variable | Description | Required
|
||||
`mac_address` \| `macaddress` | List of hardware MAC addresses. | no
|
||||
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys | no
|
||||
`userclass` \| `class` | Host category (semantics placed on this attribute are for local interpretation) | no
|
||||
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Use empty string to reset auth_ind to the initial value. Other values may be used for custom configurations. An additional check ensures that only types can be used that are supported by the IPA version. Choices: ["radius", "otp", "pkinit", "hardened", "idp", "passkey", ""] | no
|
||||
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. Use 'otp' to allow OTP-based 2FA authentications. Use 'radius' to allow RADIUS-based 2FA authentications. Use empty string to reset auth_ind to the initial value. Other values may be used for custom configurations. An additional check ensures that only types can be used that are supported by the IPA version. Choices: ["radius", "otp", "pkinit", "hardened", "idp", ""] | no
|
||||
`requires_pre_auth` \| `ipakrbrequirespreauth` | Pre-authentication is required for the service (bool) | no
|
||||
`ok_as_delegate` \| `ipakrbokasdelegate` | Client credentials may be delegated to the service (bool) | no
|
||||
`ok_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client (bool) | no
|
||||
|
||||
@@ -68,6 +68,23 @@ Example playbook to ensure a local domain idrange is present:
|
||||
name: local_domain_id_range
|
||||
base_id: 150000
|
||||
range_size: 200000
|
||||
```
|
||||
|
||||
Example playbook to ensure a local domain idrange is present, with RID and secondary RID base values:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA idrange.
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Ensure local idrange is present
|
||||
ipaidrange:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: local_domain_id_range
|
||||
base_id: 150000000
|
||||
range_size: 200000
|
||||
rid_base: 1000000
|
||||
secondary_rid_base: 200000000
|
||||
```
|
||||
@@ -155,8 +172,8 @@ Variable | Description | Required
|
||||
`name` \| `cn` | The list of idrange name strings. | yes
|
||||
`base_id` \| `ipabaseid` | First Posix ID of the range. (int) | yes, if `state: present`
|
||||
`range_size` \| `ipaidrangesize` | Number of IDs in the range. (int) | yes, if `state: present`
|
||||
`rid_base` \| `ipabaserid` | First RID of the corresponding RID range. (int) | yes, if `idrange_type: ipa-local` and `state: present` |
|
||||
`secondary_rid_base` \| `ipasecondarybaserid` | First RID of the secondary RID range. (int) | yes, if `idrange_type: ipa-local` and `state: present` |
|
||||
`rid_base` \| `ipabaserid` | First RID of the corresponding RID range. (int) | no
|
||||
`secondary_rid_base` \| `ipasecondarybaserid` | First RID of the secondary RID range. (int) | no
|
||||
`dom_sid` \| `ipanttrusteddomainsid` | Domain SID of the trusted domain. | no
|
||||
`idrange_type` \| `iparangetype` | ID range type, one of `ipa-ad-trust`, `ipa-ad-trust-posix`, `ipa-local`. Only valid if idrange does not exist. | no
|
||||
`dom_name` \| `ipanttrusteddomainname` | Name of the trusted domain. Can only be used when `ipaapi_context: server`. | no
|
||||
|
||||
@@ -1,88 +0,0 @@
|
||||
Passkeyconfig module
|
||||
============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The passkeyconfig module allows to manage FreeIPA passkey configuration settings.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Passkeyconfig management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipapasskeyconfig module.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.15+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
By default, user verification for passkey authentication is turned on (`true`). Example playbook to ensure that the requirement for user verification for passkey authentication is turned off:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA passkeyconfig.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure require_user_verification is false
|
||||
ipapasskeyconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
require_user_verification: false
|
||||
```
|
||||
|
||||
|
||||
Example playbook to get current passkeyconfig:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to get IPA passkeyconfig.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Retrieve current passkey configuration
|
||||
ipapasskeyconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
|
||||
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
|
||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to true. (bool) | no
|
||||
`require_user_verification` \| `iparequireuserverification` | Require user verification for passkey authentication. (bool) | no
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Rafael Guterres Jeffman
|
||||
@@ -230,8 +230,6 @@ Example playbook to ensure that different members are not associated with a role
|
||||
- User Administrators
|
||||
service:
|
||||
- service01
|
||||
sysaccount:
|
||||
- my-app
|
||||
action: member
|
||||
state: absent
|
||||
```
|
||||
@@ -255,8 +253,7 @@ Variable | Description | Required
|
||||
`host` | List of hosts to be assigned or not assigned to the role. | no
|
||||
`hostgroup` | List of hostgroups to be assigned or not assigned to the role. | no
|
||||
`service` | List of services to be assigned or not assigned to the role. | no
|
||||
`sysaccount` | List of sysaccounts to be assigned or not assigned to the role. | no
|
||||
`action` | Work on role or member level. It can be one of `member` or `role` and defaults to `role`. | no
|
||||
`action` | Work on role or member level. It can be on of `member` or `role` and defaults to `role`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, default: `present`. | no
|
||||
|
||||
|
||||
@@ -264,4 +261,3 @@ Authors
|
||||
=======
|
||||
|
||||
Rafael Jeffman
|
||||
Thomas Woerner
|
||||
|
||||
@@ -361,7 +361,7 @@ Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`certificate` \| `usercertificate` | Base-64 encoded service certificate. | no
|
||||
`pac_type` \| `ipakrbauthzdata` | Supported PAC type. It can be one of `MS-PAC`, `PAD`, or `NONE`. Use empty string to reset pac_type to the initial value. | no
|
||||
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. It can be any of `otp`, `radius`, `pkinit`, `hardened`, `idp`, `passkey` or `""`. An additional check ensures that only types can be used that are supported by the IPA version. Use empty string to reset auth_ind to the initial value. | no
|
||||
`auth_ind` \| `krbprincipalauthind` | Defines an allow list for Authentication Indicators. It can be any of `otp`, `radius`, `pkinit`, `hardened`, `idp` or `""`. An additional check ensures that only types can be used that are supported by the IPA version. Use empty string to reset auth_ind to the initial value. | 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_to_auth_as_delegate` \| `ipakrboktoauthasdelegate` | The service is allowed to authenticate on behalf of a client. Default to false. (bool) | no
|
||||
|
||||
@@ -1,196 +0,0 @@
|
||||
Sysaccount module
|
||||
============
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
The sysaccount module allows to ensure presence and absence of system accounts.
|
||||
|
||||
Features
|
||||
--------
|
||||
|
||||
* Sysaccount management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipasysaccount module.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.15+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure sysaccount "my-app" is present with random password:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA sysaccount.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount "my-app" is present with random password
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
random: true
|
||||
register: result
|
||||
|
||||
- name: Print generated random password
|
||||
debug:
|
||||
var: result.sysaccount.randompassword
|
||||
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure sysaccount "my-app" is present with given password:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA sysaccount.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount "my-app" is present with given password
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
password: SomeAPPpassword
|
||||
```
|
||||
|
||||
|
||||
Example playbook to make sure sysaccount "my-app" is absent:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA sysaccount.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount "my-app" is absent
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: absent
|
||||
```
|
||||
|
||||
Example playbook to ensure existing sysaccount my-app is privileged
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA sysaccount.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure existing sysaccount my-app is privileged
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
privileged: true
|
||||
```
|
||||
|
||||
Example playbook to ensure existing sysaccount my-app is not privileged
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA sysaccount.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure existing sysaccount my-app is not privileged
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
privileged: false
|
||||
```
|
||||
|
||||
Example playbook to ensure existing sysaccount my-app is disabled
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA sysaccount.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure existing sysaccount my-app is disabled
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: disabled
|
||||
```
|
||||
|
||||
Example playbook to ensure existing sysaccount my-app is enabled
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to manage IPA sysaccount.
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure existing sysaccount my-app is enabled
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: enabled
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
---------
|
||||
|
||||
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
|
||||
`ipaapi_context` | The context in which the module will execute. Executing in a server context is preferred. If not provided context will be determined by the execution environment. Valid values are `server` and `client`. | no
|
||||
`ipaapi_ldap_cache` | Use LDAP cache for IPA connection. The bool setting defaults to true. (bool) | no
|
||||
`name` \| `login` | The list of sysaccount name strings - internally uid. (list of strings) | yes
|
||||
`description` | A description for the sysaccount. (string) | no
|
||||
`privileged` | Allow password updates without reset. This flag is not replicated. It is needed to set privileged on all servers, where it is needed. (bool) | no
|
||||
`random` | Generate a random user password. (bool) | no
|
||||
`password` \| `userpassword` | Set the password. (string) | no
|
||||
`update_password` | Set password for a sysaccount in present state only on creation or always. It can be one of `always` or `on_create` and defaults to `always`. | no
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, 'enabled', 'disabled', default: `present`. | no
|
||||
|
||||
|
||||
Return Values
|
||||
=============
|
||||
|
||||
There are only return values if a random passwords has been generated.
|
||||
|
||||
Variable | Description | Returned When
|
||||
-------- | ----------- | -------------
|
||||
`sysaccount` | Sysaccount dict (dict) <br>Options: | Always
|
||||
| `randompassword` - The generated random password | If random is yes and sysaccount did not exist or update_password is yes
|
||||
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
@@ -452,7 +452,7 @@ Variable | Description | Required
|
||||
`manager` | List of manager user names. | no
|
||||
`carlicense` | List of car licenses. | no
|
||||
`sshpubkey` \| `ipasshpubkey` | List of SSH public keys. | no
|
||||
`userauthtype` \| `ipauserauthtype` | List of supported user authentication types. Choices: `password`, `radius`, `otp`, `pkinit`, `hardened`, `idp`, `passkey` and `""`. An additional check ensures that only types can be used that are supported by the IPA version. Use empty string to reset userauthtype to the initial value. | no
|
||||
`userauthtype` \| `ipauserauthtype` | List of supported user authentication types. Choices: `password`, `radius`, `otp`, `pkinit`, `hardened`, `idp` and `""`. An additional check ensures that only types can be used that are supported by the IPA version. Use empty string to reset userauthtype to the initial value. | no
|
||||
`userclass` | User category. (semantics placed on this attribute are for local interpretation). | no
|
||||
`radius` | RADIUS proxy configuration | no
|
||||
`radiususer` | RADIUS proxy username | no
|
||||
|
||||
@@ -38,7 +38,6 @@ Features
|
||||
* Modules for idview management
|
||||
* Modules for location management
|
||||
* Modules for netgroup management
|
||||
* Modules for passkeyconfig management
|
||||
* Modules for permission management
|
||||
* Modules for privilege management
|
||||
* Modules for pwpolicy management
|
||||
@@ -51,7 +50,6 @@ Features
|
||||
* Modules for sudocmd management
|
||||
* Modules for sudocmdgroup management
|
||||
* Modules for sudorule management
|
||||
* Modules for sysaccount management
|
||||
* Modules for topology management
|
||||
* Modules for trust management
|
||||
* Modules for user management
|
||||
@@ -455,7 +453,6 @@ Modules in plugin/modules
|
||||
* [idview](README-idview.md)
|
||||
* [ipalocation](README-location.md)
|
||||
* [ipanetgroup](README-netgroup.md)
|
||||
* [ipapasskeyconfig](README-passkeyconfig.md)
|
||||
* [ipapermission](README-permission.md)
|
||||
* [ipaprivilege](README-privilege.md)
|
||||
* [ipapwpolicy](README-pwpolicy.md)
|
||||
@@ -468,7 +465,6 @@ Modules in plugin/modules
|
||||
* [ipasudocmd](README-sudocmd.md)
|
||||
* [ipasudocmdgroup](README-sudocmdgroup.md)
|
||||
* [ipasudorule](README-sudorule.md)
|
||||
* [ipasysaccount](README-sysaccount.md)
|
||||
* [ipatopologysegment](README-topology.md)
|
||||
* [ipatopologysuffix](README-topology.md)
|
||||
* [ipatrust](README-trust.md)
|
||||
|
||||
@@ -3,10 +3,10 @@ trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-24.04'
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
variables:
|
||||
ansible_version: "-core >=2.18,<2.19"
|
||||
ansible_version: "-core >=2.16,<2.17"
|
||||
ansible_latest: "-core"
|
||||
ansible_minimum: "-core <2.16"
|
||||
distros: "fedora-latest,c9s,c10s,fedora-rawhide"
|
||||
@@ -36,7 +36,7 @@ stages:
|
||||
# Supported distros
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_18
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
@@ -49,7 +49,7 @@ stages:
|
||||
|
||||
# Galaxy on Fedora
|
||||
|
||||
- stage: galaxy_fedora_latest_ansible_2_18
|
||||
- stage: galaxy_fedora_latest_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
|
||||
@@ -10,26 +10,15 @@ schedules:
|
||||
trigger: none
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-24.04'
|
||||
|
||||
parameters:
|
||||
# Not really a parameter, but variables cannot be arrays or dicts
|
||||
# This maps the distro LATEST version to the avaiable ansible-core
|
||||
# version of the latest released compose.
|
||||
- name: "distro_ansible_map"
|
||||
type: object
|
||||
default:
|
||||
- { distro: "c8s", ansible_version: "<2.17", version_name: "2.16" }
|
||||
# c9s should use 2.14, but this version has an invalid certificate
|
||||
# and so is unsuable against ansible-galaxy.
|
||||
- { distro: "c9s", ansible_version: "<2.17", version_name: "2.16" }
|
||||
- { distro: "c10s", ansible_version: "<2.17", version_name: "2.16" }
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
variables:
|
||||
distros: "fedora-latest,c10s,c9s,fedora-rawhide"
|
||||
ansible_version: "-core >=2.18,<2.19"
|
||||
# We need to have two sets, as c8s is not supported by all ansible versions
|
||||
recent_distros: "fedora-latest,fedora-rawhide,c10s,c9s"
|
||||
distros: "fedora-latest,fedora-rawhide,c10s,c9s,c8s"
|
||||
ansible_latest: "-core"
|
||||
ansible_minimum: "-core <2.16"
|
||||
ansible_version: "-core >=2.16,<2.17"
|
||||
|
||||
stages:
|
||||
|
||||
@@ -49,7 +38,7 @@ stages:
|
||||
|
||||
# Latest ansible
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- ${{ each distro in split(variables.recent_distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_latest
|
||||
dependsOn: []
|
||||
jobs:
|
||||
@@ -61,44 +50,30 @@ stages:
|
||||
skip_git_test: true
|
||||
test_galaxy: false
|
||||
|
||||
# Galaxy with Latest ansible
|
||||
# Selected ansible-core version
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: galaxy_${{ replace(distro, '-', '_') }}_ansible_latest
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ distro }}
|
||||
ansible_version: ${{ variables.ansible_latest }}
|
||||
skip_git_test: true
|
||||
test_galaxy: true
|
||||
|
||||
# Test with pinned ansible version for the distro
|
||||
|
||||
- ${{ each config in parameters.distro_ansible_map }}:
|
||||
- stage: ${{ config.distro }}_distro_ansible_${{ replace(config.version_name, '.', '_') }}
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ config.distro }}
|
||||
ansible_version: -core${{ config.ansible_version }}
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: true
|
||||
test_galaxy: false
|
||||
|
||||
# Test Galaxy collection with pinned ansible version for the distro
|
||||
# Galaxy collection with selected ansible-core version
|
||||
|
||||
- ${{ each config in parameters.distro_ansible_map }}:
|
||||
- stage: galaxy_${{ config.distro }}_distro_ansible_${{ replace(config.version_name, '.', '_') }}
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: galaxy_${{ replace(distro, '-', '_') }}_asible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/group_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ config.distro }}
|
||||
ansible_version: -core${{ config.ansible_version }}
|
||||
distro: ${{ distro }}
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: true
|
||||
test_galaxy: true
|
||||
|
||||
@@ -3,31 +3,18 @@ trigger:
|
||||
- master
|
||||
|
||||
pool:
|
||||
vmImage: 'ubuntu-24.04'
|
||||
|
||||
parameters:
|
||||
# Not really a parameter, but variables cannot be arrays or dicts
|
||||
# This maps the distro LATEST version to the avaiable ansible-core
|
||||
# version of the latest released compose.
|
||||
- name: "distro_ansible_map"
|
||||
type: object
|
||||
default:
|
||||
- { distro: "c8s", ansible_version: "<2.17", version_name: "2.16" }
|
||||
# c9s should use 2.14, but this version has an invalid certificate
|
||||
# and so is unsuable against ansible-galaxy.
|
||||
- { distro: "c9s", ansible_version: "<2.17", version_name: "2.16" }
|
||||
- { distro: "c10s", ansible_version: "<2.17", version_name: "2.16" }
|
||||
vmImage: 'ubuntu-20.04'
|
||||
|
||||
variables:
|
||||
distros: "fedora-latest,c10s,c9s,fedora-rawhide"
|
||||
ansible_version: "-core >=2.18,<2.19"
|
||||
distros: "fedora-latest,c10s,c9s,c8s,fedora-rawhide"
|
||||
ansible_version: "-core >=2.15,<2.16"
|
||||
|
||||
stages:
|
||||
|
||||
# Test with repository in all "current" distros
|
||||
# Test with repository in all distros
|
||||
|
||||
- ${{ each distro in split(variables.distros, ',') }}:
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_18
|
||||
- stage: ${{ replace(distro, '-', '_') }}_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/run_tests.yml
|
||||
@@ -40,7 +27,7 @@ stages:
|
||||
|
||||
# Galaxy on Fedora
|
||||
|
||||
- stage: galaxy_fedora_latest_ansible_2_18
|
||||
- stage: galaxy_fedora_latest_ansible_2_16
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/run_tests.yml
|
||||
@@ -50,18 +37,3 @@ stages:
|
||||
ansible_version: ${{ variables.ansible_version }}
|
||||
skip_git_test: false
|
||||
test_galaxy: true
|
||||
|
||||
|
||||
# Test with pinned ansible version for the distro
|
||||
|
||||
- ${{ each config in parameters.distro_ansible_map }}:
|
||||
- stage: ${{ config.distro }}_distro_ansible_${{ replace(config.version_name, '.', '_') }}
|
||||
dependsOn: []
|
||||
jobs:
|
||||
- template: templates/run_tests.yml
|
||||
parameters:
|
||||
build_number: $(Build.BuildNumber)
|
||||
distro: ${{ config.distro }}
|
||||
ansible_version: -core${{ config.ansible_version }}
|
||||
skip_git_test: false
|
||||
test_galaxy: false
|
||||
|
||||
@@ -54,7 +54,7 @@ jobs:
|
||||
|
||||
- script: |
|
||||
git fetch --unshallow
|
||||
utils/build-collection.sh -i rpm
|
||||
utils/build-galaxy-release.sh -i
|
||||
retryCountOnTaskFailure: 5
|
||||
displayName: Build Galaxy release
|
||||
condition: ${{ parameters.test_galaxy }}
|
||||
|
||||
@@ -119,6 +119,13 @@ then
|
||||
deployed=true
|
||||
fi
|
||||
echo
|
||||
|
||||
if $deployed; then
|
||||
log info "= Enabling services ="
|
||||
container_exec "${name}" systemctl enable fixnet
|
||||
container_exec "${name}" systemctl enable fixipaip
|
||||
echo
|
||||
fi
|
||||
|
||||
container_stop "${name}"
|
||||
|
||||
|
||||
@@ -31,8 +31,6 @@ COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
RUN systemctl enable fixnet.service
|
||||
RUN systemctl enable fixipaip.service
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ dnf --assumeyes install \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
hostname \
|
||||
iproute; \
|
||||
dnf clean all; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
@@ -35,8 +34,6 @@ COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
RUN systemctl enable fixnet.service
|
||||
RUN systemctl enable fixipaip.service
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
|
||||
@@ -9,7 +9,6 @@ dnf --assumeyes install \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
hostname \
|
||||
iproute; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
|
||||
@@ -31,8 +30,6 @@ COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
RUN systemctl enable fixnet.service
|
||||
RUN systemctl enable fixipaip.service
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ dnf --assumeyes install \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
hostname \
|
||||
iproute; \
|
||||
dnf clean all; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
@@ -34,8 +33,6 @@ COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
RUN systemctl enable fixnet.service
|
||||
RUN systemctl enable fixipaip.service
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
|
||||
@@ -11,7 +11,6 @@ dnf --assumeyes install \
|
||||
bash \
|
||||
systemd \
|
||||
procps-ng \
|
||||
hostname \
|
||||
iproute; \
|
||||
dnf clean all; \
|
||||
rm -rf /var/cache/dnf/;
|
||||
@@ -34,8 +33,6 @@ COPY system-service/fixipaip.sh /root/
|
||||
COPY system-service/fixnet.service /etc/systemd/system/
|
||||
COPY system-service/fixipaip.service /etc/systemd/system/
|
||||
RUN chmod +x /root/fixnet.sh /root/fixipaip.sh
|
||||
RUN systemctl enable fixnet.service
|
||||
RUN systemctl enable fixipaip.service
|
||||
|
||||
STOPSIGNAL RTMIN+3
|
||||
|
||||
|
||||
@@ -4,20 +4,13 @@
|
||||
SCRIPTDIR="$(dirname -- "$(readlink -f "${BASH_SOURCE[0]}")")"
|
||||
TOPDIR="$(readlink -f "${SCRIPTDIR}/../..")"
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. "${SCRIPTDIR}/shdefaults"
|
||||
|
||||
# shellcheck disable=SC1091
|
||||
. "${TOPDIR}/utils/shfun"
|
||||
|
||||
container_create() {
|
||||
local name=${1}
|
||||
local image=${2}
|
||||
shift 2
|
||||
declare -a extra_opts
|
||||
readarray -t extra_opts < \
|
||||
<(sed -e "s/-/--cap-drop=/g" -e "s/+/--cap-add=/g" \
|
||||
<<< "$(printf '%s\n' "${CAP_DEFAULTS[@]}")")
|
||||
declare -a extra_opts=()
|
||||
for opt in "$@"
|
||||
do
|
||||
[ -z "${opt}" ] && continue
|
||||
@@ -26,7 +19,6 @@ container_create() {
|
||||
cpus=*) extra_opts+=("--${opt}") ;;
|
||||
memory=*) extra_opts+=("--${opt}") ;;
|
||||
capabilities=*) extra_opts+=("--cap-add=${opt##*=}") ;;
|
||||
volume=*) extra_opts+=("--volume=${opt##*=}") ;;
|
||||
*) log error "container_create: Invalid option: ${opt}" ;;
|
||||
esac
|
||||
done
|
||||
@@ -55,19 +47,6 @@ container_start() {
|
||||
|
||||
log info "= Starting ${name} ="
|
||||
podman start "${name}"
|
||||
# Add host entry to /etc/hosts
|
||||
ip=$(podman inspect "${name}" --format "{{.NetworkSettings.IPAddress}}")
|
||||
hostname=$(podman inspect "${name}" --format "{{.Config.Hostname}}")
|
||||
if [ -n "${ip}" ] && [ -n "${hostname}" ]; then
|
||||
cmd=$(cat <<EOF
|
||||
sed -i -E "/\s+${hostname}(\s|$)/d" /etc/hosts
|
||||
echo -e "$ip\t${hostname} ${hostname%%.*}" >> /etc/hosts
|
||||
EOF
|
||||
)
|
||||
podman exec "${name}" bash -c "$cmd"
|
||||
fi
|
||||
# Ensure /etc/shadow is readable
|
||||
podman exec "${name}" bash -c "chmod u+r /etc/shadow"
|
||||
echo
|
||||
}
|
||||
|
||||
@@ -216,34 +195,3 @@ container_fetch() {
|
||||
podman cp "${name}:${source}" "${destination}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_tee() {
|
||||
local name=${1}
|
||||
local destination=${2}
|
||||
tmpfile=$(mktemp /tmp/container-temp.XXXXXX)
|
||||
|
||||
log info "= Creating ${name}:${destination} from stdin ="
|
||||
cat - > "${tmpfile}"
|
||||
podman cp "${tmpfile}" "${name}:${destination}"
|
||||
rm "${tmpfile}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_save() {
|
||||
local name=${1}
|
||||
|
||||
archive="${name}.tar"
|
||||
log info "= Saving ${name} to ${archive} ="
|
||||
# podman is not able to overwrite the archive
|
||||
[ -f "${archive}" ] && rm "${archive}"
|
||||
podman save -o "${archive}" "${name}"
|
||||
echo
|
||||
}
|
||||
|
||||
container_load() {
|
||||
local name=${1}
|
||||
|
||||
image_name=$(podman load -q -i "${name}" | sed -e "s/^Loaded image: //")
|
||||
image=$(podman image list -q "${image_name}")
|
||||
echo "$image"
|
||||
}
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#!/bin/bash -eu
|
||||
# This file is meant to be source'd by other scripts
|
||||
|
||||
# Set default capabilities options for freeipa containers.
|
||||
# Use +CAP to add the capability and -CAP to drop the capability.
|
||||
CAP_DEFAULTS=(
|
||||
"+DAC_READ_SEARCH" # Required for SSSD
|
||||
"+SYS_PTRACE" # Required for debugging
|
||||
"+SYS_ADMIN" # Required to make dbus-brokder for systemd 258 work
|
||||
# Should be "+AUDIT_WRITE", "+SETUID", "+SETGID"
|
||||
)
|
||||
@@ -1,7 +1,6 @@
|
||||
[Unit]
|
||||
Description=Fix IPA server IP in IPA Server
|
||||
After=ipa.service
|
||||
PartOf=ipa.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
@@ -10,4 +9,4 @@ StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=ipa.service
|
||||
WantedBy=default.target
|
||||
|
||||
@@ -50,9 +50,9 @@ if [ -z "${FORWARDER}" ] || [ "${FORWARDER}" == "127.0.0.1" ]; then
|
||||
fi
|
||||
|
||||
echo "Fix IPA:"
|
||||
echo " HOSTNAME: '${HOSTNAME}'"
|
||||
echo " IP: '${IP}'"
|
||||
echo " PTR: '${PTR}'"
|
||||
echo " HOSTNAME: '${HOSTNAME}'"
|
||||
echo " IP: '${IP}'"
|
||||
echo " PTR: '${PTR}'"
|
||||
echo " FORWARDER: '${FORWARDER}'"
|
||||
|
||||
ZONES=$(ipa -e in_server=true dnszone-find --name-from-ip="${HOSTNAME}." \
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
[Unit]
|
||||
Description=Fix /etc/hosts and with local DNS also /etc/resolv.conf
|
||||
Description=Fix server IP in IPA Server
|
||||
Wants=network.target
|
||||
After=network.target
|
||||
Before=ipa.service
|
||||
|
||||
[Service]
|
||||
Type=oneshot
|
||||
@@ -8,4 +11,4 @@ StandardOutput=journal
|
||||
StandardError=journal
|
||||
|
||||
[Install]
|
||||
WantedBy=container-ipa.target
|
||||
WantedBy=ipa.service
|
||||
|
||||
@@ -39,35 +39,26 @@ if [ -z "${IP}" ] || ! valid_ipv4 "${IP}" ; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
DOMAIN=${HOSTNAME#*.}
|
||||
|
||||
echo "Fix NET:"
|
||||
echo " HOSTNAME: '${HOSTNAME}'"
|
||||
echo " DOMAIN: '${DOMAIN}'"
|
||||
echo " IP: '${IP}'"
|
||||
echo " IP: '${IP}'"
|
||||
echo
|
||||
|
||||
# /etc/hosts
|
||||
|
||||
sed -i -E "/\s+${HOSTNAME}(\s|$)/d" /etc/hosts
|
||||
echo -e "$IP\t${HOSTNAME} ${HOSTNAME%%.*}" >> /etc/hosts
|
||||
|
||||
echo "/etc/hosts:"
|
||||
cat "/etc/hosts"
|
||||
|
||||
# /etc/resolv.conf
|
||||
|
||||
# If bind is not installed, exit
|
||||
[ -f "/etc/named.conf" ] || exit 0
|
||||
# If dyndb is not enabled for bind, exit
|
||||
grep -q '^dyndb "ipa"' "/etc/named.conf" || exit 0
|
||||
if grep -qE "^[^(#\s*)][0-9\.]+\s$HOSTNAME(\s|$)" /etc/hosts
|
||||
then
|
||||
sed -i.bak -e "s/.*${HOSTNAME}/${IP}\t${HOSTNAME}/" /etc/hosts
|
||||
else
|
||||
echo -e "$IP\t${HOSTNAME} ${HOSTNAME%%.*}" >> /etc/hosts
|
||||
fi
|
||||
|
||||
cp -a /etc/resolv.conf /etc/resolv.conf.fixnet
|
||||
cat > /etc/resolv.conf <<EOF
|
||||
search ${DOMAIN}
|
||||
search ${HOSTNAME#*.}
|
||||
nameserver 127.0.0.1
|
||||
EOF
|
||||
|
||||
echo "/etc/hosts:"
|
||||
cat "/etc/hosts"
|
||||
echo
|
||||
echo "/etc/resolv.conf:"
|
||||
cat "/etc/resolv.conf"
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
---
|
||||
- name: Passkeyconfig example
|
||||
hosts: ipaserver
|
||||
become: no
|
||||
|
||||
tasks:
|
||||
- name: Set passkeyconfig require_user_verification to false
|
||||
ipapasskeyconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
require_user_verification: false
|
||||
@@ -1,14 +0,0 @@
|
||||
---
|
||||
- name: Passkeyconfig get current configuration example
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Get current passkey configuration
|
||||
ipapasskeyconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
register: result
|
||||
|
||||
- name: Display current passkey configuration
|
||||
ansible.builtin.debug:
|
||||
var: result.passkeyconfig
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Sysaccount example
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount my-app is absent
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: absent
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Sysaccount example
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount my-app is disabled
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: disabled
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Sysaccount example
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount my-app is enabled
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: enabled
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Sysaccount example
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount my-app is present with random password
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
random: true
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Sysaccount example
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount my-app is privileged
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
privileged: true
|
||||
@@ -1,11 +0,0 @@
|
||||
---
|
||||
- name: Sysaccount example
|
||||
hosts: ipaserver
|
||||
become: false
|
||||
|
||||
tasks:
|
||||
- name: Ensure sysaccount my-app is not privileged
|
||||
ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
privileged: false
|
||||
@@ -107,7 +107,7 @@ from ansible.plugins.inventory import BaseInventoryPlugin
|
||||
from ansible.module_utils.six.moves.urllib.parse import quote
|
||||
|
||||
|
||||
class InventoryModule(BaseInventoryPlugin): # pylint: disable=R0901
|
||||
class InventoryModule(BaseInventoryPlugin):
|
||||
|
||||
NAME = 'freeipa'
|
||||
|
||||
|
||||
@@ -33,7 +33,7 @@ __all__ = ["DEBUG_COMMAND_ALL", "DEBUG_COMMAND_LIST",
|
||||
"paths", "tasks", "get_credentials_if_valid", "Encoding",
|
||||
"DNSName", "getargspec", "certificate_loader",
|
||||
"write_certificate_list", "boolean", "template_str",
|
||||
"urlparse", "normalize_sshpubkey"]
|
||||
"urlparse", "normalize_sshpubkey", "Email"]
|
||||
|
||||
DEBUG_COMMAND_ALL = 0b1111
|
||||
# Print the while command list:
|
||||
@@ -116,6 +116,7 @@ try:
|
||||
from ipalib.krb_utils import get_credentials_if_valid
|
||||
from ipapython.dnsutil import DNSName
|
||||
from ipapython import kerberos
|
||||
from ipapython.ipavalidate import Email
|
||||
|
||||
try:
|
||||
from ipalib.x509 import Encoding
|
||||
|
||||
@@ -161,7 +161,7 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp",
|
||||
"passkey", "disabled", ""]
|
||||
"disabled", ""]
|
||||
aliases: ["ipauserauthtype"]
|
||||
ca_renewal_master_server:
|
||||
description: Renewal master for IPA certificate authority.
|
||||
@@ -344,7 +344,7 @@ config:
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, ipalib_errors
|
||||
IPAAnsibleModule, compare_args_ipa, ipalib_errors, Email
|
||||
|
||||
|
||||
def config_show(module):
|
||||
@@ -426,7 +426,7 @@ def main():
|
||||
user_auth_type=dict(type="list", elements="str", required=False,
|
||||
choices=["password", "radius", "otp",
|
||||
"pkinit", "hardened", "idp",
|
||||
"passkey", "disabled", ""],
|
||||
"disabled", ""],
|
||||
aliases=["ipauserauthtype"]),
|
||||
ca_renewal_master_server=dict(type="str", required=False),
|
||||
domain_resolution_order=dict(type="list", elements="str",
|
||||
@@ -515,6 +515,13 @@ def main():
|
||||
msg="Argument '%s' must be between %d and %d."
|
||||
% (arg, minimum, maximum))
|
||||
|
||||
# verify email domain
|
||||
emaildomain = params.get("ipadefaultemaildomain", None)
|
||||
if emaildomain:
|
||||
if not Email("test@{0}".format(emaildomain)):
|
||||
ansible_module.fail_json(
|
||||
msg="Invalid 'emaildomain' value: %s" % emaildomain)
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
|
||||
|
||||
@@ -1454,13 +1454,11 @@ def define_commands_for_present_state(module, zone_name, entry, res_find):
|
||||
# Create reverse records for existing records
|
||||
for ipv in ['a', 'aaaa']:
|
||||
record = '%srecord' % ipv
|
||||
if (
|
||||
record in args
|
||||
and args.pop('%s_extra_create_reverse' % ipv, False)
|
||||
):
|
||||
if record in args and ('%s_extra_create_reverse' % ipv) in args:
|
||||
cmds = create_reverse_ip_record(
|
||||
module, zone_name, name, args[record])
|
||||
_commands.extend(cmds)
|
||||
del args['%s_extra_create_reverse' % ipv]
|
||||
for record, fields in _RECORD_PARTS.items():
|
||||
part_fields = [f for f in fields if f in args]
|
||||
if part_fields:
|
||||
@@ -1622,6 +1620,7 @@ def main():
|
||||
commands.extend(cmds)
|
||||
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(
|
||||
commands, exception_handler=exception_handler)
|
||||
|
||||
|
||||
@@ -184,7 +184,7 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["krbprincipalauthind"]
|
||||
choices: ["radius", "otp", "pkinit", "hardened", "idp", "passkey", ""]
|
||||
choices: ["radius", "otp", "pkinit", "hardened", "idp", ""]
|
||||
required: false
|
||||
requires_pre_auth:
|
||||
description: Pre-authentication is required for the service
|
||||
@@ -356,7 +356,7 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["krbprincipalauthind"]
|
||||
choices: ["radius", "otp", "pkinit", "hardened", "idp", "passkey", ""]
|
||||
choices: ["radius", "otp", "pkinit", "hardened", "idp", ""]
|
||||
required: false
|
||||
requires_pre_auth:
|
||||
description: Pre-authentication is required for the service
|
||||
@@ -758,7 +758,7 @@ def main():
|
||||
auth_ind=dict(type='list', elements="str",
|
||||
aliases=["krbprincipalauthind"], default=None,
|
||||
choices=["radius", "otp", "pkinit", "hardened", "idp",
|
||||
"passkey", ""]),
|
||||
""]),
|
||||
requires_pre_auth=dict(type="bool", aliases=["ipakrbrequirespreauth"],
|
||||
default=None),
|
||||
ok_as_delegate=dict(type="bool", aliases=["ipakrbokasdelegate"],
|
||||
|
||||
@@ -281,14 +281,6 @@ def main():
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
# set required fields
|
||||
required = ["base_id", "range_size"]
|
||||
requires_baserid = (
|
||||
ansible_module.ipa_command_param_exists("config_mod", "enable_sid")
|
||||
and idrange_type in [None, "ipa-local"]
|
||||
)
|
||||
if requires_baserid:
|
||||
required.extend(["rid_base", "secondary_rid_base"])
|
||||
|
||||
commands = []
|
||||
for name in names:
|
||||
@@ -329,18 +321,6 @@ def main():
|
||||
del args["iparangetype"]
|
||||
commands.append([name, "idrange_mod", args])
|
||||
else:
|
||||
# Check if required parameters were given
|
||||
missing_params = [
|
||||
pname for pname in required
|
||||
if ansible_module.params_get(pname) is None
|
||||
]
|
||||
if missing_params:
|
||||
ansible_module.fail_json(
|
||||
msg=(
|
||||
"Missing required parameters: %s"
|
||||
% (", ".join(missing_params))
|
||||
)
|
||||
)
|
||||
commands.append([name, "idrange_add", args])
|
||||
|
||||
elif state == "absent":
|
||||
|
||||
@@ -1,174 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Rafael Guterres Jeffman <rjeffman@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2025 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/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipapasskeyconfig
|
||||
short_description: Manage FreeIPA passkeyconfig
|
||||
description: Manage FreeIPA passkeyconfig
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
options:
|
||||
require_user_verification:
|
||||
description: Require user verification for passkey authentication
|
||||
required: false
|
||||
type: bool
|
||||
default: true
|
||||
aliases: ["iparequireuserverification"]
|
||||
author:
|
||||
- Rafael Guterres Jeffman (@rjeffman)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Set passkeyconfig
|
||||
- ipapasskeyconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
require_user_verification: false
|
||||
|
||||
# Get current passkeyconfig
|
||||
- ipapasskeyconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
passkeyconfig:
|
||||
description: Dict of passkeyconfig settings
|
||||
returned: always
|
||||
type: dict
|
||||
contains:
|
||||
require_user_verification:
|
||||
description: Require user verification for passkey authentication
|
||||
type: bool
|
||||
returned: always
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, ipalib_errors
|
||||
from ansible.module_utils import six
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def find_passkeyconfig(module):
|
||||
"""Find the current passkeyconfig settings."""
|
||||
try:
|
||||
_result = module.ipa_command_no_name(
|
||||
"passkeyconfig_show", {"all": True})
|
||||
except ipalib_errors.NotFound:
|
||||
# An exception is raised if passkeyconfig is not found.
|
||||
return None
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def gen_args(require_user_verification):
|
||||
_args = {}
|
||||
if require_user_verification is not None:
|
||||
_args["iparequireuserverification"] = require_user_verification
|
||||
return _args
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# passkeyconfig
|
||||
require_user_verification=dict(
|
||||
required=False, type='bool',
|
||||
aliases=["iparequireuserverification"],
|
||||
default=None
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
require_user_verification = (
|
||||
ansible_module.params_get("require_user_verification")
|
||||
)
|
||||
|
||||
# Init
|
||||
changed = False
|
||||
exit_args = {}
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
|
||||
if not ansible_module.ipa_command_exists("passkeyconfig_show"):
|
||||
msg = "Managing passkeyconfig is not supported by your IPA version"
|
||||
ansible_module.fail_json(msg=msg)
|
||||
|
||||
result = find_passkeyconfig(ansible_module)
|
||||
|
||||
if result is None:
|
||||
ansible_module.fail_json(msg="Could not retrieve passkeyconfig")
|
||||
|
||||
if require_user_verification is not None:
|
||||
# Generate args
|
||||
args = gen_args(require_user_verification)
|
||||
|
||||
# Check if there are different settings in the find result.
|
||||
# If yes: modify
|
||||
if not compare_args_ipa(ansible_module, args, result):
|
||||
changed = True
|
||||
if not ansible_module.check_mode:
|
||||
try:
|
||||
ansible_module.ipa_command_no_name(
|
||||
"passkeyconfig_mod", args)
|
||||
except ipalib_errors.EmptyModlist:
|
||||
changed = False
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(
|
||||
msg="passkeyconfig_mod failed: %s" % str(e))
|
||||
else:
|
||||
# No parameters provided, just return current config
|
||||
pass
|
||||
|
||||
# Get updated config if changes were made
|
||||
if changed:
|
||||
result = find_passkeyconfig(ansible_module)
|
||||
|
||||
# Prepare exit args
|
||||
exit_args["passkeyconfig"] = {}
|
||||
if result:
|
||||
# Map IPA API field to module parameter
|
||||
if "iparequireuserverification" in result:
|
||||
exit_args["passkeyconfig"]["require_user_verification"] = \
|
||||
result["iparequireuserverification"][0]
|
||||
|
||||
# Done
|
||||
ansible_module.exit_json(changed=changed, **exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -85,11 +85,6 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
sysaccount:
|
||||
description: List of sysaccounts.
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
action:
|
||||
description: Work on role or member level.
|
||||
type: str
|
||||
@@ -182,7 +177,7 @@ def check_parameters(module):
|
||||
"description",
|
||||
"user", "group",
|
||||
"host", "hostgroup",
|
||||
"service", "sysaccount",
|
||||
"service",
|
||||
"privilege",
|
||||
]
|
||||
|
||||
@@ -230,7 +225,7 @@ def ensure_absent_state(module, name, action, res_find):
|
||||
{"privilege": del_list}])
|
||||
|
||||
member_args = {}
|
||||
for key in ['user', 'group', 'hostgroup', 'sysaccount']:
|
||||
for key in ['user', 'group', 'hostgroup']:
|
||||
_members = module.params_get_lowercase(key)
|
||||
if _members:
|
||||
del_list = gen_intersection_list(
|
||||
@@ -340,7 +335,7 @@ def ensure_role_with_members_is_present(module, name, res_find, action):
|
||||
add_members = {}
|
||||
del_members = {}
|
||||
|
||||
for key in ["user", "group", "hostgroup", "sysaccount"]:
|
||||
for key in ["user", "group", "hostgroup"]:
|
||||
_members = module.params_get_lowercase(key)
|
||||
if _members is not None:
|
||||
add_list, del_list = gen_add_del_lists(
|
||||
@@ -442,8 +437,6 @@ def create_module():
|
||||
default=None),
|
||||
service=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
sysaccount=dict(required=False, type='list', elements="str",
|
||||
default=None),
|
||||
|
||||
# state
|
||||
action=dict(type="str", default="role",
|
||||
@@ -474,15 +467,8 @@ def main():
|
||||
state = ansible_module.params_get("state")
|
||||
action = ansible_module.params_get("action")
|
||||
names = ansible_module.params_get("name")
|
||||
sysaccount = ansible_module.params_get("sysaccount")
|
||||
commands = []
|
||||
|
||||
has_sysaccount_member = ansible_module.ipa_command_param_exists(
|
||||
"role_add_member", "sysaccount")
|
||||
if not has_sysaccount_member and sysaccount is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="sysaccount members are not supported by your IPA version")
|
||||
|
||||
for name in names:
|
||||
cmds = role_commands_for_name(ansible_module, state, action, name)
|
||||
commands.extend(cmds)
|
||||
|
||||
@@ -74,7 +74,7 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
choices: ["otp", "radius", "pkinit", "hardened", "idp", "passkey", ""]
|
||||
choices: ["otp", "radius", "pkinit", "hardened", "idp", ""]
|
||||
aliases: ["krbprincipalauthind"]
|
||||
skip_host_check:
|
||||
description: Skip checking if host object exists.
|
||||
@@ -192,7 +192,7 @@ options:
|
||||
type: list
|
||||
elements: str
|
||||
required: false
|
||||
choices: ["otp", "radius", "pkinit", "hardened", "idp", "passkey", ""]
|
||||
choices: ["otp", "radius", "pkinit", "hardened", "idp", ""]
|
||||
aliases: ["krbprincipalauthind"]
|
||||
skip_host_check:
|
||||
description: Skip checking if host object exists.
|
||||
@@ -560,7 +560,7 @@ def init_ansible_module():
|
||||
auth_ind=dict(type="list", elements="str",
|
||||
aliases=["krbprincipalauthind"],
|
||||
choices=["otp", "radius", "pkinit", "hardened", "idp",
|
||||
"passkey", ""]),
|
||||
""]),
|
||||
skip_host_check=dict(type="bool"),
|
||||
force=dict(type="bool"),
|
||||
requires_pre_auth=dict(
|
||||
|
||||
@@ -1,309 +0,0 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2025 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/>.
|
||||
|
||||
from __future__ import (absolute_import, division, print_function)
|
||||
|
||||
__metaclass__ = type
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipasysaccount
|
||||
short_description: Manage FreeIPA system account
|
||||
description: Manage FreeIPA system account
|
||||
extends_documentation_fragment:
|
||||
- ipamodule_base_docs
|
||||
- ipamodule_base_docs.delete_continue
|
||||
options:
|
||||
name:
|
||||
description: The list of sysaccount name strings (internally uid).
|
||||
required: true
|
||||
type: list
|
||||
elements: str
|
||||
aliases: ["login"]
|
||||
description:
|
||||
description: A description for the sysaccount.
|
||||
type: str
|
||||
required: false
|
||||
privileged:
|
||||
description: Allow password updates without reset.
|
||||
type: bool
|
||||
required: false
|
||||
random:
|
||||
description: Generate a random user password.
|
||||
required: false
|
||||
type: bool
|
||||
password:
|
||||
description: Set the user password.
|
||||
required: false
|
||||
type: str
|
||||
aliases: ["userpassword"]
|
||||
update_password:
|
||||
description:
|
||||
Set password for a sysaccount in present state only on creation or always
|
||||
type: str
|
||||
choices: ["always", "on_create"]
|
||||
required: false
|
||||
state:
|
||||
description: The state to ensure.
|
||||
choices: ["present", "absent", "enabled", "disabled"]
|
||||
default: present
|
||||
type: str
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
# Ensure sysaccount my-app is present
|
||||
- ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
random: true
|
||||
|
||||
# Ensure sysaccount my-app is absent
|
||||
- ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: absent
|
||||
|
||||
# Ensure existing sysaccount my-app is privileged
|
||||
- ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
privileged: true
|
||||
|
||||
# Ensure existing sysaccount my-app is not privileged
|
||||
- ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
privileged: false
|
||||
|
||||
# Ensure existing sysaccount my-app is disabled
|
||||
- ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: disabled
|
||||
|
||||
# Ensure existing sysaccount my-app is enabled
|
||||
- ipasysaccount:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
name: my-app
|
||||
state: enabled
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
sysaccount:
|
||||
description: Sysaccount dict with random password
|
||||
returned: |
|
||||
If random is yes and user sysaccount not exist or update_password is yes
|
||||
type: dict
|
||||
contains:
|
||||
randompassword:
|
||||
description: The generated random password
|
||||
type: str
|
||||
"""
|
||||
|
||||
|
||||
from ansible.module_utils.ansible_freeipa_module import \
|
||||
IPAAnsibleModule, compare_args_ipa, ipalib_errors
|
||||
from ansible.module_utils import six
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
|
||||
def find_sysaccount(module, name):
|
||||
"""Find if a sysaccount with the given name already exist."""
|
||||
try:
|
||||
_result = module.ipa_command("sysaccount_show", name, {"all": True})
|
||||
except ipalib_errors.NotFound:
|
||||
# An exception is raised if sysaccount name is not found.
|
||||
return None
|
||||
return _result["result"]
|
||||
|
||||
|
||||
def gen_args(description, random, privileged, password):
|
||||
_args = {}
|
||||
if description is not None:
|
||||
_args["description"] = description
|
||||
if random is not None:
|
||||
_args["random"] = random
|
||||
if privileged is not None:
|
||||
_args["privileged"] = privileged
|
||||
if password is not None:
|
||||
_args["userpassword"] = password
|
||||
return _args
|
||||
|
||||
|
||||
# pylint: disable=unused-argument
|
||||
def result_handler(module, result, command, name, args, exit_args, errors):
|
||||
if "random" in args and command in ["sysaccount_add", "sysaccount_mod"] \
|
||||
and "randompassword" in result["result"]:
|
||||
exit_args["randompassword"] = \
|
||||
result["result"]["randompassword"]
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = IPAAnsibleModule(
|
||||
argument_spec=dict(
|
||||
# general
|
||||
name=dict(type="list", elements="str", required=True,
|
||||
aliases=["login"]),
|
||||
# present
|
||||
description=dict(required=False, type='str', default=None),
|
||||
random=dict(required=False, type='bool', default=None),
|
||||
privileged=dict(required=False, type='bool', default=None),
|
||||
password=dict(required=False, type='str',
|
||||
aliases=["userpassword"], default=None),
|
||||
|
||||
# mod
|
||||
update_password=dict(type='str', default=None, no_log=False,
|
||||
choices=['always', 'on_create']),
|
||||
|
||||
# state
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent", "enabled", "disabled"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
ipa_module_options=["delete_continue"],
|
||||
mutually_exclusive=[["random", "password"]]
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
# general
|
||||
names = ansible_module.params_get("name")
|
||||
|
||||
# present
|
||||
description = ansible_module.params_get("description")
|
||||
random = ansible_module.params_get("random")
|
||||
privileged = ansible_module.params_get("privileged")
|
||||
password = ansible_module.params_get("password")
|
||||
|
||||
# mod
|
||||
update_password = ansible_module.params_get("update_password")
|
||||
|
||||
# absent
|
||||
delete_continue = ansible_module.params_get("delete_continue")
|
||||
|
||||
# state
|
||||
state = ansible_module.params_get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
invalid = []
|
||||
|
||||
if state == "present" and len(names) != 1:
|
||||
ansible_module.fail_json(
|
||||
msg="Only one sysaccount can be added at a time.")
|
||||
|
||||
if state in ["absent", "enabled", "disabled"]:
|
||||
if len(names) < 1:
|
||||
ansible_module.fail_json(msg="No name given.")
|
||||
invalid = ["description", "random", "privileged", "password"]
|
||||
|
||||
ansible_module.params_fail_used_invalid(invalid, state)
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
exit_args = {}
|
||||
|
||||
# Connect to IPA API
|
||||
with ansible_module.ipa_connect():
|
||||
|
||||
if not ansible_module.ipa_command_exists("sysaccount_add"):
|
||||
ansible_module.fail_json(
|
||||
msg=("Managing sysaccounts is not supported by your "
|
||||
"IPA version")
|
||||
)
|
||||
|
||||
commands = []
|
||||
for name in names:
|
||||
# Make sure sysaccount exists
|
||||
res_find = find_sysaccount(ansible_module, name)
|
||||
|
||||
# Create command
|
||||
if state == "present":
|
||||
|
||||
# Generate args
|
||||
args = gen_args(description, random, privileged, password)
|
||||
|
||||
# Found the sysaccount
|
||||
if res_find is not None:
|
||||
# Ignore password and random with
|
||||
# update_password == on_create
|
||||
if update_password == "on_create":
|
||||
if "userpassword" in args:
|
||||
del args["userpassword"]
|
||||
if "random" in args:
|
||||
del args["random"]
|
||||
# if using "random:false" password should not be
|
||||
# generated.
|
||||
if not args.get("random", True):
|
||||
del args["random"]
|
||||
|
||||
# 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, "sysaccount_mod", args])
|
||||
else:
|
||||
commands.append([name, "sysaccount_add", args])
|
||||
|
||||
elif state == "absent":
|
||||
if res_find is not None:
|
||||
commands.append(
|
||||
[name, "sysaccount_del", {"continue": delete_continue}]
|
||||
)
|
||||
|
||||
elif state == "enabled":
|
||||
if res_find is not None and res_find["nsaccountlock"]:
|
||||
commands.append([name, "sysaccount_enable", {}])
|
||||
|
||||
elif state == "disabled":
|
||||
if res_find is not None and not res_find["nsaccountlock"]:
|
||||
commands.append([name, "sysaccount_disable", {}])
|
||||
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute commands
|
||||
|
||||
changed = ansible_module.execute_ipa_commands(
|
||||
commands, result_handler, keeponly=["randompassword"],
|
||||
exit_args=exit_args)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed, sysaccount=exit_args)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -208,8 +208,7 @@ options:
|
||||
Use empty string to reset userauthtype to the initial value.
|
||||
type: list
|
||||
elements: str
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp",
|
||||
"passkey", ""]
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp", ""]
|
||||
required: false
|
||||
aliases: ["ipauserauthtype"]
|
||||
userclass:
|
||||
@@ -481,8 +480,7 @@ options:
|
||||
Use empty string to reset userauthtype to the initial value.
|
||||
type: list
|
||||
elements: str
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp",
|
||||
"passkey", ""]
|
||||
choices: ["password", "radius", "otp", "pkinit", "hardened", "idp", ""]
|
||||
required: false
|
||||
aliases: ["ipauserauthtype"]
|
||||
userclass:
|
||||
@@ -1072,7 +1070,7 @@ def main():
|
||||
userauthtype=dict(type='list', elements="str",
|
||||
aliases=["ipauserauthtype"], default=None,
|
||||
choices=["password", "radius", "otp", "pkinit",
|
||||
"hardened", "idp", "passkey", ""]),
|
||||
"hardened", "idp", ""]),
|
||||
userclass=dict(type="list", elements="str", aliases=["class"],
|
||||
default=None),
|
||||
radius=dict(type="str", aliases=["ipatokenradiusconfiglink"],
|
||||
|
||||
@@ -4,4 +4,3 @@ junit_family = xunit1
|
||||
markers=
|
||||
source_order: mark test as order bound
|
||||
playbook: playbook tests
|
||||
pythonpath = tests
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
-r requirements-tests.txt
|
||||
ipdb==0.13.4
|
||||
pre-commit==2.20.0
|
||||
flake8
|
||||
flake8==7.0.0
|
||||
flake8-bugbear
|
||||
pylint>=3.2
|
||||
wrapt==1.14.1
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
-r requirements.txt
|
||||
pytest
|
||||
pytest-sourceorder
|
||||
pytest==7.1.3
|
||||
pytest-sourceorder==0.6.0
|
||||
pytest-split>=0.8.0
|
||||
pytest-custom_exit_code>=0.3.0
|
||||
pytest-testinfra
|
||||
pytest-randomly
|
||||
pytest-testinfra==6.8.0
|
||||
pytest-randomly==3.12.0
|
||||
pyyaml>=3
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
setuptools
|
||||
|
||||
@@ -91,21 +91,20 @@
|
||||
enabled: yes
|
||||
state: started
|
||||
|
||||
- name: Firewalld - Verify zones
|
||||
- name: Firewalld - Verify runtime zone "{{ ipabackup_firewalld_zone }}"
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--info-zone="{{ ipabackup_firewalld_zone }}"
|
||||
>/dev/null
|
||||
when: ipabackup_firewalld_zone is defined
|
||||
block:
|
||||
- name: Firewalld - Verify runtime zone from ipabackup_firewalld_zone
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--info-zone="{{ ipabackup_firewalld_zone }}"
|
||||
>/dev/null
|
||||
|
||||
- name: Firewalld - Verify permanent zone from ipabackup_firewalld_zone
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--permanent
|
||||
--info-zone="{{ ipabackup_firewalld_zone }}"
|
||||
>/dev/null
|
||||
- name: Firewalld - Verify permanent zone "{{ ipabackup_firewalld_zone }}"
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--permanent
|
||||
--info-zone="{{ ipabackup_firewalld_zone }}"
|
||||
>/dev/null
|
||||
when: ipabackup_firewalld_zone is defined
|
||||
|
||||
### RESTORE
|
||||
|
||||
|
||||
@@ -202,8 +202,6 @@ Variable | Description | Required
|
||||
`ipaclient_request_cert` | The bool value defines if the certificate for the machine wil be requested. The certificate will be stored in /etc/ipa/nssdb under the nickname "Local IPA host". . `ipaclient_request_cert` defaults to `no`. The option is deprecated and will be removed in a future release. | no
|
||||
`ipaclient_keytab` | The string value contains the path on the node of a backup host keytab from a previous enrollment. | no
|
||||
`ipaclient_automount_location` | Automount location | no
|
||||
`ipaclient_dns_over_tls` | Configure DNS over TLS. Requires FreeIPA version 4.12.5 or later. (bool, default: false) | no
|
||||
`ipaclient_no_dnssec_validation` | Disable DNSSEC validation for DNS over TLS. This turns off DNSSEC validation for unbound. Ignored if `ipaserver_dns_over_tls` is not enabled. (bool, default: false) | no
|
||||
|
||||
|
||||
Server Variables
|
||||
|
||||
@@ -26,8 +26,6 @@ ipasssd_enable_dns_updates: no
|
||||
ipasssd_no_krb5_offline_passwords: no
|
||||
ipasssd_preserve_sssd: no
|
||||
ipaclient_request_cert: no
|
||||
ipaclient_dns_over_tls: no
|
||||
ipaclient_no_dnssec_validation: no
|
||||
|
||||
### packages ###
|
||||
ipaclient_install_packages: yes
|
||||
|
||||
@@ -86,16 +86,6 @@ options:
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
no_dnssec_validation:
|
||||
description: Disable DNSSEC validation for DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
enable_dns_updates:
|
||||
description: |
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
@@ -222,9 +212,7 @@ def main():
|
||||
mkhomedir=dict(required=False, type='bool'),
|
||||
on_master=dict(required=False, type='bool'),
|
||||
dnsok=dict(required=False, type='bool', default=False),
|
||||
dns_over_tls=dict(required=False, type='bool', default=False),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
|
||||
enable_dns_updates=dict(required=False, type='bool'),
|
||||
all_ip_addresses=dict(required=False, type='bool', default=False),
|
||||
ip_addresses=dict(required=False, type='list', elements='str',
|
||||
@@ -261,8 +249,6 @@ def main():
|
||||
options.mkhomedir = module.params.get('mkhomedir')
|
||||
options.on_master = module.params.get('on_master')
|
||||
dnsok = module.params.get('dnsok')
|
||||
options.dns_over_tls = module.params.get('dns_over_tls')
|
||||
options.no_dnssec_validation = module.params.get('no_dnssec_validation')
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
statestore = sysrestore.StateFile(paths.IPA_CLIENT_SYSRESTORE)
|
||||
@@ -270,7 +256,6 @@ def main():
|
||||
os.environ['KRB5CCNAME'] = paths.IPA_DNS_CCACHE
|
||||
|
||||
options.dns_updates = module.params.get('enable_dns_updates')
|
||||
options.dns_over_tls = module.params.get('dns_over_tls')
|
||||
options.all_ip_addresses = module.params.get('all_ip_addresses')
|
||||
options.ip_addresses = ansible_module_get_parsed_ip_addresses(module)
|
||||
options.request_cert = module.params.get('request_cert')
|
||||
@@ -294,7 +279,6 @@ def main():
|
||||
options.no_sssd = False
|
||||
options.sssd = not options.no_sssd
|
||||
options.no_ac = False
|
||||
options.dns_over_tls = module.params.get('dns_over_tls')
|
||||
nosssd_files = module.params.get('nosssd_files')
|
||||
selinux_works = module.params.get('selinux_works')
|
||||
krb_name = module.params.get('krb_name')
|
||||
@@ -355,19 +339,17 @@ def main():
|
||||
ca_subject)
|
||||
ca_certs_trust = [(c, n,
|
||||
certstore.key_policy_to_trust_flags(t, True, u))
|
||||
for (c, n, t, u) in [x[0:4] for x in ca_certs]]
|
||||
for (c, n, t, u) in ca_certs]
|
||||
|
||||
if hasattr(paths, "KDC_CA_BUNDLE_PEM"):
|
||||
x509.write_certificate_list(
|
||||
[c for c, n, t, u in [x[0:4] for x in ca_certs]
|
||||
if t is not False],
|
||||
[c for c, n, t, u in ca_certs if t is not False],
|
||||
paths.KDC_CA_BUNDLE_PEM,
|
||||
# mode=0o644
|
||||
)
|
||||
if hasattr(paths, "CA_BUNDLE_PEM"):
|
||||
x509.write_certificate_list(
|
||||
[c for c, n, t, u in [x[0:4] for x in ca_certs]
|
||||
if t is not False],
|
||||
[c for c, n, t, u in ca_certs if t is not False],
|
||||
paths.CA_BUNDLE_PEM,
|
||||
# mode=0o644
|
||||
)
|
||||
@@ -388,22 +370,13 @@ def main():
|
||||
tasks.insert_ca_certs_into_systemwide_ca_store(ca_certs)
|
||||
|
||||
if not options.on_master:
|
||||
argspec_client_dns = getargspec(client_dns)
|
||||
if "statestore" in argspec_client_dns.args:
|
||||
client_dns(cli_server[0], hostname, options, statestore)
|
||||
else:
|
||||
client_dns(cli_server[0], hostname, options)
|
||||
client_dns(cli_server[0], hostname, options)
|
||||
|
||||
if hasattr(paths, "SSH_CONFIG_DIR"):
|
||||
ssh_config_dir = paths.SSH_CONFIG_DIR
|
||||
else:
|
||||
ssh_config_dir = services.knownservices.sshd.get_config_dir()
|
||||
argspec_update_ssh_keys = getargspec(update_ssh_keys)
|
||||
# Hotfix for https://github.com/freeipa/freeipa/pull/7343
|
||||
if "options" in argspec_update_ssh_keys.args:
|
||||
update_ssh_keys(hostname, ssh_config_dir, options, cli_server[0])
|
||||
else:
|
||||
update_ssh_keys(hostname, ssh_config_dir, options.create_sshfp)
|
||||
update_ssh_keys(hostname, ssh_config_dir, options.create_sshfp)
|
||||
|
||||
try:
|
||||
os.remove(CCACHE_FILE)
|
||||
|
||||
@@ -91,11 +91,6 @@ options:
|
||||
changes
|
||||
type: bool
|
||||
required: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
preserve_sssd:
|
||||
description: Preserve old SSSD configuration if possible
|
||||
type: bool
|
||||
@@ -145,7 +140,6 @@ def main():
|
||||
fixed_primary=dict(required=False, type='bool'),
|
||||
permit=dict(required=False, type='bool'),
|
||||
enable_dns_updates=dict(required=False, type='bool'),
|
||||
dns_over_tls=dict(required=False, type='bool', default=False),
|
||||
preserve_sssd=dict(required=False, type='bool'),
|
||||
no_krb5_offline_passwords=dict(required=False, type='bool'),
|
||||
),
|
||||
@@ -175,13 +169,11 @@ def main():
|
||||
options.primary = module.params.get('fixed_primary')
|
||||
options.permit = module.params.get('permit')
|
||||
options.dns_updates = module.params.get('enable_dns_updates')
|
||||
options.dns_over_tls = module.params.get('dns_over_tls')
|
||||
options.preserve_sssd = module.params.get('preserve_sssd')
|
||||
|
||||
options.no_krb5_offline_passwords = module.params.get(
|
||||
'no_krb5_offline_passwords')
|
||||
options.krb5_offline_passwords = not options.no_krb5_offline_passwords
|
||||
options.dns_over_tls = False
|
||||
|
||||
fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
client_domain = hostname[hostname.find(".") + 1:]
|
||||
|
||||
@@ -124,16 +124,6 @@ options:
|
||||
type: bool
|
||||
required: no
|
||||
default: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
no_dnssec_validation:
|
||||
description: Disable DNSSEC validation for DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
enable_dns_updates:
|
||||
description:
|
||||
Configures the machine to attempt dns updates when the ip address
|
||||
@@ -258,8 +248,7 @@ from ansible.module_utils.ansible_ipa_client import (
|
||||
CLIENT_INSTALL_ERROR, tasks, check_ldap_conf, timeconf, constants,
|
||||
validate_hostname, nssldap_exists, gssapi, remove_file,
|
||||
check_ip_addresses, ipadiscovery, print_port_conf_info,
|
||||
IPA_PYTHON_VERSION, getargspec, services,
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION
|
||||
IPA_PYTHON_VERSION, getargspec
|
||||
)
|
||||
|
||||
|
||||
@@ -339,9 +328,6 @@ def main():
|
||||
default=None),
|
||||
all_ip_addresses=dict(required=False, type='bool', default=False),
|
||||
on_master=dict(required=False, type='bool', default=False),
|
||||
dns_over_tls=dict(required=False, type='bool', default=False),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
# sssd
|
||||
enable_dns_updates=dict(required=False, type='bool',
|
||||
default=False),
|
||||
@@ -370,8 +356,6 @@ def main():
|
||||
options.ip_addresses = module.params.get('ip_addresses')
|
||||
options.all_ip_addresses = module.params.get('all_ip_addresses')
|
||||
options.on_master = module.params.get('on_master')
|
||||
options.dns_over_tls = module.params.get('dns_over_tls')
|
||||
options.no_dnssec_validation = module.params.get('no_dnssec_validation')
|
||||
options.enable_dns_updates = module.params.get('enable_dns_updates')
|
||||
|
||||
# Get domain from first server if domain is not set, but if there are
|
||||
@@ -381,16 +365,6 @@ def main():
|
||||
options.domain_name = options.servers[0][
|
||||
options.servers[0].find(".") + 1:]
|
||||
|
||||
if options.dns_over_tls \
|
||||
and not services.knownservices["unbound"].is_installed():
|
||||
module.fail_json(
|
||||
msg="To enable DNS over TLS, package ipa-client-encrypted-dns "
|
||||
"must be installed.")
|
||||
if options.dns_over_tls and not CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION:
|
||||
module.fail_json(
|
||||
msg="Important patches for DNS over TLS are missing in your IPA "
|
||||
"version.")
|
||||
|
||||
try:
|
||||
self = options
|
||||
|
||||
|
||||
@@ -231,6 +231,8 @@ try:
|
||||
cli_realm, cli_domain, cli_server, cli_kdc, dnsok,
|
||||
filename, client_domain, client_hostname, force=False,
|
||||
configure_sssd=True):
|
||||
# pylint: disable=global-variable-not-assigned
|
||||
global options
|
||||
options.force = force
|
||||
options.sssd = configure_sssd
|
||||
return ipa_client_install.configure_krb5_conf(
|
||||
@@ -310,15 +312,6 @@ try:
|
||||
except ImportError:
|
||||
configure_selinux_for_client = None
|
||||
|
||||
try:
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION = False
|
||||
from ipaclient.install.client import ClientInstallInterface
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
if hasattr(ClientInstallInterface, "no_dnssec_validation"):
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION = True
|
||||
|
||||
logger = logging.getLogger("ipa-client-install")
|
||||
root_logger = logger
|
||||
|
||||
|
||||
@@ -1,23 +1,11 @@
|
||||
---
|
||||
# tasks file for ipaclient
|
||||
|
||||
- name: Install - Package installation
|
||||
- name: Install - Ensure that IPA client packages are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipaclient_packages }}"
|
||||
state: present
|
||||
when: ipaclient_install_packages | bool
|
||||
block:
|
||||
|
||||
- name: Install - Set packages for installation
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ ipaclient_packages }}"
|
||||
|
||||
- name: Install - Set packages for installlation, add DOT
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipaclient_packages_dot }}"
|
||||
when: ipaclient_dns_over_tls | bool
|
||||
|
||||
- name: Install - Ensure that packages are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ _ipapackages }}"
|
||||
state: present
|
||||
|
||||
- name: Install - Set ipaclient_servers
|
||||
ansible.builtin.set_fact:
|
||||
@@ -50,7 +38,7 @@
|
||||
msg: "ipaclient_domain or ipaserver_domain is required for ipaclient_configure_dns_resolver"
|
||||
when: ipaserver_domain is not defined and ipaclient_domain is not defined
|
||||
|
||||
- name: Install - Fail on missing ipaclient_dns_servers
|
||||
- name: Install - Fail on missing ipaclient_servers
|
||||
ansible.builtin.fail:
|
||||
msg: "ipaclient_dns_servers is required for ipaclient_configure_dns_resolver"
|
||||
when: ipaclient_dns_servers is not defined
|
||||
@@ -81,10 +69,9 @@
|
||||
ip_addresses: "{{ ipaclient_ip_addresses | default(omit) }}"
|
||||
all_ip_addresses: "{{ ipaclient_all_ip_addresses }}"
|
||||
on_master: "{{ ipaclient_on_master }}"
|
||||
dns_over_tls: "{{ ipaclient_dns_over_tls }}"
|
||||
no_dnssec_validation: "{{ ipaclient_no_dnssec_validation }}"
|
||||
### sssd ###
|
||||
enable_dns_updates: "{{ ipasssd_enable_dns_updates }}"
|
||||
enable_dns_updates: "{{ ipassd_enable_dns_updates
|
||||
| default(ipasssd_enable_dns_updates) }}"
|
||||
register: result_ipaclient_test
|
||||
|
||||
- name: Install - Client deployment
|
||||
@@ -181,10 +168,10 @@
|
||||
|
||||
- name: Install - Store the previously obtained OTP
|
||||
no_log: yes
|
||||
when: result_ipaclient_get_otp.host is defined
|
||||
ansible.builtin.set_fact:
|
||||
ipaadmin_orig_password: "{{ ipaadmin_password | default(omit) }}"
|
||||
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword | default(omit) }}"
|
||||
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword
|
||||
if result_ipaclient_get_otp.host is defined }}"
|
||||
rescue:
|
||||
- name: Install - Report error for OTP generation
|
||||
ansible.builtin.debug:
|
||||
@@ -334,12 +321,16 @@
|
||||
no_sshd: "{{ ipaclient_no_sshd }}"
|
||||
no_sudo: "{{ ipaclient_no_sudo }}"
|
||||
all_ip_addresses: "{{ ipaclient_all_ip_addresses }}"
|
||||
fixed_primary: "{{ ipasssd_fixed_primary }}"
|
||||
permit: "{{ ipasssd_permit }}"
|
||||
enable_dns_updates: "{{ ipasssd_enable_dns_updates }}"
|
||||
dns_over_tls: "{{ ipaclient_dns_over_tls }}"
|
||||
preserve_sssd: "{{ ipasssd_preserve_sssd }}"
|
||||
no_krb5_offline_passwords: "{{ ipasssd_no_krb5_offline_passwords }}"
|
||||
fixed_primary: "{{ ipassd_fixed_primary
|
||||
| default(ipasssd_fixed_primary) }}"
|
||||
permit: "{{ ipassd_permit | default(ipasssd_permit) }}"
|
||||
enable_dns_updates: "{{ ipassd_enable_dns_updates
|
||||
| default(ipasssd_enable_dns_updates) }}"
|
||||
preserve_sssd: "{{ ipassd_preserve_sssd
|
||||
| default(ipasssd_preserve_sssd) }}"
|
||||
no_krb5_offline_passwords:
|
||||
"{{ ipassd_no_krb5_offline_passwords
|
||||
| default(ipasssd_no_krb5_offline_passwords) }}"
|
||||
|
||||
- name: Install - IPA API calls for remaining enrollment parts
|
||||
ipaclient_api:
|
||||
@@ -374,20 +365,23 @@
|
||||
ca_enabled: "{{ result_ipaclient_api.ca_enabled }}"
|
||||
on_master: "{{ ipaclient_on_master }}"
|
||||
dnsok: "{{ result_ipaclient_test.dnsok }}"
|
||||
enable_dns_updates: "{{ ipasssd_enable_dns_updates }}"
|
||||
dns_over_tls: "{{ ipaclient_dns_over_tls }}"
|
||||
no_dnssec_validation: "{{ ipaclient_no_dnssec_validation }}"
|
||||
enable_dns_updates: "{{ ipassd_enable_dns_updates
|
||||
| default(ipasssd_enable_dns_updates) }}"
|
||||
all_ip_addresses: "{{ ipaclient_all_ip_addresses }}"
|
||||
ip_addresses: "{{ ipaclient_ip_addresses | default(omit) }}"
|
||||
request_cert: "{{ ipaclient_request_cert }}"
|
||||
preserve_sssd: "{{ ipasssd_preserve_sssd }}"
|
||||
preserve_sssd: "{{ ipassd_preserve_sssd
|
||||
| default(ipasssd_preserve_sssd) }}"
|
||||
no_ssh: "{{ ipaclient_no_ssh }}"
|
||||
no_sshd: "{{ ipaclient_no_sshd }}"
|
||||
no_sudo: "{{ ipaclient_no_sudo }}"
|
||||
subid: "{{ ipaclient_subid }}"
|
||||
fixed_primary: "{{ ipasssd_fixed_primary }}"
|
||||
permit: "{{ ipasssd_permit }}"
|
||||
no_krb5_offline_passwords: "{{ ipasssd_no_krb5_offline_passwords }}"
|
||||
fixed_primary: "{{ ipassd_fixed_primary
|
||||
| default(ipasssd_fixed_primary) }}"
|
||||
permit: "{{ ipassd_permit | default(ipasssd_permit) }}"
|
||||
no_krb5_offline_passwords:
|
||||
"{{ ipassd_no_krb5_offline_passwords
|
||||
| default(ipasssd_no_krb5_offline_passwords) }}"
|
||||
no_dns_sshfp: "{{ ipaclient_no_dns_sshfp }}"
|
||||
nosssd_files: "{{ result_ipaclient_test.nosssd_files }}"
|
||||
selinux_works: "{{ result_ipaclient_test.selinux_works }}"
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
---
|
||||
# vars/Debian.yml
|
||||
ipaclient_packages: [ "freeipa-client" ]
|
||||
ipaclient_packages_dot: [ ]
|
||||
# Debian Buster must use python2 as Python interpreter due
|
||||
# to the way freeipa-client package is defined.
|
||||
# You must install package python2.7 before executing this role.
|
||||
|
||||
@@ -2,4 +2,3 @@
|
||||
# vars/Debian.yml
|
||||
---
|
||||
ipaclient_packages: [ "freeipa-client" ]
|
||||
ipaclient_packages_dot: [ ]
|
||||
|
||||
@@ -2,4 +2,3 @@
|
||||
# vars/RedHat-7
|
||||
---
|
||||
ipaclient_packages: [ "ipa-client", "libselinux-python" ]
|
||||
ipaclient_packages_dot: [ ]
|
||||
|
||||
@@ -2,4 +2,3 @@
|
||||
# vars/RedHat-8.yml
|
||||
---
|
||||
ipaclient_packages: [ "@idm:DL1/client" ]
|
||||
ipaclient_packages_dot: [ ]
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
# vars/Ubuntu-18.04.yml
|
||||
---
|
||||
ipaclient_packages: [ "freeipa-client" ]
|
||||
ipaclient_packages_dot: [ ]
|
||||
# Ubuntu Bionic Beaver must use python2 as Python interpreter due
|
||||
# to the way python-ipalib package is defined.
|
||||
# Package python2.7 must be installed before executing this role.
|
||||
|
||||
@@ -2,4 +2,3 @@
|
||||
# vars/default.yml
|
||||
---
|
||||
ipaclient_packages: [ "ipa-client", "python3-libselinux" ]
|
||||
ipaclient_packages_dot: [ "ipa-client-encrypted-dns" ]
|
||||
|
||||
@@ -270,11 +270,6 @@ Variable | Description | Required
|
||||
`ipareplica_auto_forwarders` | Add DNS forwarders configured in /etc/resolv.conf to the list of forwarders used by IPA DNS. (bool, default: false) | no
|
||||
`ipareplica_forward_policy` | DNS forwarding policy for global forwarders specified using other options. (choice: first,only) | no
|
||||
`ipareplica_no_dnssec_validation` | Disable DNSSEC validation on this server. (bool, default: false) | no
|
||||
`ipareplica_dot_forwarders` | List of DNS over TLS forwarders. Required if `ipareplica_dns_over_tls` is enabled. (list of strings) | no
|
||||
`ipareplica_dns_over_tls` \| `ipaclient_dns_over_tls` | Configure DNS over TLS. Requires FreeIPA version 4.12.5 or later. (bool, default: false) | no
|
||||
`ipareplica_dns_over_tls_cert` | Certificate to use for DNS over TLS. If empty, a new certificate will be requested from IPA CA. (string) | no
|
||||
`ipareplica_dns_over_tls_key` | Key for certificate specified in `ipareplica_dns_over_tls_cert`. (string) | no
|
||||
`ipareplica_dns_policy` | Encrypted DNS policy. Only usable if `ipareplica_dns_over_tls` is enabled. (choice: relaxed, enforced, default: relaxed) | no
|
||||
|
||||
AD trust Variables
|
||||
------------------
|
||||
|
||||
@@ -224,32 +224,6 @@ options:
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dot_forwarders:
|
||||
description: List of DNS over TLS forwarders
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
required: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dns_over_tls_cert:
|
||||
description:
|
||||
Certificate to use for DNS over TLS. If empty, a new
|
||||
certificate will be requested from IPA CA
|
||||
type: str
|
||||
required: no
|
||||
dns_over_tls_key:
|
||||
description: Key for certificate specified in dns_over_tls_cert
|
||||
type: str
|
||||
required: no
|
||||
dns_policy:
|
||||
description: Encrypted DNS policy
|
||||
type: str
|
||||
choices: ['relaxed', 'enforced']
|
||||
default: 'relaxed'
|
||||
enable_compat:
|
||||
description: Enable support for trusted domains for old clients
|
||||
type: bool
|
||||
@@ -380,15 +354,6 @@ def main():
|
||||
choices=['first', 'only'], default=None),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dot_forwarders=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
dns_over_tls=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dns_over_tls_cert=dict(required=False, type='str'),
|
||||
dns_over_tls_key=dict(required=False, type='str'),
|
||||
dns_policy=dict(required=False, type='str',
|
||||
choices=['relaxed', 'enforced'],
|
||||
default='relaxed'),
|
||||
# ad trust
|
||||
enable_compat=dict(required=False, type='bool', default=False),
|
||||
netbios_name=dict(required=False, type='str'),
|
||||
@@ -465,11 +430,6 @@ def main():
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
options.dot_forwarders = ansible_module.params.get('dot_forwarders')
|
||||
options.dns_over_tls = ansible_module.params.get('dns_over_tls')
|
||||
options.dns_over_tls_cert = ansible_module.params.get('dns_over_tls_cert')
|
||||
options.dns_over_tls_key = ansible_module.params.get('dns_over_tls_key')
|
||||
options.dns_policy = ansible_module.params.get('dns_policy')
|
||||
# ad trust
|
||||
options.enable_compat = ansible_module.params.get('enable_compat')
|
||||
options.netbios_name = ansible_module.params.get('netbios_name')
|
||||
|
||||
@@ -72,32 +72,6 @@ options:
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dot_forwarders:
|
||||
description: List of DNS over TLS forwarders
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
required: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dns_over_tls_cert:
|
||||
description:
|
||||
Certificate to use for DNS over TLS. If empty, a new
|
||||
certificate will be requested from IPA CA
|
||||
type: str
|
||||
required: no
|
||||
dns_over_tls_key:
|
||||
description: Key for certificate specified in dns_over_tls_cert
|
||||
type: str
|
||||
required: no
|
||||
dns_policy:
|
||||
description: Encrypted DNS policy
|
||||
type: str
|
||||
choices: ['relaxed', 'enforced']
|
||||
default: 'relaxed'
|
||||
dns_ip_addresses:
|
||||
description: The dns ip_addresses setting
|
||||
type: list
|
||||
@@ -143,9 +117,6 @@ from ansible.module_utils.ansible_ipa_replica import (
|
||||
gen_ReplicaConfig, gen_remote_api, api, redirect_stdout, dns,
|
||||
ansible_module_get_parsed_ip_addresses
|
||||
)
|
||||
# pylint: disable=unused-import
|
||||
from ansible.module_utils.ansible_ipa_replica import bindinstance # noqa: F401
|
||||
# pylint: enable=unused-import
|
||||
|
||||
|
||||
def main():
|
||||
@@ -164,14 +135,6 @@ def main():
|
||||
choices=['first', 'only'], default=None),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dot_forwarders=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
dns_over_tls=dict(required=False, type='bool', default=False),
|
||||
dns_over_tls_cert=dict(required=False, type='str'),
|
||||
dns_over_tls_key=dict(required=False, type='str'),
|
||||
dns_policy=dict(required=False, type='str',
|
||||
choices=['relaxed', 'enforced'],
|
||||
default='relaxed'),
|
||||
# additional
|
||||
dns_ip_addresses=dict(required=True, type='list', elements='str'),
|
||||
dns_reverse_zones=dict(required=True, type='list', elements='str'),
|
||||
@@ -204,11 +167,6 @@ def main():
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
options.dot_forwarders = ansible_module.params.get('dot_forwarders')
|
||||
options.dns_over_tls = ansible_module.params.get('dns_over_tls')
|
||||
options.dns_over_tls_cert = ansible_module.params.get('dns_over_tls_cert')
|
||||
options.dns_over_tls_key = ansible_module.params.get('dns_over_tls_key')
|
||||
options.dns_policy = ansible_module.params.get('dns_policy')
|
||||
# additional
|
||||
dns.ip_addresses = ansible_module_get_parsed_ip_addresses(
|
||||
ansible_module, 'dns_ip_addresses')
|
||||
|
||||
@@ -181,32 +181,6 @@ options:
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dot_forwarders:
|
||||
description: List of DNS over TLS forwarders
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
required: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dns_over_tls_cert:
|
||||
description:
|
||||
Certificate to use for DNS over TLS. If empty, a new
|
||||
certificate will be requested from IPA CA
|
||||
type: str
|
||||
required: no
|
||||
dns_over_tls_key:
|
||||
description: Key for certificate specified in dns_over_tls_cert
|
||||
type: str
|
||||
required: no
|
||||
dns_policy:
|
||||
description: Encrypted DNS policy
|
||||
type: str
|
||||
choices: ['relaxed', 'enforced']
|
||||
default: 'relaxed'
|
||||
author:
|
||||
- Thomas Woerner (@t-woerner)
|
||||
'''
|
||||
@@ -225,8 +199,7 @@ from ansible.module_utils.ansible_ipa_replica import (
|
||||
paths, sysrestore, ansible_module_get_parsed_ip_addresses, service,
|
||||
redirect_stdout, create_ipa_conf, ipautil,
|
||||
x509, validate_domain_name, common_check,
|
||||
IPA_PYTHON_VERSION, getargspec, adtrustinstance, install_ca_cert,
|
||||
services, CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION
|
||||
IPA_PYTHON_VERSION, getargspec, adtrustinstance, install_ca_cert
|
||||
)
|
||||
|
||||
|
||||
@@ -277,14 +250,6 @@ def main():
|
||||
choices=['first', 'only'], default=None),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dot_forwarders=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
dns_over_tls=dict(required=False, type='bool', default=False),
|
||||
dns_over_tls_cert=dict(required=False, type='str'),
|
||||
dns_over_tls_key=dict(required=False, type='str'),
|
||||
dns_policy=dict(required=False, type='str',
|
||||
choices=['relaxed', 'enforced'],
|
||||
default='relaxed'),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -333,11 +298,6 @@ def main():
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
options.dot_forwarders = ansible_module.params.get('dot_forwarders')
|
||||
options.dns_over_tls = ansible_module.params.get('dns_over_tls')
|
||||
options.dns_over_tls_cert = ansible_module.params.get('dns_over_tls_cert')
|
||||
options.dns_over_tls_key = ansible_module.params.get('dns_over_tls_key')
|
||||
options.dns_policy = ansible_module.params.get('dns_policy')
|
||||
|
||||
##########################################################################
|
||||
# replica init ###########################################################
|
||||
@@ -459,14 +419,6 @@ def main():
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --no-dnssec-validation option "
|
||||
"without the --setup-dns option")
|
||||
if installer.dns_over_tls_cert:
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --dns-over-tls-cert option "
|
||||
"without the --setup-dns option")
|
||||
if installer.dns_over_tls_key:
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --dns-over-tls-key option "
|
||||
"without the --setup-dns option")
|
||||
elif installer.forwarders and installer.no_forwarders:
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --forwarder option together with "
|
||||
@@ -483,31 +435,6 @@ def main():
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --auto-reverse option together with "
|
||||
"--no-reverse")
|
||||
elif installer.dot_forwarders and not installer.dns_over_tls:
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --dot-forwarder option "
|
||||
"without the --dns-over-tls option")
|
||||
elif (installer.dns_over_tls
|
||||
and not services.knownservices["unbound"].is_installed()):
|
||||
ansible_module.fail_json(
|
||||
msg="To enable DNS over TLS, package ipa-server-encrypted-dns "
|
||||
"must be installed.")
|
||||
elif installer.dns_policy == "enforced" and not installer.dns_over_tls:
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --dns-policy option "
|
||||
"without the --dns-over-tls option")
|
||||
elif installer.dns_over_tls_cert and not installer.dns_over_tls:
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --dns-over-tls-cert option "
|
||||
"without the --dns-over-tls option")
|
||||
elif installer.dns_over_tls_key and not installer.dns_over_tls:
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --dns-over-tls-key option "
|
||||
"without the --dns-over-tls option")
|
||||
elif bool(installer.dns_over_tls_key) != bool(installer.dns_over_tls_cert):
|
||||
ansible_module.fail_json(
|
||||
msg="You cannot specify a --dns-over-tls-key option "
|
||||
"without the --dns-over-tls-cert option and vice versa")
|
||||
|
||||
# replica installers
|
||||
if installer.servers and not installer.domain_name:
|
||||
@@ -522,10 +449,6 @@ def main():
|
||||
ansible_module.fail_json(
|
||||
msg="You must specify at least one of --forwarder, "
|
||||
"--auto-forwarders, or --no-forwarders options")
|
||||
if installer.dns_over_tls and not installer.dot_forwarders:
|
||||
ansible_module.fail_json(
|
||||
msg="You must specify --dot-forwarder "
|
||||
"when enabling DNS over TLS")
|
||||
|
||||
if installer.dirsrv_config_file is not None and \
|
||||
not os.path.exists(installer.dirsrv_config_file):
|
||||
@@ -563,11 +486,6 @@ def main():
|
||||
if installer.domain_name is not None:
|
||||
validate_domain_name(installer.domain_name)
|
||||
|
||||
if installer.dns_over_tls and not CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION:
|
||||
ansible_module.fail_json(
|
||||
msg="Important patches for DNS over TLS are missing in your "
|
||||
"IPA version.")
|
||||
|
||||
##########################################################################
|
||||
# replica promote_check excerpts #########################################
|
||||
##########################################################################
|
||||
|
||||
@@ -80,13 +80,6 @@ except ImportError:
|
||||
try:
|
||||
from contextlib import contextmanager as contextlib_contextmanager
|
||||
from ipapython.version import NUM_VERSION, VERSION
|
||||
try:
|
||||
from ipapython.version import parse_version
|
||||
except ImportError:
|
||||
# In IPA we either need pkg_resources or packaging Version
|
||||
# class to compare versions with check_remote_version, so
|
||||
# we let an exception to be raised if neither is available.
|
||||
from pkg_resources import parse_version
|
||||
|
||||
if NUM_VERSION < 30201:
|
||||
# See ipapython/version.py
|
||||
@@ -106,6 +99,8 @@ try:
|
||||
import dns.resolver as dnsresolver
|
||||
import dns.reversename as dnsreversename
|
||||
|
||||
from pkg_resources import parse_version
|
||||
|
||||
from ipaclient.install.ipachangeconf import IPAChangeConf
|
||||
from ipalib.install import certstore, sysrestore
|
||||
from ipapython.ipautil import ipa_generate_password
|
||||
@@ -187,14 +182,6 @@ try:
|
||||
from ipaserver.install import ntpinstance
|
||||
time_service = "ntpd" # pylint: disable=invalid-name
|
||||
|
||||
try:
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION = False
|
||||
from ipaclient.install.client import ClientInstallInterface
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
if hasattr(ClientInstallInterface, "no_dnssec_validation"):
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION = True
|
||||
else:
|
||||
# IPA version < 4.6
|
||||
raise RuntimeError("freeipa version '%s' is too old" % VERSION)
|
||||
@@ -221,13 +208,11 @@ def setup_logging():
|
||||
|
||||
@contextlib_contextmanager
|
||||
def redirect_stdout(stream):
|
||||
old_stdout = sys.stdout
|
||||
|
||||
sys.stdout = stream
|
||||
try:
|
||||
yield stream
|
||||
finally:
|
||||
sys.stdout = old_stdout
|
||||
sys.stdout = sys.__stdout__
|
||||
|
||||
|
||||
class AnsibleModuleLog():
|
||||
@@ -346,7 +331,6 @@ options.add_agents = False
|
||||
# ServerReplicaInstall
|
||||
options.subject_base = None
|
||||
options.ca_subject = None
|
||||
|
||||
# pylint: enable=attribute-defined-outside-init
|
||||
|
||||
|
||||
|
||||
@@ -1,42 +1,32 @@
|
||||
---
|
||||
# tasks file for ipareplica
|
||||
|
||||
- name: Install - Set ipareplica__dns_over_lts
|
||||
ansible.builtin.set_fact:
|
||||
ipareplica__dns_over_tls: "{{ ipareplica_dns_over_tls | default(ipaclient_dns_over_tls) | default(False) }}"
|
||||
|
||||
- name: Install - Package installation
|
||||
- name: Package installation
|
||||
when: ipareplica_install_packages | bool
|
||||
block:
|
||||
|
||||
- name: Install - Set packages for installation
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ ipareplica_packages }}"
|
||||
- name: Install - Ensure IPA replica packages are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipareplica_packages }}"
|
||||
state: present
|
||||
|
||||
- name: Install - Set packages for installlation, add DNS
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipareplica_packages_dns }}"
|
||||
- name: Install - Ensure IPA replica packages for dns are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipareplica_packages_dns }}"
|
||||
state: present
|
||||
when: ipareplica_setup_dns | bool
|
||||
|
||||
- name: Install - Set packages for installlation, add DOT
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipareplica_packages_dot }}"
|
||||
when: ipareplica__dns_over_tls | bool
|
||||
|
||||
- name: Install - Set packages for installlation, add adtrust
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipareplica_packages_adtrust }}"
|
||||
- name: Install - Ensure IPA replica packages for adtrust are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipareplica_packages_adtrust }}"
|
||||
state: present
|
||||
when: ipareplica_setup_adtrust | bool
|
||||
|
||||
- name: Install - Set packages for installlation, add firewalld
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipareplica_packages_firewalld }}"
|
||||
when: ipareplica_setup_firewalld | bool
|
||||
|
||||
- name: Install - Ensure that packages are installed
|
||||
- name: Install - Ensure that firewall packages installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ _ipapackages }}"
|
||||
name: "{{ ipareplica_packages_firewalld }}"
|
||||
state: present
|
||||
when: ipareplica_setup_firewalld | bool
|
||||
|
||||
- name: Firewall configuration
|
||||
when: ipareplica_setup_firewalld | bool
|
||||
@@ -47,21 +37,20 @@
|
||||
enabled: yes
|
||||
state: started
|
||||
|
||||
- name: Firewalld - Verify zones
|
||||
- name: Firewalld - Verify runtime zone "{{ ipareplica_firewalld_zone }}"
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--info-zone="{{ ipareplica_firewalld_zone }}"
|
||||
>/dev/null
|
||||
when: ipareplica_firewalld_zone is defined
|
||||
block:
|
||||
- name: Firewalld - Verify runtime zone from ipareplica_firewalld_zone
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--info-zone="{{ ipareplica_firewalld_zone }}"
|
||||
>/dev/null
|
||||
|
||||
- name: Firewalld - Verify permanent zone from ipareplica_firewalld_zone
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--permanent
|
||||
--info-zone="{{ ipareplica_firewalld_zone }}"
|
||||
>/dev/null
|
||||
- name: Firewalld - Verify permanent zone "{{ ipareplica_firewalld_zone }}"
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--permanent
|
||||
--info-zone="{{ ipareplica_firewalld_zone }}"
|
||||
>/dev/null
|
||||
when: ipareplica_firewalld_zone is defined
|
||||
|
||||
- name: Install - Set ipareplica_servers
|
||||
ansible.builtin.set_fact:
|
||||
@@ -115,11 +104,6 @@
|
||||
auto_forwarders: "{{ ipareplica_auto_forwarders }}"
|
||||
forward_policy: "{{ ipareplica_forward_policy | default(omit) }}"
|
||||
no_dnssec_validation: "{{ ipareplica_no_dnssec_validation }}"
|
||||
dot_forwarders: "{{ ipareplica_dot_forwarders | default([]) }}"
|
||||
dns_over_tls: "{{ ipareplica__dns_over_tls }}"
|
||||
dns_over_tls_cert: "{{ ipareplica_dns_over_tls_cert | default(omit) }}"
|
||||
dns_over_tls_key: "{{ ipareplica_dns_over_tls_key | default(omit) }}"
|
||||
dns_policy: "{{ ipareplica_dns_policy | default(omit) }}"
|
||||
register: result_ipareplica_test
|
||||
|
||||
- name: Install - Deploy replica
|
||||
@@ -143,8 +127,6 @@
|
||||
ipaclient_hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
ipaclient_ip_addresses: "{{ ipareplica_ip_addresses | default(omit) }}"
|
||||
ipaclient_install_packages: "{{ ipareplica_install_packages }}"
|
||||
ipaclient_dns_over_tls: "{{ ipareplica__dns_over_tls }}"
|
||||
ipaclient_no_dnssec_validation: "{{ ipareplica_no_dnssec_validation }}"
|
||||
when: not result_ipareplica_test.client_enrolled
|
||||
|
||||
- name: Install - Configure firewalld
|
||||
@@ -158,8 +140,6 @@
|
||||
{{ "--add-service=freeipa-trust" if result_ipareplica_test.setup_adtrust
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipareplica_setup_dns | bool else "" }}
|
||||
{{ "--add-service=dns-over-tls" if ipareplica__dns_over_tls | bool
|
||||
else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipareplica_setup_firewalld | bool
|
||||
|
||||
@@ -173,8 +153,6 @@
|
||||
{{ "--add-service=freeipa-trust" if result_ipareplica_test.setup_adtrust
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipareplica_setup_dns | bool else "" }}
|
||||
{{ "--add-service=dns-over-tls" if ipareplica__dns_over_tls | bool
|
||||
else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipareplica_setup_firewalld | bool
|
||||
|
||||
@@ -223,11 +201,6 @@
|
||||
auto_forwarders: "{{ ipareplica_auto_forwarders }}"
|
||||
forward_policy: "{{ ipareplica_forward_policy | default(omit) }}"
|
||||
no_dnssec_validation: "{{ ipareplica_no_dnssec_validation }}"
|
||||
dot_forwarders: "{{ ipareplica_dot_forwarders | default([]) }}"
|
||||
dns_over_tls: "{{ ipareplica__dns_over_tls }}"
|
||||
dns_over_tls_cert: "{{ ipareplica_dns_over_tls_cert | default(omit) }}"
|
||||
dns_over_tls_key: "{{ ipareplica_dns_over_tls_key | default(omit) }}"
|
||||
dns_policy: "{{ ipareplica_dns_policy | default(omit) }}"
|
||||
### ad trust ###
|
||||
enable_compat: "{{ ipareplica_enable_compat }}"
|
||||
netbios_name: "{{ ipareplica_netbios_name | default(omit) }}"
|
||||
@@ -744,11 +717,6 @@
|
||||
result_ipareplica_prepare.forward_policy is
|
||||
not none else omit }}"
|
||||
no_dnssec_validation: "{{ ipareplica_no_dnssec_validation }}"
|
||||
dot_forwarders: "{{ ipareplica_dot_forwarders | default([]) }}"
|
||||
dns_over_tls: "{{ ipareplica__dns_over_tls }}"
|
||||
dns_over_tls_cert: "{{ ipareplica_dns_over_tls_cert | default(omit) }}"
|
||||
dns_over_tls_key: "{{ ipareplica_dns_over_tls_key | default(omit) }}"
|
||||
dns_policy: "{{ ipareplica_dns_policy | default(omit) }}"
|
||||
### additional ###
|
||||
dns_ip_addresses: "{{ result_ipareplica_prepare.dns_ip_addresses }}"
|
||||
dns_reverse_zones: "{{ result_ipareplica_prepare.dns_reverse_zones }}"
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipareplica_packages: [ "freeipa-server", "python3-libselinux" ]
|
||||
ipareplica_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipareplica_packages_dot: [ "freeipa-server-encrypted-dns" ]
|
||||
ipareplica_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipareplica_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipareplica_packages: [ "ipa-server", "libselinux-python" ]
|
||||
ipareplica_packages_dns: [ "ipa-server-dns" ]
|
||||
ipareplica_packages_dot: [ ]
|
||||
ipareplica_packages_adtrust: [ "ipa-server-trust-ad" ]
|
||||
ipareplica_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipareplica_packages: [ "@idm:DL1/server" ]
|
||||
ipareplica_packages_dns: [ "@idm:DL1/dns" ]
|
||||
ipareplica_packages_dot: [ ]
|
||||
ipareplica_packages_adtrust: [ "@idm:DL1/adtrust" ]
|
||||
ipareplica_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
---
|
||||
ipareplica_packages: [ "freeipa-server" ]
|
||||
ipareplica_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipareplica_packages_dot: [ ]
|
||||
ipareplica_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipareplica_packages_firewalld: [ "firewalld" ]
|
||||
# Ubuntu Bionic Beaver must use python2 as Python interpreter due
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipareplica_packages: [ "freeipa-server" ]
|
||||
ipareplica_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipareplica_packages_dot: [ ]
|
||||
ipareplica_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipareplica_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -1,8 +1,7 @@
|
||||
# defaults file for ipareplica
|
||||
# vars/default.yml
|
||||
---
|
||||
ipareplica_packages: [ "ipa-server", "python3-libselinux" ]
|
||||
ipareplica_packages_dns: [ "ipa-server-dns" ]
|
||||
ipareplica_packages_dot: [ "ipa-server-encrypted-dns" ]
|
||||
ipareplica_packages_adtrust: [ "ipa-server-trust-ad" ]
|
||||
ipareplica_packages: [ "freeipa-server", "python3-libselinux" ]
|
||||
ipareplica_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipareplica_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipareplica_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -343,12 +343,6 @@ Variable | Description | Required
|
||||
`ipaserver_auto_forwarders` | Add DNS forwarders configured in /etc/resolv.conf to the list of forwarders used by IPA DNS. (bool, default: false) | no
|
||||
`ipaserver_forward_policy` | DNS forwarding policy for global forwarders specified using other options. (choice: first, only) | no
|
||||
`ipaserver_no_dnssec_validation` | Disable DNSSEC validation on this server. (bool, default: false) | no
|
||||
`ipaserver_dot_forwarders` | List of DNS over TLS forwarders. Required if `ipaserver_dns_over_tls` is enabled. (list of strings) | no
|
||||
`ipaserver_dns_over_tls` \| `ipaclient_dns_over_tls` | Configure DNS over TLS. Requires FreeIPA version 4.12.5 or later. (bool, default: false) | no
|
||||
`ipaserver_dns_over_tls_cert` | Certificate to use for DNS over TLS. If empty, a new certificate will be requested from IPA CA. (string) | no
|
||||
`ipaserver_dns_over_tls_key` | Key for certificate specified in `ipaserver_dns_over_tls_cert`. (string) | no
|
||||
`ipaserver_dns_policy` | Encrypted DNS policy. Only usable if `ipaserver_dns_over_tls` is enabled. (choice: relaxed, enforced, default: relaxed) | no
|
||||
|
||||
|
||||
AD trust Variables
|
||||
------------------
|
||||
|
||||
@@ -174,32 +174,6 @@ options:
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dot_forwarders:
|
||||
description: List of DNS over TLS forwarders
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
required: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dns_over_tls_cert:
|
||||
description:
|
||||
Certificate to use for DNS over TLS. If empty, a new
|
||||
certificate will be requested from IPA CA
|
||||
type: str
|
||||
required: no
|
||||
dns_over_tls_key:
|
||||
description: Key for certificate specified in dns_over_tls_cert
|
||||
type: str
|
||||
required: no
|
||||
dns_policy:
|
||||
description: Encrypted DNS policy
|
||||
type: str
|
||||
choices: ['relaxed', 'enforced']
|
||||
default: 'relaxed'
|
||||
enable_compat:
|
||||
description: Enable support for trusted domains for old clients
|
||||
type: bool
|
||||
@@ -306,15 +280,6 @@ def main():
|
||||
choices=['first', 'only'], default=None),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dot_forwarders=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
dns_over_tls=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dns_over_tls_cert=dict(required=False, type='str'),
|
||||
dns_over_tls_key=dict(required=False, type='str'),
|
||||
dns_policy=dict(required=False, type='str',
|
||||
choices=['relaxed', 'enforced'],
|
||||
default='relaxed'),
|
||||
# ad trust
|
||||
enable_compat=dict(required=False, type='bool', default=False),
|
||||
netbios_name=dict(required=False, type='str'),
|
||||
@@ -395,11 +360,6 @@ def main():
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
options.dot_forwarders = ansible_module.params.get('dot_forwarders')
|
||||
options.dns_over_tls = ansible_module.params.get('dns_over_tls')
|
||||
options.dns_over_tls_cert = ansible_module.params.get('dns_over_tls_cert')
|
||||
options.dns_over_tls_key = ansible_module.params.get('dns_over_tls_key')
|
||||
options.dns_policy = ansible_module.params.get('dns_policy')
|
||||
# ad trust
|
||||
options.enable_compat = ansible_module.params.get('enable_compat')
|
||||
options.netbios_name = ansible_module.params.get('netbios_name')
|
||||
|
||||
@@ -83,32 +83,6 @@ options:
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dot_forwarders:
|
||||
description: List of DNS over TLS forwarders
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
required: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dns_over_tls_cert:
|
||||
description:
|
||||
Certificate to use for DNS over TLS. If empty, a new
|
||||
certificate will be requested from IPA CA
|
||||
type: str
|
||||
required: no
|
||||
dns_over_tls_key:
|
||||
description: Key for certificate specified in dns_over_tls_cert
|
||||
type: str
|
||||
required: no
|
||||
dns_policy:
|
||||
description: Encrypted DNS policy
|
||||
type: str
|
||||
choices: ['relaxed', 'enforced']
|
||||
default: 'relaxed'
|
||||
dns_ip_addresses:
|
||||
description: The dns ip_addresses setting
|
||||
type: list
|
||||
@@ -133,13 +107,9 @@ from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils.ansible_ipa_server import (
|
||||
check_imports, AnsibleModuleLog, setup_logging, options, paths, dns,
|
||||
ansible_module_get_parsed_ip_addresses, sysrestore, api_Backend_ldap2,
|
||||
redirect_stdout
|
||||
redirect_stdout, bindinstance
|
||||
)
|
||||
|
||||
# pylint: disable=unused-import
|
||||
from ansible.module_utils.ansible_ipa_server import bindinstance # noqa: F401
|
||||
# pylint: enable=unused-import
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
@@ -160,14 +130,6 @@ def main():
|
||||
default='first'),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dot_forwarders=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
dns_over_tls=dict(required=False, type='bool', default=False),
|
||||
dns_over_tls_cert=dict(required=False, type='str'),
|
||||
dns_over_tls_key=dict(required=False, type='str'),
|
||||
dns_policy=dict(required=False, type='str',
|
||||
choices=['relaxed', 'enforced'],
|
||||
default='relaxed'),
|
||||
# additional
|
||||
dns_ip_addresses=dict(required=True, type='list', elements='str'),
|
||||
dns_reverse_zones=dict(required=True, type='list', elements='str'),
|
||||
@@ -196,11 +158,6 @@ def main():
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
options.dot_forwarders = ansible_module.params.get('dot_forwarders')
|
||||
options.dns_over_tls = ansible_module.params.get('dns_over_tls')
|
||||
options.dns_over_tls_cert = ansible_module.params.get('dns_over_tls_cert')
|
||||
options.dns_over_tls_key = ansible_module.params.get('dns_over_tls_key')
|
||||
options.dns_policy = ansible_module.params.get('dns_policy')
|
||||
# additional
|
||||
dns.ip_addresses = ansible_module_get_parsed_ip_addresses(
|
||||
ansible_module, 'dns_ip_addresses')
|
||||
@@ -208,16 +165,25 @@ def main():
|
||||
|
||||
# init ##################################################################
|
||||
|
||||
# pylint: disable=unused-variable
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE) # noqa: F841
|
||||
# pylint: enable=unused-variable
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
|
||||
api_Backend_ldap2(options.host_name, options.setup_ca, connect=True)
|
||||
|
||||
# setup dns #############################################################
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
dns.install(False, False, options)
|
||||
if options.setup_dns:
|
||||
dns.install(False, False, options)
|
||||
else:
|
||||
# Create a BIND instance
|
||||
bind = bindinstance.BindInstance(fstore)
|
||||
bind.set_output(ansible_log)
|
||||
bind.setup(options.host_name, options.ip_addresses,
|
||||
options.realm_name,
|
||||
options.domain_name, (), 'first', (),
|
||||
zonemgr=options.zonemgr,
|
||||
no_dnssec_validation=options.no_dnssec_validation)
|
||||
bind.create_file_with_system_records()
|
||||
|
||||
# done ##################################################################
|
||||
|
||||
|
||||
@@ -265,32 +265,6 @@ options:
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dot_forwarders:
|
||||
description: List of DNS over TLS forwarders
|
||||
type: list
|
||||
elements: str
|
||||
default: []
|
||||
required: no
|
||||
dns_over_tls:
|
||||
description: Configure DNS over TLS
|
||||
type: bool
|
||||
default: no
|
||||
required: no
|
||||
dns_over_tls_cert:
|
||||
description:
|
||||
Certificate to use for DNS over TLS. If empty, a new
|
||||
certificate will be requested from IPA CA
|
||||
type: str
|
||||
required: no
|
||||
dns_over_tls_key:
|
||||
description: Key for certificate specified in dns_over_tls_cert
|
||||
type: str
|
||||
required: no
|
||||
dns_policy:
|
||||
description: Encrypted DNS policy
|
||||
type: str
|
||||
choices: ['relaxed', 'enforced']
|
||||
default: 'relaxed'
|
||||
enable_compat:
|
||||
description: Enable support for trusted domains for old clients
|
||||
type: bool
|
||||
@@ -338,8 +312,7 @@ from ansible.module_utils.ansible_ipa_server import (
|
||||
check_dirsrv, ScriptError, get_fqdn, verify_fqdn, BadHostError,
|
||||
validate_domain_name, load_pkcs12, IPA_PYTHON_VERSION,
|
||||
encode_certificate, check_available_memory, getargspec, adtrustinstance,
|
||||
get_min_idstart, SerialNumber, services, service,
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION
|
||||
get_min_idstart, SerialNumber
|
||||
)
|
||||
from ansible.module_utils import six
|
||||
|
||||
@@ -423,14 +396,6 @@ def main():
|
||||
choices=['first', 'only'], default=None),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
dot_forwarders=dict(required=False, type='list', elements='str',
|
||||
default=[]),
|
||||
dns_over_tls=dict(required=False, type='bool', default=False),
|
||||
dns_over_tls_cert=dict(required=False, type='str'),
|
||||
dns_over_tls_key=dict(required=False, type='str'),
|
||||
dns_policy=dict(required=False, type='str',
|
||||
choices=['relaxed', 'enforced'],
|
||||
default='relaxed'),
|
||||
# ad trust
|
||||
enable_compat=dict(required=False, type='bool', default=False),
|
||||
netbios_name=dict(required=False, type='str'),
|
||||
@@ -517,11 +482,6 @@ def main():
|
||||
options.forward_policy = ansible_module.params.get('forward_policy')
|
||||
options.no_dnssec_validation = ansible_module.params.get(
|
||||
'no_dnssec_validation')
|
||||
options.dot_forwarders = ansible_module.params.get('dot_forwarders')
|
||||
options.dns_over_tls = ansible_module.params.get('dns_over_tls')
|
||||
options.dns_over_tls_cert = ansible_module.params.get('dns_over_tls_cert')
|
||||
options.dns_over_tls_key = ansible_module.params.get('dns_over_tls_key')
|
||||
options.dns_policy = ansible_module.params.get('dns_policy')
|
||||
# ad trust
|
||||
options.enable_compat = ansible_module.params.get('enable_compat')
|
||||
options.netbios_name = ansible_module.params.get('netbios_name')
|
||||
@@ -643,14 +603,6 @@ def main():
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --no-dnssec-validation option "
|
||||
"without the --setup-dns option")
|
||||
if self.dns_over_tls_cert:
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --dns-over-tls-cert option "
|
||||
"without the --setup-dns option")
|
||||
if self.dns_over_tls_key:
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --dns-over-tls-key option "
|
||||
"without the --setup-dns option")
|
||||
elif self.forwarders and self.no_forwarders:
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --forwarder option together with "
|
||||
@@ -667,31 +619,7 @@ def main():
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --auto-reverse option together with "
|
||||
"--no-reverse")
|
||||
elif self.dot_forwarders and not self.dns_over_tls:
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --dot-forwarder option "
|
||||
"without the --dns-over-tls option")
|
||||
elif (self.dns_over_tls
|
||||
and not services.knownservices["unbound"].is_installed()):
|
||||
raise RuntimeError(
|
||||
"To enable DNS over TLS, package ipa-server-encrypted-dns "
|
||||
"must be installed.")
|
||||
elif self.dns_policy == "enforced" and not self.dns_over_tls:
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --dns-policy option "
|
||||
"without the --dns-over-tls option")
|
||||
elif self.dns_over_tls_cert and not self.dns_over_tls:
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --dns-over-tls-cert option "
|
||||
"without the --dns-over-tls option")
|
||||
elif self.dns_over_tls_key and not self.dns_over_tls:
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --dns-over-tls-key option "
|
||||
"without the --dns-over-tls option")
|
||||
elif bool(self.dns_over_tls_key) != bool(self.dns_over_tls_cert):
|
||||
raise RuntimeError(
|
||||
"You cannot specify a --dns-over-tls-key option "
|
||||
"without the --dns-over-tls-cert option and vice versa")
|
||||
|
||||
if not self.setup_adtrust:
|
||||
if self.add_agents:
|
||||
raise RuntimeError(
|
||||
@@ -749,10 +677,6 @@ def main():
|
||||
raise RuntimeError(
|
||||
"You must specify at least one of --forwarder, "
|
||||
"--auto-forwarders, or --no-forwarders options")
|
||||
if self.dns_over_tls and not self.dot_forwarders:
|
||||
raise RuntimeError(
|
||||
"You must specify --dot-forwarder "
|
||||
"when enabling DNS over TLS")
|
||||
|
||||
any_ignore_option_true = any(
|
||||
[self.ignore_topology_disconnect, self.ignore_last_of_role])
|
||||
@@ -795,19 +719,6 @@ def main():
|
||||
|
||||
# #######################################################################
|
||||
|
||||
if options.dns_over_tls and not CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION:
|
||||
ansible_module.fail_json(
|
||||
msg="Important patches for DNS over TLS are missing in your "
|
||||
"IPA version.")
|
||||
|
||||
client_dns_over_tls = self.dns_over_tls
|
||||
if self.dns_over_tls and not self.setup_dns:
|
||||
service.print_msg("Warning: --dns-over-tls option "
|
||||
"specified without --setup-dns, ignoring")
|
||||
client_dns_over_tls = False
|
||||
|
||||
# #######################################################################
|
||||
|
||||
# If any of the key file options are selected, all are required.
|
||||
cert_file_req = (options.dirsrv_cert_files, options.http_cert_files)
|
||||
cert_file_opt = (options.pkinit_cert_files,)
|
||||
@@ -1297,7 +1208,6 @@ def main():
|
||||
domainlevel=options.domainlevel,
|
||||
sid_generation_always=sid_generation_always,
|
||||
random_serial_numbers=options._random_serial_numbers,
|
||||
client_dns_over_tls=client_dns_over_tls
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -216,14 +216,6 @@ try:
|
||||
except ImportError:
|
||||
SerialNumber = None
|
||||
|
||||
try:
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION = False
|
||||
from ipaclient.install.client import ClientInstallInterface
|
||||
except ImportError:
|
||||
pass
|
||||
else:
|
||||
if hasattr(ClientInstallInterface, "no_dnssec_validation"):
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION = True
|
||||
else:
|
||||
# IPA version < 4.5
|
||||
raise RuntimeError("freeipa version '%s' is too old" % VERSION)
|
||||
@@ -249,13 +241,11 @@ def setup_logging():
|
||||
|
||||
@contextlib_contextmanager
|
||||
def redirect_stdout(stream):
|
||||
old_stdout = sys.stdout
|
||||
|
||||
sys.stdout = stream
|
||||
try:
|
||||
yield stream
|
||||
finally:
|
||||
sys.stdout = old_stdout
|
||||
sys.stdout = sys.__stdout__
|
||||
|
||||
|
||||
class AnsibleModuleLog():
|
||||
|
||||
@@ -1,42 +1,32 @@
|
||||
---
|
||||
# tasks file for ipaserver
|
||||
|
||||
- name: Install - Set ipaserver__dns_over_lts
|
||||
ansible.builtin.set_fact:
|
||||
ipaserver__dns_over_tls: "{{ ipaserver_dns_over_tls | default(ipaclient_dns_over_tls) | default(False) }}"
|
||||
|
||||
- name: Install - Package installation
|
||||
when: ipaserver_install_packages | bool
|
||||
block:
|
||||
- name: Install - Ensure that IPA server packages are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipaserver_packages }}"
|
||||
state: present
|
||||
|
||||
- name: Install - Set packages for installation
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ ipaserver_packages }}"
|
||||
|
||||
- name: Install - Set packages for installlation, add DNS
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipaserver_packages_dns }}"
|
||||
- name: Install - Ensure that IPA server packages for dns are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipaserver_packages_dns }}"
|
||||
state: present
|
||||
when: ipaserver_setup_dns | bool
|
||||
|
||||
- name: Install - Set packages for installlation, add DOT
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipaserver_packages_dot }}"
|
||||
when: ipaserver__dns_over_tls | bool
|
||||
|
||||
- name: Install - Set packages for installlation, add adtrust
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipaserver_packages_adtrust }}"
|
||||
- name: Install - Ensure that IPA server packages for adtrust are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipaserver_packages_adtrust }}"
|
||||
state: present
|
||||
when: ipaserver_setup_adtrust | bool
|
||||
|
||||
- name: Install - Set packages for installlation, add firewalld
|
||||
ansible.builtin.set_fact:
|
||||
_ipapackages: "{{ _ipapackages + ipaserver_packages_firewalld }}"
|
||||
- name: Install - Ensure that firewall packages installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ ipaserver_packages_firewalld }}"
|
||||
state: present
|
||||
when: ipaserver_setup_firewalld | bool
|
||||
|
||||
- name: Install - Ensure that packages are installed
|
||||
ansible.builtin.package:
|
||||
name: "{{ _ipapackages }}"
|
||||
state: present
|
||||
|
||||
- name: Install - Firewall configuration
|
||||
when: ipaserver_setup_firewalld | bool
|
||||
@@ -47,21 +37,20 @@
|
||||
enabled: yes
|
||||
state: started
|
||||
|
||||
- name: Firewalld - verify zones
|
||||
- name: Firewalld - Verify runtime zone "{{ ipaserver_firewalld_zone }}"
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--info-zone="{{ ipaserver_firewalld_zone }}"
|
||||
>/dev/null
|
||||
when: ipaserver_firewalld_zone is defined
|
||||
block:
|
||||
- name: Firewalld - Verify runtime zone from ipaserver_firewalld_zone
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--info-zone="{{ ipaserver_firewalld_zone }}"
|
||||
>/dev/null
|
||||
|
||||
- name: Firewalld - Verify permanent zone from ipaserver_firewalld_zone
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--permanent
|
||||
--info-zone="{{ ipaserver_firewalld_zone }}"
|
||||
>/dev/null
|
||||
- name: Firewalld - Verify permanent zone "{{ ipaserver_firewalld_zone }}"
|
||||
ansible.builtin.shell: >
|
||||
firewall-cmd
|
||||
--permanent
|
||||
--info-zone="{{ ipaserver_firewalld_zone }}"
|
||||
>/dev/null
|
||||
when: ipaserver_firewalld_zone is defined
|
||||
|
||||
- name: Copy external certs
|
||||
ansible.builtin.include_tasks: "{{ role_path }}/tasks/copy_external_cert.yml"
|
||||
@@ -132,11 +121,6 @@
|
||||
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
forward_policy: "{{ ipaserver_forward_policy | default(omit) }}"
|
||||
no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}"
|
||||
dot_forwarders: "{{ ipaserver_dot_forwarders | default([]) }}"
|
||||
dns_over_tls: "{{ ipaserver__dns_over_tls }}"
|
||||
dns_over_tls_cert: "{{ ipaserver_dns_over_tls_cert | default(omit) }}"
|
||||
dns_over_tls_key: "{{ ipaserver_dns_over_tls_key | default(omit) }}"
|
||||
dns_policy: "{{ ipaserver_dns_policy | default(omit) }}"
|
||||
### ad trust ###
|
||||
enable_compat: "{{ ipaserver_enable_compat }}"
|
||||
netbios_name: "{{ ipaserver_netbios_name | default(omit) }}"
|
||||
@@ -208,11 +192,6 @@
|
||||
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
forward_policy: "{{ ipaserver_forward_policy | default(omit) }}"
|
||||
no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}"
|
||||
dot_forwarders: "{{ ipaserver_dot_forwarders | default([]) }}"
|
||||
dns_over_tls: "{{ ipaserver__dns_over_tls }}"
|
||||
dns_over_tls_cert: "{{ ipaserver_dns_over_tls_cert | default(omit) }}"
|
||||
dns_over_tls_key: "{{ ipaserver_dns_over_tls_key | default(omit) }}"
|
||||
dns_policy: "{{ ipaserver_dns_policy | default(omit) }}"
|
||||
### ad trust ###
|
||||
enable_compat: "{{ ipaserver_enable_compat }}"
|
||||
netbios_name: "{{ ipaserver_netbios_name | default(omit) }}"
|
||||
@@ -402,11 +381,6 @@
|
||||
forward_policy: "{{ result_ipaserver_prepare.forward_policy }}"
|
||||
zonemgr: "{{ ipaserver_zonemgr | default(omit) }}"
|
||||
no_dnssec_validation: "{{ result_ipaserver_prepare.no_dnssec_validation }}"
|
||||
dot_forwarders: "{{ ipaserver_dot_forwarders | default([]) }}"
|
||||
dns_over_tls: "{{ ipaserver__dns_over_tls }}"
|
||||
dns_over_tls_cert: "{{ ipaserver_dns_over_tls_cert | default(omit) }}"
|
||||
dns_over_tls_key: "{{ ipaserver_dns_over_tls_key | default(omit) }}"
|
||||
dns_policy: "{{ ipaserver_dns_policy | default(omit) }}"
|
||||
### additional ###
|
||||
dns_ip_addresses: "{{ result_ipaserver_prepare.dns_ip_addresses }}"
|
||||
dns_reverse_zones: "{{ result_ipaserver_prepare.dns_reverse_zones }}"
|
||||
@@ -458,7 +432,6 @@
|
||||
ipaclient_no_ntp:
|
||||
"{{ 'true' if result_ipaserver_test.ipa_python_version >= 40690
|
||||
else 'false' }}"
|
||||
ipaclient_dns_over_tls: "{{ result_ipaserver_test.client_dns_over_tls }}"
|
||||
ipaclient_install_packages: no
|
||||
|
||||
- name: Install - Enable IPA
|
||||
@@ -479,8 +452,6 @@
|
||||
{{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }}
|
||||
{{ "--add-service=dns-over-tls" if ipaserver__dns_over_tls | bool
|
||||
else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipaserver_setup_firewalld | bool
|
||||
|
||||
@@ -494,8 +465,6 @@
|
||||
{{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }}
|
||||
{{ "--add-service=dns-over-tls" if ipaserver__dns_over_tls | bool
|
||||
else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipaserver_setup_firewalld | bool
|
||||
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipaserver_packages: [ "freeipa-server", "python3-libselinux" ]
|
||||
ipaserver_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipaserver_packages_dot: [ "freeipa-server-encrypted-dns" ]
|
||||
ipaserver_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipaserver_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipaserver_packages: [ "ipa-server", "libselinux-python" ]
|
||||
ipaserver_packages_dns: [ "ipa-server-dns" ]
|
||||
ipaserver_packages_dot: [ ]
|
||||
ipaserver_packages_adtrust: [ "ipa-server-trust-ad" ]
|
||||
ipaserver_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipaserver_packages: [ "@idm:DL1/server" ]
|
||||
ipaserver_packages_dns: [ "@idm:DL1/dns" ]
|
||||
ipaserver_packages_dot: [ ]
|
||||
ipaserver_packages_adtrust: [ "@idm:DL1/adtrust" ]
|
||||
ipaserver_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -2,7 +2,6 @@
|
||||
---
|
||||
ipaserver_packages: [ "freeipa-server" ]
|
||||
ipaserver_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipaserver_packages_dot: [ ]
|
||||
ipaserver_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipaserver_packages_firewalld: [ "firewalld" ]
|
||||
# Ubuntu Bionic Beaver must use python2 as Python interpreter due
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipaserver_packages: [ "freeipa-server" ]
|
||||
ipaserver_packages_dns: [ "freeipa-server-dns" ]
|
||||
ipaserver_packages_dot: [ ]
|
||||
ipaserver_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipaserver_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -3,6 +3,5 @@
|
||||
---
|
||||
ipaserver_packages: [ "ipa-server", "python3-libselinux" ]
|
||||
ipaserver_packages_dns: [ "ipa-server-dns" ]
|
||||
ipaserver_packages_dot: [ "ipa-server-encrypted-dns" ]
|
||||
ipaserver_packages_adtrust: [ "freeipa-server-trust-ad" ]
|
||||
ipaserver_packages_firewalld: [ "firewalld" ]
|
||||
|
||||
@@ -61,12 +61,7 @@ good-names =
|
||||
dt, ca,
|
||||
# These are utils tools, and not part of the released collection.
|
||||
galaxyfy-playbook, galaxyfy-README, galaxyfy-module-EXAMPLES,
|
||||
module_EXAMPLES,
|
||||
MODULE_IMPORT_ERROR, ANSIBLE_IPA_CLIENT_MODULE_IMPORT_ERROR,
|
||||
CLIENT_SUPPORTS_NO_DNSSEC_VALIDATION, ANSIBLE_IPA_REPLICA_MODULE_IMPORT_ERROR,
|
||||
SYSTEMD_RESOLVED_IPA_CONF, ANSIBLE_IPA_SERVER_MODULE_IMPORT_ERROR,
|
||||
NETWORK_MANAGER_IPA_CONF, ANSIBLE_FREEIPA_MODULE_IMPORT_ERROR,
|
||||
FIX_6741_DEEPCOPY_OBJECTCLASSES
|
||||
module_EXAMPLES
|
||||
|
||||
|
||||
[pylint.IMPORTS]
|
||||
|
||||
@@ -66,7 +66,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: result
|
||||
failed_when: result.files | length == 0
|
||||
failed_when: not result.files
|
||||
|
||||
# Test backup and copy to controller, don't keep copy on server
|
||||
- name: Remove all backup from server.
|
||||
@@ -108,7 +108,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length > 0
|
||||
failed_when: backups.files
|
||||
|
||||
- name: Verify backup on controller.
|
||||
ansible.builtin.find:
|
||||
@@ -116,7 +116,7 @@
|
||||
pattern: "{{ ansible_facts.fqdn }}*"
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length == 0
|
||||
failed_when: not backups.files
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
@@ -161,7 +161,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: result
|
||||
failed_when: result.files | length == 0
|
||||
failed_when: not result.files
|
||||
|
||||
- name: Verify backup on controller.
|
||||
ansible.builtin.find:
|
||||
@@ -169,7 +169,7 @@
|
||||
pattern: "{{ ansible_facts.fqdn }}*"
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length == 0
|
||||
failed_when: not backups.files
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
@@ -214,7 +214,7 @@
|
||||
pattern: "{{ ansible_facts.fqdn }}*"
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length == 0
|
||||
failed_when: not backups.files
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
@@ -232,7 +232,7 @@
|
||||
pattern: "{{ ansible_facts.fqdn }}*"
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length == 0
|
||||
failed_when: not backups.files
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
@@ -252,7 +252,7 @@
|
||||
path: /var/lib/ipa/backup
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length == 0
|
||||
failed_when: not backups.files
|
||||
|
||||
# Copy backup from server to controller
|
||||
- name: List all existing backups on controller
|
||||
@@ -280,7 +280,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: server_backups
|
||||
failed_when: server_backups.files | length == 0
|
||||
failed_when: not server_backups.files
|
||||
|
||||
- name: Copy backup from server to controller.
|
||||
ansible.builtin.include_role:
|
||||
@@ -300,7 +300,7 @@
|
||||
pattern: "{{ ansible_facts.fqdn }}*"
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length == 0
|
||||
failed_when: not backups.files
|
||||
delegate_to: localhost
|
||||
become: no
|
||||
|
||||
@@ -311,7 +311,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length == 0
|
||||
failed_when: not backups.files
|
||||
|
||||
- name: Remov all backup from server.
|
||||
ansible.builtin.include_role:
|
||||
@@ -326,7 +326,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length > 0
|
||||
failed_when: backups.files
|
||||
|
||||
# Remove all backups from server
|
||||
- name: Create a backup on the server
|
||||
@@ -348,7 +348,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: backups
|
||||
failed_when: backups.files | length > 0
|
||||
failed_when: backups.files
|
||||
|
||||
# Remove all backup from server
|
||||
- name: Remove all backup from server.
|
||||
@@ -370,7 +370,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: server_backups
|
||||
failed_when: server_backups.files | length == 0
|
||||
failed_when: not server_backups.files
|
||||
|
||||
- name: Remove backup from server.
|
||||
ansible.builtin.include_role:
|
||||
@@ -406,7 +406,7 @@
|
||||
recurse: no
|
||||
file_type: directory
|
||||
register: server_backups
|
||||
failed_when: server_backups.files | length > 0
|
||||
failed_when: server_backups.files
|
||||
|
||||
# CLEANUP
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@
|
||||
reason: 9
|
||||
state: revoked
|
||||
register: result
|
||||
failed_when: not (result.failed and ("Request failed with status 404" in result.msg or result.msg is regex("Certificate [^0]*0x123456789 not found")))
|
||||
failed_when: not (result.failed and ("Request failed with status 404" in result.msg or "Certificate serial number 0x123456789 not found" in result.msg))
|
||||
|
||||
- name: Try to release revoked certificate
|
||||
ipacert:
|
||||
@@ -140,7 +140,7 @@
|
||||
certificate_out: "/root/cert_1.pem"
|
||||
state: requested
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed or result.certificate != {}
|
||||
failed_when: not result.changed or result.failed or result.certificate
|
||||
|
||||
- name: Check requested certificate file
|
||||
ansible.builtin.file:
|
||||
@@ -155,7 +155,7 @@
|
||||
certificate_out: "/root/retrieved.pem"
|
||||
state: retrieved
|
||||
register: result
|
||||
failed_when: result.changed or result.failed or result.certificate != {}
|
||||
failed_when: result.changed or result.failed or result.certificate
|
||||
|
||||
- name: Check retrieved certificate file
|
||||
ansible.builtin.file:
|
||||
@@ -194,7 +194,7 @@
|
||||
profile: invalid_profile
|
||||
state: requested
|
||||
register: result
|
||||
failed_when: not (result.failed and ("Request failed with status 400" in result.msg or "Profile not found" in result.msg))
|
||||
failed_when: not (result.failed and "Request failed with status 400" in result.msg)
|
||||
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
@@ -136,7 +136,7 @@
|
||||
reason: 9
|
||||
state: revoked
|
||||
register: result
|
||||
failed_when: not (result.failed and ("Request failed with status 404" in result.msg or result.msg is regex("Certificate [^0]*0x123456789 not found")))
|
||||
failed_when: not (result.failed and ("Request failed with status 404" in result.msg or "Certificate serial number 0x123456789 not found" in result.msg))
|
||||
|
||||
- name: Try to release revoked certificate
|
||||
ipacert:
|
||||
@@ -153,7 +153,7 @@
|
||||
certificate_out: "/root/cert_1.pem"
|
||||
state: requested
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed or result.certificate != {}
|
||||
failed_when: not result.changed or result.failed or result.certificate
|
||||
|
||||
- name: Check requested certificate file
|
||||
ansible.builtin.file:
|
||||
@@ -168,7 +168,7 @@
|
||||
certificate_out: "/root/retrieved.pem"
|
||||
state: retrieved
|
||||
register: result
|
||||
failed_when: result.changed or result.failed or result.certificate != {}
|
||||
failed_when: result.changed or result.failed or result.certificate
|
||||
|
||||
- name: Check retrieved certificate file
|
||||
ansible.builtin.file:
|
||||
@@ -207,7 +207,7 @@
|
||||
profile: invalid_profile
|
||||
state: requested
|
||||
register: result
|
||||
failed_when: not (result.failed and ("Request failed with status 400" in result.msg or "Profile not found" in result.msg))
|
||||
failed_when: not (result.failed and "Request failed with status 400" in result.msg)
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
|
||||
@@ -123,7 +123,7 @@
|
||||
reason: 9
|
||||
state: revoked
|
||||
register: result
|
||||
failed_when: not (result.failed and ("Request failed with status 404" in result.msg or result.msg is regex("Certificate [^0]*0x123456789 not found")))
|
||||
failed_when: not (result.failed and ("Request failed with status 404" in result.msg or "Certificate serial number 0x123456789 not found" in result.msg))
|
||||
|
||||
- name: Try to release revoked certificate
|
||||
ipacert:
|
||||
@@ -140,7 +140,7 @@
|
||||
certificate_out: "/root/cert_1.pem"
|
||||
state: requested
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed or result.certificate != {}
|
||||
failed_when: not result.changed or result.failed or result.certificate
|
||||
|
||||
- name: Check requested certificate file
|
||||
ansible.builtin.file:
|
||||
@@ -155,7 +155,7 @@
|
||||
certificate_out: "/root/retrieved.pem"
|
||||
state: retrieved
|
||||
register: result
|
||||
failed_when: result.changed or result.failed or result.certificate != {}
|
||||
failed_when: result.changed or result.failed or result.certificate
|
||||
|
||||
- name: Check retrieved certificate file
|
||||
ansible.builtin.file:
|
||||
@@ -194,7 +194,7 @@
|
||||
profile: invalid_profile
|
||||
state: requested
|
||||
register: result
|
||||
failed_when: not (result.failed and ("Request failed with status 400" in result.msg or "Profile not found" in result.msg))
|
||||
failed_when: not (result.failed and "Request failed with status 400" in result.msg)
|
||||
|
||||
# CLEANUP TEST ITEMS
|
||||
|
||||
|
||||
@@ -34,6 +34,16 @@
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
emaildomain: ipa.test
|
||||
|
||||
- name: Ensure the default e-mail domain cannot be set to an invalid email domain.
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
emaildomain: invalid@emaildomain
|
||||
register: invalid_emaildomain
|
||||
failed_when:
|
||||
invalid_emaildomain.changed
|
||||
or not (invalid_emaildomain.failed and "Invalid 'emaildomain' value:" in invalid_emaildomain.msg)
|
||||
|
||||
- name: Set default shell to '/bin/sh'
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -400,7 +410,7 @@
|
||||
searchrecordslimit: '{{ previousconfig.config.searchrecordslimit | default(100) | int }}'
|
||||
usersearch: '{{ previousconfig.config.usersearch | default(omit) }}'
|
||||
groupsearch: '{{ previousconfig.config.groupsearch | default(omit) }}'
|
||||
enable_migration: '{{ omit if previousconfig.config.enable_migration is not defined else (previousconfig.config.enable_migration | bool) }}'
|
||||
enable_migration: '{{ previousconfig.config.enable_migration | default(False) | bool }}'
|
||||
groupobjectclasses: '{{ previousconfig.config.groupobjectclasses | default(omit) }}'
|
||||
userobjectclasses: '{{ previousconfig.config.userobjectclasses | default(omit) }}'
|
||||
pwdexpnotify: '{{ previousconfig.config.pwdexpnotify | default(4) | int }}'
|
||||
@@ -436,7 +446,7 @@
|
||||
searchrecordslimit: '{{ previousconfig.config.searchrecordslimit | default(omit) | int }}'
|
||||
usersearch: '{{ previousconfig.config.usersearch | default(omit) }}'
|
||||
groupsearch: '{{ previousconfig.config.groupsearch | default(omit) }}'
|
||||
enable_migration: '{{ omit if previousconfig.config.enable_migration is not defined else (previousconfig.config.enable_migration | bool) }}'
|
||||
enable_migration: '{{ previousconfig.config.enable_migration | default(omit) | bool }}'
|
||||
groupobjectclasses: '{{ previousconfig.config.groupobjectclasses | default(omit) }}'
|
||||
userobjectclasses: '{{ previousconfig.config.userobjectclasses | default(omit) }}'
|
||||
pwdexpnotify: '{{ previousconfig.config.pwdexpnotify | default(omit) | int }}'
|
||||
@@ -473,7 +483,7 @@
|
||||
searchrecordslimit: '{{ previousconfig.config.searchrecordslimit | default(omit) | int }}'
|
||||
usersearch: '{{ previousconfig.config.usersearch | default(omit) }}'
|
||||
groupsearch: '{{ previousconfig.config.groupsearch | default(omit) }}'
|
||||
enable_migration: '{{ omit if previousconfig.config.enable_migration is not defined else (previousconfig.config.enable_migration | bool) }}'
|
||||
enable_migration: '{{ previousconfig.config.enable_migration | default(omit) | bool }}'
|
||||
groupobjectclasses: '{{ previousconfig.config.groupobjectclasses | default(omit) }}'
|
||||
userobjectclasses: '{{ previousconfig.config.userobjectclasses | default(omit) }}'
|
||||
pwdexpnotify: '{{ previousconfig.config.pwdexpnotify | default(omit) | int }}'
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
gather_facts: no
|
||||
|
||||
tasks:
|
||||
- name: Include tasks ../env_freeipa_facts.yml
|
||||
ansible.builtin.include_tasks: ../env_freeipa_facts.yml
|
||||
|
||||
# GET CURRENT CONFIG
|
||||
|
||||
@@ -82,36 +80,6 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure config with user_auth_type passkey
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
user_auth_type:
|
||||
- passkey
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
when: passkey_is_supported
|
||||
|
||||
- name: Ensure config with user_auth_type passkey, again
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
user_auth_type:
|
||||
- passkey
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
when: passkey_is_supported
|
||||
|
||||
- name: Check if correct message is given if passkey is not supported.
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
user_auth_type:
|
||||
- passkey
|
||||
register: result
|
||||
failed_when: not result.failed or "'passkey' is not supported" not in result.msg
|
||||
when: not passkey_is_supported
|
||||
|
||||
- name: Ensure config with empty user_auth_type
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
@@ -170,6 +138,6 @@
|
||||
ipaconfig:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
pac_type: '{{ previousconfig.config.pac_type | default("") }}'
|
||||
user_auth_type: '{{ previousconfig.config.user_auth_type | default("") }}'
|
||||
configstring: '{{ previousconfig.config.configstring | default("") }}'
|
||||
pac_type: '{{ previousconfig.config.pac_type }}'
|
||||
user_auth_type: '{{ previousconfig.config.user_auth_type }}'
|
||||
configstring: '{{ previousconfig.config.configstring }}'
|
||||
|
||||
@@ -134,9 +134,11 @@
|
||||
name: "{{ item }}"
|
||||
state: absent
|
||||
with_items:
|
||||
- "{{ zone_prefix_reverse }}"
|
||||
- "{{ zone_prefix_reverse_24 }}"
|
||||
- "{{ zone_prefix_reverse_16 }}"
|
||||
- "{{ zone_prefix_reverse_8 }}"
|
||||
- "{{ zone_ipv6_reverse }}"
|
||||
- "{{ zone_ipv6_reverse_workaround }}"
|
||||
- "{{ testzone }}"
|
||||
- "{{ safezone }}"
|
||||
|
||||
@@ -15,11 +15,13 @@
|
||||
skip_nameserver_check: yes
|
||||
skip_overlap_check: yes
|
||||
with_items:
|
||||
- "{{ zone_prefix_reverse }}"
|
||||
- "{{ zone_prefix_reverse_24 }}"
|
||||
- "{{ zone_prefix_reverse_16 }}"
|
||||
- "{{ zone_prefix_reverse_8 }}"
|
||||
- "{{ zone_ipv6_reverse_workaround }}"
|
||||
- "{{ testzone }}"
|
||||
- "{{ zone_ipv6_reverse }}"
|
||||
|
||||
- name: Ensure DNSSEC zone '"{{ safezone }}"' is present.
|
||||
ipadnszone:
|
||||
|
||||
@@ -7,17 +7,14 @@
|
||||
ipv4_reverse: "{{ ansible_facts['default_ipv4'].address.split('.')[:-1] |
|
||||
reverse |
|
||||
join('.') }}"
|
||||
# The 'external_ipv4_address' represents an IP address that
|
||||
# is not part of the expected CIDR zones managed by the IPA
|
||||
# deployment. It is used to test the cases were the the reverse
|
||||
# DNS zone must not be available in the embedded DNS nameserver.
|
||||
external_ipv4_address: "1.2.3.4"
|
||||
|
||||
- name: Set zone prefixes.
|
||||
ansible.builtin.set_fact:
|
||||
testzone: 'testzone.test'
|
||||
safezone: 'safezone.test'
|
||||
zone_ipv6_reverse: "ip6.arpa."
|
||||
zone_ipv6_reverse_workaround: "d.f.ip6.arpa."
|
||||
zone_prefix_reverse: "in-addr.arpa."
|
||||
zone_prefix_reverse_24: "{{ ipv4_reverse.split('.')[:] | join('.') }}.in-addr.arpa."
|
||||
zone_prefix_reverse_16: "{{ ipv4_reverse.split('.')[1:] | join('.') }}.in-addr.arpa."
|
||||
zone_prefix_reverse_8: "{{ ipv4_reverse.split('.')[2:] | join('.') }}.in-addr.arpa."
|
||||
|
||||
@@ -1545,28 +1545,6 @@
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
- name: Ensure host has IP in subnet not managed by IPA, without PTR record
|
||||
ipadnsrecord:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
zone_name: "{{ testzone }}"
|
||||
name: host01
|
||||
a_rec: "{{ external_ipv4_address }}"
|
||||
a_create_reverse: false
|
||||
register: result
|
||||
failed_when: not result.changed or result.failed
|
||||
|
||||
- name: Ensure host has IP in subnet not managed by IPA, without PTR record, again
|
||||
ipadnsrecord:
|
||||
ipaadmin_password: SomeADMINpassword
|
||||
ipaapi_context: "{{ ipa_context | default(omit) }}"
|
||||
zone_name: "{{ testzone }}"
|
||||
name: host01
|
||||
a_rec: "{{ external_ipv4_address }}"
|
||||
a_create_reverse: false
|
||||
register: result
|
||||
failed_when: result.changed or result.failed
|
||||
|
||||
# cleanup
|
||||
- name: Cleanup test environment.
|
||||
ansible.builtin.include_tasks: env_cleanup.yml
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user