mirror of
https://github.com/freeipa/ansible-freeipa.git
synced 2026-03-27 05:43:05 +00:00
Compare commits
42 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d328caa59 | ||
|
|
6fe001e804 | ||
|
|
e1aa9641a4 | ||
|
|
7d43c861bb | ||
|
|
df65de902d | ||
|
|
46925086b7 | ||
|
|
9a53e71de8 | ||
|
|
c82867585b | ||
|
|
2717fc6ca4 | ||
|
|
62fd4cc157 | ||
|
|
c822423b14 | ||
|
|
9c2b995724 | ||
|
|
b51397eb89 | ||
|
|
2dc2799883 | ||
|
|
5057b3cfe0 | ||
|
|
5951b954be | ||
|
|
69b894a7e5 | ||
|
|
bb591f33dd | ||
|
|
1a3f72b1f4 | ||
|
|
ab1b4bc6ba | ||
|
|
6b4f0f62de | ||
|
|
dd321b2065 | ||
|
|
9397776501 | ||
|
|
be04079fc7 | ||
|
|
5bdaa9aa6f | ||
|
|
1b1198a091 | ||
|
|
bdf3ad4a9c | ||
|
|
939f10eeff | ||
|
|
eded3b4cfd | ||
|
|
58e1f03bcb | ||
|
|
e0c85c5af4 | ||
|
|
34ce174d55 | ||
|
|
0ddd62ea01 | ||
|
|
36afd2220e | ||
|
|
2be00c1e0f | ||
|
|
93f9b900c6 | ||
|
|
e5be194d57 | ||
|
|
65fb75feaf | ||
|
|
d08291bec4 | ||
|
|
bb9abeec8c | ||
|
|
8c77c34d5f | ||
|
|
12006859d9 |
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
||||
*.pyc
|
||||
*.retry
|
||||
154
README-topology.md
Normal file
154
README-topology.md
Normal file
@@ -0,0 +1,154 @@
|
||||
Topology modules
|
||||
================
|
||||
|
||||
Description
|
||||
-----------
|
||||
|
||||
These modules allow to manage the topology. That means that topology segments can be added, removed and reinitialized. Also it is possible to verify topology suffixes.
|
||||
|
||||
|
||||
Features
|
||||
--------
|
||||
* Topology management
|
||||
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
|
||||
FreeIPA versions 4.4.0 and up are supported by the ipatopologysegment and ipatopologysuffix modules.
|
||||
|
||||
|
||||
Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.8+
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
Example inventory file
|
||||
|
||||
```ini
|
||||
[ipaserver]
|
||||
ipaserver.test.local
|
||||
```
|
||||
|
||||
|
||||
Example playbook to add a topology segment wiht default name (cn):
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle topologysegment
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
state: present
|
||||
```
|
||||
The name (cn) can also be set if it should not be the default `{left}-to-{rkight}`.
|
||||
|
||||
|
||||
Example playbook to delete a topology segment:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle topologysegment
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Delete topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
state: absent
|
||||
```
|
||||
It is possible to either use the name (cn) or left and right nodes. If left and right nodes are used, then the name will be searched and used internally.
|
||||
|
||||
|
||||
Example playbook to reinitialize a topology segment:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle topologysegment
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Reinitialize topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
direction: left-to-right
|
||||
state: reinitialized
|
||||
```
|
||||
It is possible to either use the name (cn) or left and right nodes. If left and right nodes are used, then the name will be searched and used internally.
|
||||
|
||||
|
||||
Example playbook to verify a topology suffix:
|
||||
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to handle topologysuffix
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Verify topology suffix
|
||||
ipatopologysuffix:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
state: verified
|
||||
```
|
||||
|
||||
|
||||
Variables
|
||||
=========
|
||||
|
||||
ipatopologysegment
|
||||
------------------
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`suffix` | The topology suffix to be used, this can either be `domain` or `ca` | yes
|
||||
`name` \| `cn` | The topology segment name (cn) is the unique identifier for a segment. | no
|
||||
`left` \| `leftnode` | The left replication node string - an IPA server | no
|
||||
`right` \| `rightnode` | The right replication node string - an IPA server | no
|
||||
`direction` | The direction a segment will be reinitialized. It can either be `left-to-right` or `right-to-left` and only used with `state: reinitialized` |
|
||||
`state` | The state to ensure. It can be one of `present`, `absent`, `enabled`, `disabled` or `reinitialized` | yes
|
||||
|
||||
|
||||
ipatopologysuffix
|
||||
-----------------
|
||||
|
||||
Verify FreeIPA topology suffix
|
||||
|
||||
Variable | Description | Required
|
||||
-------- | ----------- | --------
|
||||
`principal` | The admin principal is a string and defaults to `admin` | no
|
||||
`password` | The admin password is a string and is required if there is no admin ticket available on the node | no
|
||||
`suffix` | The topology suffix to be used, this can either be `domain` or `ca` | yes
|
||||
`state` | The state to ensure. It can only be `verified` | yes
|
||||
|
||||
|
||||
Authors
|
||||
=======
|
||||
|
||||
Thomas Woerner
|
||||
64
README.md
64
README.md
@@ -11,6 +11,7 @@ Features
|
||||
* Cluster deployments: Server, replicas and clients in one playbook
|
||||
* One-time-password (OTP) support for client installation
|
||||
* Repair mode for clients
|
||||
* Modules for topology management
|
||||
|
||||
Supported FreeIPA Versions
|
||||
--------------------------
|
||||
@@ -30,8 +31,8 @@ Requirements
|
||||
------------
|
||||
|
||||
**Controller**
|
||||
* Ansible version: 2.5+
|
||||
* python3-gssapi is required on the controller if a one time password (OTP) is used to install the client.
|
||||
* Ansible version: 2.8+ (ansible-freeipa is an Ansible Collection)
|
||||
* python3-gssapi is required on the controller if a one time password (OTP) is used with keytab to install the client.
|
||||
|
||||
**Node**
|
||||
* Supported FreeIPA version (see above)
|
||||
@@ -121,12 +122,34 @@ This will create a chain from ```ipaserver.test.local <- ipareplica1.test.local
|
||||
|
||||
If you need to set more than one server for a replica (for fallbacks etc.), simply use a comma separated list for ```ipareplica_servers```:
|
||||
```yaml
|
||||
[ipareplicas]
|
||||
[ipareplicas_tier1]
|
||||
ipareplica1.test.local
|
||||
|
||||
[ipareplicas_tier2]
|
||||
ipareplica2.test.local ipareplica_servers=ipareplica1.test.local,ipaserver.test.local
|
||||
```
|
||||
The first entry in ```ipareplica_servers``` will be used as the master.
|
||||
|
||||
In this case you need to have separate tasks in the playbook to first deploy replicas from tier1 and then replicas from tier2:
|
||||
```yaml
|
||||
---
|
||||
- name: Playbook to configure IPA replicas (tier1)
|
||||
hosts: ipareplicas_tier1
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ipareplica
|
||||
state: present
|
||||
|
||||
- name: Playbook to configure IPA replicas (tier2)
|
||||
hosts: ipareplicas_tier2
|
||||
become: true
|
||||
|
||||
roles:
|
||||
- role: ipareplica
|
||||
state: present
|
||||
```
|
||||
|
||||
You can add settings for replica deployment:
|
||||
```yaml
|
||||
[ipareplicas:vars]
|
||||
@@ -179,7 +202,7 @@ If you need to set more than one server for a client (for fallbacks etc.), simpl
|
||||
|
||||
You can add settings for client deployment:
|
||||
```yaml
|
||||
[ipareplicas:vars]
|
||||
[ipaclients:vars]
|
||||
ipaadmin_password=ADMPassword1
|
||||
ipaserver_domain=test.local
|
||||
ipaserver_realm=TEST.LOCAL
|
||||
@@ -188,7 +211,7 @@ ipaserver_realm=TEST.LOCAL
|
||||
For enhanced security it is possible to use a auto-generated one-time-password (OTP). This will be generated on the controller using the (first) server. It is needed to have the Python gssapi bindings installed on the controller for this.
|
||||
To enable the generation of the one-time-password:
|
||||
```yaml
|
||||
[ipareplicas:vars]
|
||||
[ipaclients:vars]
|
||||
ipaclient_use_otp=yes
|
||||
```
|
||||
|
||||
@@ -214,16 +237,17 @@ All these settings will be available in the ```[ipaserver]```, ```[ipareplicas]`
|
||||
Playbooks
|
||||
=========
|
||||
|
||||
The playbooks needed to deploy or undeploy server, replicas and clients are part of the repository. There are also playbooks to deploy and undeploy clusters. With them it is only needed to add an inventory file:
|
||||
The playbooks needed to deploy or undeploy server, replicas and clients are part of the repository and placed in the playbooks folder. There are also playbooks to deploy and undeploy clusters. With them it is only needed to add an inventory file:
|
||||
```
|
||||
install-client.yml
|
||||
install-cluster.yml
|
||||
install-replica.yml
|
||||
install-server.yml
|
||||
uninstall-client.yml
|
||||
uninstall-cluster.yml
|
||||
uninstall-replica.yml
|
||||
uninstall-server.yml
|
||||
playbooks\
|
||||
install-client.yml
|
||||
install-cluster.yml
|
||||
install-replica.yml
|
||||
install-server.yml
|
||||
uninstall-client.yml
|
||||
uninstall-cluster.yml
|
||||
uninstall-replica.yml
|
||||
uninstall-server.yml
|
||||
```
|
||||
|
||||
How to deploy a master server
|
||||
@@ -281,6 +305,12 @@ This will deploy the server, replicas and clients defined in the inventory file.
|
||||
Roles
|
||||
=====
|
||||
|
||||
* [Server](SERVER.md)
|
||||
* [Replica](REPLICA.md)
|
||||
* [Client](CLIENT.md)
|
||||
* [Server](roles/ipaserver/README.md)
|
||||
* [Replica](roles/ipareplica/README.md)
|
||||
* [Client](roles/ipaclient/README.md)
|
||||
|
||||
Plugins in plugin/modules
|
||||
=========================
|
||||
|
||||
* [ipatopologysegment](README-topology.md)
|
||||
* [ipatopologysuffix](README-topology.md)
|
||||
|
||||
25
galaxy.yml
Normal file
25
galaxy.yml
Normal file
@@ -0,0 +1,25 @@
|
||||
namespace: "freeipa"
|
||||
name: "ansible_freeipa"
|
||||
version: "0.1.1"
|
||||
description: ""
|
||||
|
||||
authors:
|
||||
- "Thomas Woerner <twoerner@redhat.com>"
|
||||
|
||||
repository: "https://github.com/freeipa/ansible-freeipa"
|
||||
documentation: "https://github.com/freeipa/ansible-freeipa/blob/master/README.md"
|
||||
homepage: "https://github.com/freeipa/ansible-freeipa"
|
||||
issues: "https://github.com/freeipa/ansible-freeipa/issues"
|
||||
|
||||
dependencies: {}
|
||||
|
||||
readme: "README.md"
|
||||
license: "GPL-3.0-or-later"
|
||||
license_file: "COPYING"
|
||||
|
||||
tags:
|
||||
- "identity"
|
||||
- "ipa"
|
||||
- "freeipa"
|
||||
- "cluster"
|
||||
- "collection"
|
||||
13
playbooks/topology/add-topologysegment.yml
Normal file
13
playbooks/topology/add-topologysegment.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Playbook to handle topologysegment
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Add topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
state: present
|
||||
13
playbooks/topology/delete-topologysegment.yml
Normal file
13
playbooks/topology/delete-topologysegment.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
---
|
||||
- name: Playbook to handle topologysegment
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Delete topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
state: absent
|
||||
14
playbooks/topology/reinitialize-topologysegment.yml
Normal file
14
playbooks/topology/reinitialize-topologysegment.yml
Normal file
@@ -0,0 +1,14 @@
|
||||
---
|
||||
- name: Playbook to handle topologysegment
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Reinitialize topology segment
|
||||
ipatopologysegment:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
left: ipareplica1.test.local
|
||||
right: ipareplica2.test.local
|
||||
direction: left-to-right
|
||||
state: reinitialized
|
||||
11
playbooks/topology/verify-topologysuffix.yml
Normal file
11
playbooks/topology/verify-topologysuffix.yml
Normal file
@@ -0,0 +1,11 @@
|
||||
---
|
||||
- name: Playbook to handle topologysuffix
|
||||
hosts: ipaserver
|
||||
become: true
|
||||
|
||||
tasks:
|
||||
- name: Verify topology suffix
|
||||
ipatopologysuffix:
|
||||
password: MyPassword123
|
||||
suffix: domain
|
||||
state: verified
|
||||
122
plugins/module_utils/ansible_freeipa_module.py
Normal file
122
plugins/module_utils/ansible_freeipa_module.py
Normal file
@@ -0,0 +1,122 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
|
||||
import os
|
||||
import sys
|
||||
import tempfile
|
||||
import shutil
|
||||
from ipalib import api, errors
|
||||
from ipalib.config import Env
|
||||
from ipalib.constants import DEFAULT_CONFIG
|
||||
try:
|
||||
from ipalib.install.kinit import kinit_password
|
||||
except ImportError:
|
||||
from ipapython.ipautil import kinit_password
|
||||
from ipapython.ipautil import run
|
||||
from ipaplatform.paths import paths
|
||||
from ipalib.krb_utils import get_credentials_if_valid
|
||||
|
||||
|
||||
def valid_creds(principal):
|
||||
"""
|
||||
Get valid credintials matching the princial
|
||||
"""
|
||||
creds = get_credentials_if_valid()
|
||||
if creds and \
|
||||
creds.lifetime > 0 and \
|
||||
"%s@" % principal in creds.name.display_as(creds.name.name_type):
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def temp_kinit(principal, password):
|
||||
"""
|
||||
kinit with password using a temporary ccache
|
||||
"""
|
||||
if not password:
|
||||
raise RuntimeError("The password is not set")
|
||||
if not principal:
|
||||
principal = "admin"
|
||||
|
||||
ccache_dir = tempfile.mkdtemp(prefix='krbcc')
|
||||
ccache_name = os.path.join(ccache_dir, 'ccache')
|
||||
|
||||
try:
|
||||
kinit_password(principal, password, ccache_name)
|
||||
except RuntimeError as e:
|
||||
raise RuntimeError("Kerberos authentication failed: {}".format(e))
|
||||
|
||||
return ccache_dir, ccache_name
|
||||
|
||||
|
||||
def temp_kdestroy(ccache_dir, ccache_name):
|
||||
"""
|
||||
Destroy temporary ticket and remove temporary ccache
|
||||
"""
|
||||
if ccache_name is not None:
|
||||
run([paths.KDESTROY, '-c', ccache_name], raiseonerr=False)
|
||||
if ccache_dir is not None:
|
||||
shutil.rmtree(ccache_dir, ignore_errors=True)
|
||||
|
||||
|
||||
def api_connect():
|
||||
"""
|
||||
Create environment, initialize api and connect to ldap2
|
||||
"""
|
||||
env = Env()
|
||||
env._bootstrap()
|
||||
env._finalize_core(**dict(DEFAULT_CONFIG))
|
||||
|
||||
api.bootstrap(context='server', debug=env.debug, log=None)
|
||||
api.finalize()
|
||||
api.Backend.ldap2.connect()
|
||||
|
||||
|
||||
def api_command(module, command, name, args):
|
||||
"""
|
||||
Call ipa.Command, use AnsibleModule.fail_json for error handling
|
||||
"""
|
||||
try:
|
||||
return api.Command[command](name, **args)
|
||||
except Exception as e:
|
||||
module.fail_json(msg="%s: %s" % (command, e))
|
||||
|
||||
|
||||
def execute_api_command(module, principal, password, command, name, args):
|
||||
"""
|
||||
Get KRB ticket if not already there, initialize api, connect,
|
||||
execute command and destroy ticket again if it has been created also.
|
||||
"""
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(principal):
|
||||
ccache_dir, ccache_name = temp_kinit(principal, password)
|
||||
api_connect()
|
||||
|
||||
return api_command(module, command, name, args)
|
||||
except Exception as e:
|
||||
module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
288
plugins/modules/ipatopologysegment.py
Normal file
288
plugins/modules/ipatopologysegment.py
Normal file
@@ -0,0 +1,288 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipatopologysegment
|
||||
short description: Manage FreeIPA topology segments
|
||||
description: Manage FreeIPA topology segments
|
||||
options:
|
||||
principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
password:
|
||||
description: The admin password
|
||||
required: false
|
||||
suffix:
|
||||
description: Topology suffix
|
||||
required: true
|
||||
choices: ["domain", "ca"]
|
||||
name:
|
||||
description: Topology segment name, unique identifier.
|
||||
required: false
|
||||
aliases: ["cn"]
|
||||
left:
|
||||
description: Left replication node - an IPA server
|
||||
aliases: ["leftnode"]
|
||||
right:
|
||||
description: Right replication node - an IPA server
|
||||
aliases: ["rightnode"]
|
||||
direction:
|
||||
description: The direction a segment will be reinitialized
|
||||
required: false
|
||||
choices: ["left-to-right", "right-to-left"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: present
|
||||
choices: ["present", "absent", "enabled", "disabled", "reinitialized"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
- ipatopologysegment:
|
||||
suffix: domain
|
||||
left: ipaserver.test.local
|
||||
right: ipareplica1.test.local
|
||||
state: present
|
||||
|
||||
- ipatopologysegment:
|
||||
suffix: domain
|
||||
name: ipaserver.test.local-to-replica1.test.local
|
||||
state: absent
|
||||
|
||||
- ipatopologysegment:
|
||||
suffix: domain
|
||||
left: ipaserver.test.local
|
||||
right: ipareplica1.test.local
|
||||
state: absent
|
||||
|
||||
- ipatopologysegment:
|
||||
suffix: ca
|
||||
name: ipaserver.test.local-to-replica1.test.local
|
||||
direction: left-to-right
|
||||
state: reinitialized
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import temp_kinit, \
|
||||
temp_kdestroy, valid_creds, api_connect, api_command
|
||||
|
||||
def find_left_right(module, suffix, left, right):
|
||||
_args = {
|
||||
"iparepltoposegmentleftnode": to_text(left),
|
||||
"iparepltoposegmentrightnode": to_text(right),
|
||||
}
|
||||
_result = api_command(module, "topologysegment_find",
|
||||
to_text(suffix), _args)
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="Combination of left node '%s' and right node '%s' is "
|
||||
"not unique for suffix '%s'" % (left, right, suffix))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def find_cn(module, suffix, name):
|
||||
_args = {
|
||||
"cn": to_text(name),
|
||||
}
|
||||
_result = api_command(module, "topologysegment_find",
|
||||
to_text(suffix), _args)
|
||||
if len(_result["result"]) > 1:
|
||||
module.fail_json(
|
||||
msg="CN '%s' is not unique for suffix '%s'" % (name, suffix))
|
||||
elif len(_result["result"]) == 1:
|
||||
return _result["result"][0]
|
||||
else:
|
||||
return None
|
||||
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
principal=dict(type="str", default="admin"),
|
||||
password=dict(type="str", required=False, no_log=True),
|
||||
suffix=dict(choices=["domain", "ca"], required=True),
|
||||
name=dict(type="str", aliases=["cn"], default=None),
|
||||
left=dict(type="str", aliases=["leftnode"], default=None),
|
||||
right=dict(type="str", aliases=["rightnode"], default=None),
|
||||
direction=dict(type="str", default=None,
|
||||
choices=["left-to-right", "right-to-left"]),
|
||||
state=dict(type="str", default="present",
|
||||
choices=["present", "absent", "enabled", "disabled",
|
||||
"reinitialized"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
principal = ansible_module.params.get("principal")
|
||||
password = ansible_module.params.get("password")
|
||||
suffix = ansible_module.params.get("suffix")
|
||||
name = ansible_module.params.get("name")
|
||||
left = ansible_module.params.get("left")
|
||||
right = ansible_module.params.get("right")
|
||||
direction = ansible_module.params.get("direction")
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
if state != "reinitialized" and direction is not None:
|
||||
ansible_module.fail_json(
|
||||
msg="Direction is not supported in this mode.")
|
||||
|
||||
# Init
|
||||
|
||||
changed = False
|
||||
ccache_dir = None
|
||||
ccache_name = None
|
||||
try:
|
||||
if not valid_creds(principal):
|
||||
ccache_dir, ccache_name = temp_kinit(principal, password)
|
||||
api_connect()
|
||||
|
||||
command = None
|
||||
|
||||
# Get name (cn) from left and right node if set for absent, disabled
|
||||
# or reinitialized.
|
||||
if state in ["absent", "disabled", "reinitialized"]:
|
||||
if left is not None and right is not None:
|
||||
left_right = find_left_right(ansible_module, suffix,
|
||||
left, right)
|
||||
if left_right is not None:
|
||||
if name is not None and \
|
||||
left_right["cn"][0] != to_text(name):
|
||||
ansible_module.fail_json(
|
||||
msg="Left and right nodes do not match "
|
||||
"given name name (cn) '%s'" % name)
|
||||
args = {
|
||||
"cn": left_right["cn"][0]
|
||||
}
|
||||
# else: Nothing to change
|
||||
elif name is not None:
|
||||
result = find_cn(ansible_module, suffix, name)
|
||||
if result is not None:
|
||||
args = {
|
||||
"cn": result["cn"][0]
|
||||
}
|
||||
# else: Nothing to change
|
||||
else:
|
||||
ansible_module.fail_json(
|
||||
msg="Either left and right or name need to be set.")
|
||||
|
||||
# Create command
|
||||
if state in ["present", "enabled"]:
|
||||
# Make sure topology segment exists
|
||||
|
||||
if left is None or right is None:
|
||||
ansible_module.fail_json(
|
||||
msg="Left and right need to be set.")
|
||||
args = {
|
||||
"iparepltoposegmentleftnode": to_text(left),
|
||||
"iparepltoposegmentrightnode": to_text(right),
|
||||
}
|
||||
if name is not None:
|
||||
args["cn"] = to_text(name)
|
||||
|
||||
res_left_right = find_left_right(ansible_module, suffix,
|
||||
left, right)
|
||||
if res_left_right is not None:
|
||||
if name is not None and \
|
||||
res_left_right["cn"][0] != to_text(name):
|
||||
ansible_module.fail_json(
|
||||
msg="Left and right nodes already used with "
|
||||
"different name (cn) '%s'" % res_left_right["cn"])
|
||||
|
||||
# Left and right nodes and also the name can not be
|
||||
# changed
|
||||
for key in [ "iparepltoposegmentleftnode",
|
||||
"iparepltoposegmentrightnode" ]:
|
||||
if key in args:
|
||||
del args[key]
|
||||
if len(args) > 1:
|
||||
# cn needs to be in args always
|
||||
command = "topologysegment_mod"
|
||||
# else: Nothing to change
|
||||
else:
|
||||
if name is None:
|
||||
args["cn"] = to_text("%s-to-%s" % (left, right))
|
||||
command = "topologysegment_add"
|
||||
|
||||
elif state in ["absent", "disabled"]:
|
||||
# Make sure topology segment does not exist
|
||||
|
||||
if len(args) > 0:
|
||||
# Either name defined or found name from left and right node
|
||||
command = "topologysegment_del"
|
||||
|
||||
elif state == "reinitialized":
|
||||
# Reinitialize segment
|
||||
|
||||
if len(args) > 0:
|
||||
# Either name defined or found name from left and right node
|
||||
command = "topologysegment_reinitialize"
|
||||
|
||||
if direction == "left-to-right":
|
||||
args["left"] = True
|
||||
elif direction == "right-to-left":
|
||||
args["right"] = True
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unknown direction '%s'" %
|
||||
direction)
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute command
|
||||
|
||||
if command is not None:
|
||||
result = api_command(ansible_module, command,
|
||||
to_text(suffix), args)
|
||||
changed = True
|
||||
|
||||
except Exception as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
temp_kdestroy(ccache_dir, ccache_name)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=changed)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
109
plugins/modules/ipatopologysuffix.py
Normal file
109
plugins/modules/ipatopologysuffix.py
Normal file
@@ -0,0 +1,109 @@
|
||||
#!/usr/bin/python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Authors:
|
||||
# Thomas Woerner <twoerner@redhat.com>
|
||||
#
|
||||
# Copyright (C) 2019 Red Hat
|
||||
# see file 'COPYING' for use and warranty information
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
ANSIBLE_METADATA = {
|
||||
"metadata_version": "1.0",
|
||||
"supported_by": "community",
|
||||
"status": ["preview"],
|
||||
}
|
||||
|
||||
DOCUMENTATION = """
|
||||
---
|
||||
module: ipatopologysuffix
|
||||
short description: Verify FreeIPA topology suffix
|
||||
description: Verify FreeIPA topology suffix
|
||||
options:
|
||||
principal:
|
||||
description: The admin principal
|
||||
default: admin
|
||||
password:
|
||||
description: The admin password
|
||||
required: false
|
||||
suffix:
|
||||
description: Topology suffix
|
||||
required: true
|
||||
choices: ["domain", "ca"]
|
||||
state:
|
||||
description: State to ensure
|
||||
default: verified
|
||||
choices: ["verified"]
|
||||
author:
|
||||
- Thomas Woerner
|
||||
"""
|
||||
|
||||
EXAMPLES = """
|
||||
- ipatopologysuffix:
|
||||
suffix: domain
|
||||
state: verified
|
||||
"""
|
||||
|
||||
RETURN = """
|
||||
"""
|
||||
|
||||
from ansible.module_utils.basic import AnsibleModule
|
||||
from ansible.module_utils._text import to_bytes, to_native, to_text
|
||||
from ansible.module_utils.ansible_freeipa_module import execute_api_command
|
||||
|
||||
def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
principal=dict(type="str", default="admin"),
|
||||
password=dict(type="str", required=False, no_log=True),
|
||||
suffix=dict(choices=["domain", "ca"], required=True),
|
||||
state=dict(type="str", default="verified",
|
||||
choices=["verified"]),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
ansible_module._ansible_debug = True
|
||||
|
||||
# Get parameters
|
||||
|
||||
principal = ansible_module.params.get("principal")
|
||||
password = ansible_module.params.get("password")
|
||||
suffix = ansible_module.params.get("suffix")
|
||||
state = ansible_module.params.get("state")
|
||||
|
||||
# Check parameters
|
||||
|
||||
# Init
|
||||
|
||||
# Create command
|
||||
|
||||
if state in ["verified"]:
|
||||
command = "topologysuffix_verify"
|
||||
args = {}
|
||||
else:
|
||||
ansible_module.fail_json(msg="Unkown state '%s'" % state)
|
||||
|
||||
# Execute command
|
||||
|
||||
execute_api_command(ansible_module, principal, password,
|
||||
command, to_text(suffix), args)
|
||||
|
||||
# Done
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1 +1 @@
|
||||
ansible>=2.5.0
|
||||
ansible>=2.8.0
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
---
|
||||
krb5_packages: krb5-workstation
|
||||
krb5_conf: /etc/krb5.conf
|
||||
krb5_conf_d: /etc/krb5.conf.d/ # paths.COMMON_KRB5_CONF_DIR
|
||||
krb5_include_d: /var/lib/sss/pubconf/krb5.include.d/ # paths.SSSD_PUBCONF_KRB5_INCLUDE_D_DIR
|
||||
|
||||
krb5_realm:
|
||||
krb5_servers:
|
||||
krb5_dns_lookup_realm: "false"
|
||||
krb5_dns_lookup_kdc: "false"
|
||||
krb5_no_default_domain: "false"
|
||||
krb5_default_ccache_name: KEYRING:persistent:%{uid}
|
||||
@@ -1,12 +0,0 @@
|
||||
galaxy_info:
|
||||
author: Thomas Woerner
|
||||
description: A role to configure krb5
|
||||
company: Red Hat, Inc
|
||||
|
||||
license: GPLv3
|
||||
|
||||
min_ansible_version: 2.0
|
||||
|
||||
galaxy_tags: [ 'identity', 'ipa']
|
||||
|
||||
dependencies: []
|
||||
@@ -1,22 +0,0 @@
|
||||
---
|
||||
- name: Install {{ krb5_packages }}
|
||||
package: name="{{ item }}" state=present
|
||||
with_items: "{{ krb5_packages }}"
|
||||
|
||||
- name: Install - Create ipabkp of krb5.conf
|
||||
copy: src="{{ krb5_conf }}" dest="{{ krb5_conf }}".ipabkp
|
||||
failed_when: false
|
||||
|
||||
- name: Install - Backup krb5.conf
|
||||
ipaclient_fstore:
|
||||
backup: "{{ krb5_conf }}"
|
||||
|
||||
- name: Template krb5.conf
|
||||
template:
|
||||
src: krb5.conf.j2
|
||||
dest: "{{ krb5_conf }}"
|
||||
backup: no
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
force: yes
|
||||
@@ -1,39 +0,0 @@
|
||||
includedir {{ krb5_conf_d }}
|
||||
includedir {{ krb5_include_d }}
|
||||
|
||||
[libdefaults]
|
||||
default_realm = {{ krb5_realm | upper }}
|
||||
dns_lookup_realm = {{ krb5_dns_lookup_realm }}
|
||||
dns_lookup_kdc = {{ krb5_dns_lookup_kdc }}
|
||||
rdns = false
|
||||
{% if krb5_dns_canonicalize_hostname is defined %}
|
||||
dns_canonicalize_hostname = {{ krb5_dns_canonicalize_hostname }}
|
||||
{% endif %}
|
||||
ticket_lifetime = 24h
|
||||
forwardable = true
|
||||
udp_preference_limit = 0
|
||||
default_ccache_name = {{ krb5_default_ccache_name }}
|
||||
|
||||
[realms]
|
||||
{{ krb5_realm | upper }} = {
|
||||
{% for server in krb5_servers %}
|
||||
kdc = {{ server }}:88
|
||||
master_kdc = {{ server }}:88
|
||||
admin_server = {{ server }}:749
|
||||
kpasswd_server = {{ server }}:464
|
||||
{% endfor %}
|
||||
{% if krb5_default_domain | bool %}
|
||||
default_domain = {{ krb5_realm | lower }}
|
||||
{% endif %}
|
||||
{% if krb5_pkinit_anchors is defined %}
|
||||
pkinit_anchors = {{ krb5_pkinit_anchors }}
|
||||
{% endif %}
|
||||
{% if krb5_pkinit_pool is defined %}
|
||||
pkinit_pool = {{ krb5_pkinit_pool }}
|
||||
{% endif %}
|
||||
}
|
||||
|
||||
[domain_realm]
|
||||
.{{ krb5_realm | lower }} = {{ krb5_realm | upper }}
|
||||
{{ krb5_realm | lower }} = {{ krb5_realm | upper }}
|
||||
{{ ansible_host | lower }} = {{ krb5_realm | upper }}
|
||||
@@ -1,2 +0,0 @@
|
||||
krb5_packages:
|
||||
- krb5-workstation
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
sssd_conf: /etc/sssd/sssd.conf
|
||||
sssd_packages: sssd, libselinux-python
|
||||
sssd_on_master: "false"
|
||||
sssd_domains:
|
||||
sssd_id_provider:
|
||||
sssd_auth_provider:
|
||||
sssd_access_provider:
|
||||
sssd_chpass_provider:
|
||||
sssd_cache_credentials: False
|
||||
sssd_krb5_offline_passwords: False
|
||||
sssd_ipa_servers:
|
||||
sssd_services:
|
||||
@@ -1,12 +0,0 @@
|
||||
galaxy_info:
|
||||
author: Thomas Woerner
|
||||
description: A role to configure sssd for IPA
|
||||
company: Red Hat, Inc
|
||||
|
||||
license: GPLv3
|
||||
|
||||
min_ansible_version: 2.0
|
||||
|
||||
galaxy_tags: [ 'identity', 'ipa']
|
||||
|
||||
dependencies: []
|
||||
@@ -1,27 +0,0 @@
|
||||
---
|
||||
- name: Install {{ sssd_packages }}
|
||||
package: name="{{ item }}" state=present
|
||||
with_items: "{{ sssd_packages }}"
|
||||
|
||||
# No backup in ipa-client-install mode
|
||||
#- name: Backup {{ sssd_conf }}
|
||||
# copy:
|
||||
# src: "{{ sssd_conf }}"
|
||||
# dest: "{{ sssd_conf }}.bkp"
|
||||
# force: no
|
||||
|
||||
- name: Template sssd.conf
|
||||
template:
|
||||
src: sssd.conf.j2
|
||||
dest: "{{ sssd_conf }}"
|
||||
backup: no
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0600
|
||||
force: yes
|
||||
|
||||
#- name: Enable and start sssd
|
||||
# service:
|
||||
# name: sssd
|
||||
# state: restarted
|
||||
# enabled: yes
|
||||
@@ -1,34 +0,0 @@
|
||||
[domain/{{ sssd_domains }}]
|
||||
cache_credentials = {{ sssd_cache_credentials }}
|
||||
krb5_store_password_if_offline = {{ sssd_krb5_offline_passwords }}
|
||||
ipa_domain = {{ sssd_domains }}
|
||||
id_provider = {{ sssd_id_provider }}
|
||||
auth_provider = {{ sssd_auth_provider }}
|
||||
access_provider = {{ sssd_access_provider }}
|
||||
ipa_hostname = {{ ansible_host }}
|
||||
chpass_provider = {{ sssd_chpass_provider }}
|
||||
{% if sssd_on_master | bool %}
|
||||
ipa_server = {{ sssd_ipa_servers | join(", ") }}
|
||||
ipa_server_mode = True
|
||||
{% else %}
|
||||
{% if sssd_domains != ansible_domain %}
|
||||
dns_discovery_domain = sssd_domains
|
||||
{% endif %}
|
||||
ipa_server = _srv_, {{ sssd_ipa_servers | join(", ")}}
|
||||
{% endif %}
|
||||
ldap_tls_cacert = /etc/ipa/ca.crt
|
||||
|
||||
{% if sssd_on_master | bool %}
|
||||
{% set sssd_services = sssd_services + ", ifp" %}
|
||||
{% endif %}
|
||||
[sssd]
|
||||
services = {{ sssd_services }}
|
||||
domains = {{ sssd_domains }}
|
||||
|
||||
{% for service in sssd_services.split(',') %}
|
||||
[{{ service | trim }}]
|
||||
{% if service | trim == "nss" %}
|
||||
homedir_substring = /home
|
||||
{% endif %}
|
||||
|
||||
{% endfor %}
|
||||
@@ -1,4 +0,0 @@
|
||||
sssd_packages:
|
||||
- sssd
|
||||
- sssd-ipa
|
||||
- sssd-krb5
|
||||
@@ -17,7 +17,10 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import gssapi
|
||||
try:
|
||||
import gssapi
|
||||
except ImportError:
|
||||
gssapi = None
|
||||
import os
|
||||
import shutil
|
||||
import subprocess
|
||||
@@ -76,6 +79,9 @@ def kinit_keytab(principal, keytab, ccache_name, config):
|
||||
Perform kinit using principal/keytab, with the specified config file
|
||||
and store the TGT in ccache_name.
|
||||
"""
|
||||
if gssapi is None:
|
||||
raise ImportError("gssapi is not available")
|
||||
|
||||
old_config = os.environ.get('KRB5_CONFIG')
|
||||
os.environ['KRB5_CONFIG'] = config
|
||||
try:
|
||||
@@ -117,7 +123,7 @@ KRB5CONF_TEMPLATE = """
|
||||
|
||||
[domain_realm]
|
||||
.{{ ipa_domain }} = {{ ipa_realm }}
|
||||
{{ ipa_domain }} = {{ ipa_realm}}
|
||||
{{ ipa_domain }} = {{ ipa_realm }}
|
||||
"""
|
||||
|
||||
class ActionModule(ActionBase):
|
||||
|
||||
@@ -306,8 +306,9 @@ def main():
|
||||
|
||||
# Get domain from first server if domain is not set, but if there are
|
||||
# servers
|
||||
if options.domain_name is None and len(options.servers) > 0:
|
||||
options.domain_name = options.servers[0][options.servers[0].find(".")+1:]
|
||||
if options.domain_name is None and options.servers is not None:
|
||||
if len(options.servers) > 0:
|
||||
options.domain_name = options.servers[0][options.servers[0].find(".")+1:]
|
||||
|
||||
try:
|
||||
self = options
|
||||
@@ -324,7 +325,8 @@ def main():
|
||||
|
||||
### ServiceInstallInterface ###
|
||||
|
||||
validate_domain_name(options.domain_name)
|
||||
if options.domain_name:
|
||||
validate_domain_name(options.domain_name)
|
||||
|
||||
if options.realm_name:
|
||||
argspec = inspect.getargspec(validate_domain_name)
|
||||
@@ -527,6 +529,14 @@ def main():
|
||||
"Invalid hostname, '{}' must not be used.".format(hostname),
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
if hasattr(constants, "MAXHOSTNAMELEN"):
|
||||
try:
|
||||
validate_hostname(hostname, maxlen=constants.MAXHOSTNAMELEN)
|
||||
except ValueError as e:
|
||||
raise ScriptError(
|
||||
'invalid hostname: {}'.format(e),
|
||||
rval=CLIENT_INSTALL_ERROR)
|
||||
|
||||
if hasattr(tasks, "is_nosssd_supported"):
|
||||
# --no-sssd is not supported any more for rhel-based distros
|
||||
if not tasks.is_nosssd_supported() and not options.sssd:
|
||||
|
||||
@@ -1,24 +1,20 @@
|
||||
dependencies: []
|
||||
|
||||
galaxy_info:
|
||||
author: Florence Blanc-Renaud, Thomas Woerner
|
||||
description: A role to join a machine to an IPA domain
|
||||
company: Red Hat, Inc
|
||||
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
license: GPLv3
|
||||
|
||||
min_ansible_version: 2.3.1
|
||||
|
||||
#github_branch:
|
||||
|
||||
min_ansible_version: 2.8
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- 25
|
||||
- name: rhel
|
||||
- all
|
||||
- name: EL
|
||||
versions:
|
||||
- 7
|
||||
|
||||
galaxy_tags: [ 'identity', 'ipa']
|
||||
|
||||
dependencies: []
|
||||
- 8
|
||||
galaxy_tags:
|
||||
- identity
|
||||
- ipa
|
||||
- freeipa
|
||||
|
||||
@@ -81,6 +81,7 @@ if NUM_VERSION >= 40400:
|
||||
except ImportError:
|
||||
from ipaclient import ipadiscovery
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib import constants
|
||||
try:
|
||||
from ipalib.install import sysrestore
|
||||
except ImportError:
|
||||
@@ -97,7 +98,8 @@ if NUM_VERSION >= 40400:
|
||||
from ipapython import certdb, ipautil
|
||||
from ipapython.admintool import ScriptError
|
||||
from ipapython.ipautil import CheckedIPAddress
|
||||
from ipalib.util import validate_domain_name, normalize_hostname
|
||||
from ipalib.util import validate_domain_name, normalize_hostname, \
|
||||
validate_hostname
|
||||
from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform.tasks import tasks
|
||||
|
||||
@@ -8,8 +8,8 @@
|
||||
with_items: "{{ ipaclient_packages }}"
|
||||
when: ipaclient_install_packages | bool
|
||||
|
||||
- name: Install - Include Python2/3 import test
|
||||
import_tasks: "{{role_path}}/tasks/python_2_3_test.yml"
|
||||
#- name: Install - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
|
||||
- name: Install - Set ipaclient_servers
|
||||
set_fact:
|
||||
@@ -19,9 +19,11 @@
|
||||
- name: Install - Set ipaclient_servers from cluster inventory
|
||||
set_fact:
|
||||
ipaclient_servers: "{{ groups['ipaserver'] | list }}"
|
||||
when: ipaclient_no_dns_lookup | bool and groups.ipaserver is defined and ipaclient_servers is not defined
|
||||
when: ipaclient_no_dns_lookup | bool and groups.ipaserver is defined and
|
||||
ipaclient_servers is not defined
|
||||
|
||||
- fail: msg="ipaadmin_principal and ipaadmin_keytab cannot be used together"
|
||||
- name: Install - Check that either principal or keytab is set
|
||||
fail: msg="ipaadmin_principal and ipaadmin_keytab cannot be used together"
|
||||
when: ipaadmin_keytab is defined and ipaadmin_principal is defined
|
||||
|
||||
- name: Install - Set default principal if no keytab is given
|
||||
@@ -65,12 +67,17 @@
|
||||
ntp_servers: "{{ ipaclient_ntp_servers | default(omit) }}"
|
||||
ntp_pool: "{{ ipaclient_ntp_pool | default(omit) }}"
|
||||
no_ntp: "{{ ipaclient_no_ntp }}"
|
||||
#force_ntpd: "{{ ipaclient_force_ntpd }}"
|
||||
# force_ntpd: "{{ ipaclient_force_ntpd }}"
|
||||
on_master: "{{ ipaclient_on_master }}"
|
||||
### additional ###
|
||||
servers: "{{ result_ipaclient_test.servers }}"
|
||||
domain: "{{ result_ipaclient_test.domain }}"
|
||||
|
||||
- name: Install - Disable One-Time Password for on_master
|
||||
set_fact:
|
||||
ipaclient_use_otp: "no"
|
||||
when: ipaclient_use_otp | bool and ipaclient_on_master | bool
|
||||
|
||||
- name: Install - Test if IPA client has working krb5.keytab
|
||||
ipaclient_test_keytab:
|
||||
servers: "{{ result_ipaclient_test.servers }}"
|
||||
@@ -81,11 +88,13 @@
|
||||
kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}"
|
||||
register: result_ipaclient_test_keytab
|
||||
|
||||
- name: Install - Disable One-Time Password for client with working krb5.keytab
|
||||
- name: Install - Disable One-Time Password for client with working
|
||||
krb5.keytab
|
||||
set_fact:
|
||||
ipaclient_use_otp: "no"
|
||||
when: ipaclient_use_otp | bool and result_ipaclient_test_keytab.krb5_keytab_ok and not ipaclient_force_join | bool
|
||||
|
||||
when: ipaclient_use_otp | bool and
|
||||
result_ipaclient_test_keytab.krb5_keytab_ok and
|
||||
not ipaclient_force_join | bool
|
||||
|
||||
# The following block is executed when using OTP to enroll IPA client
|
||||
# ie when ipaclient_use_otp is set.
|
||||
@@ -94,19 +103,20 @@
|
||||
# If a keytab is specified in the hostent, then the hostent will be disabled
|
||||
# if ipaclient_use_otp is set.
|
||||
- block:
|
||||
- fail: msg="Keytab or password is required for otp"
|
||||
- name: Install - Keytab or password is required for otp
|
||||
fail: msg="Keytab or password is required for otp"
|
||||
when: ipaadmin_keytab is undefined and ipaadmin_password is undefined
|
||||
|
||||
- name: Install - Save client ansible_python_interpreter setting
|
||||
set_fact:
|
||||
ipaclient_ansible_python_interpreter: "{{ ansible_python_interpreter }}"
|
||||
|
||||
- name: Install - Include Python2/3 import test
|
||||
import_tasks: "{{role_path}}/tasks/python_2_3_test.yml"
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
#- name: Install - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
# delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
|
||||
- name: Install - Get One-Time Password for client enrollment
|
||||
#no_log: yes
|
||||
no_log: yes
|
||||
ipaclient_get_otp:
|
||||
state: present
|
||||
principal: "{{ ipaadmin_principal | default('admin') }}"
|
||||
@@ -119,14 +129,18 @@
|
||||
register: result_ipaclient_get_otp
|
||||
# If the host is already enrolled, this command will exit on error
|
||||
# The error can be ignored
|
||||
failed_when: result_ipaclient_get_otp is failed and "Password cannot be set on enrolled host" not in result_ipaclient_get_otp.msg
|
||||
failed_when: result_ipaclient_get_otp is failed and
|
||||
"Password cannot be set on enrolled host" not
|
||||
in result_ipaclient_get_otp.msg
|
||||
delegate_to: "{{ result_ipaclient_test.servers[0] }}"
|
||||
delegate_facts: True
|
||||
delegate_facts: yes
|
||||
|
||||
- name: Install - Store the previously obtained OTP
|
||||
no_log: yes
|
||||
set_fact:
|
||||
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword if result_ipaclient_get_otp.host is defined }}"
|
||||
ipaadmin_orig_password: "{{ ipaadmin_password }}"
|
||||
ipaadmin_password: "{{ result_ipaclient_get_otp.host.randompassword
|
||||
if result_ipaclient_get_otp.host is defined }}"
|
||||
|
||||
- name: Install - Restore client ansible_python_interpreter setting
|
||||
set_fact:
|
||||
@@ -145,11 +159,14 @@
|
||||
|
||||
- name: Install - Check if principal and keytab are set
|
||||
fail: msg="Principal and keytab cannot be used together"
|
||||
when: ipaadmin_principal is defined and ipaadmin_principal != "" and ipaclient_keytab is defined and ipaclient_keytab != ""
|
||||
when: ipaadmin_principal is defined and ipaadmin_principal|length > 0
|
||||
and ipaclient_keytab is defined and ipaclient_keytab|length > 0
|
||||
|
||||
- name: Install - Check if one of password and keytab are set
|
||||
fail: msg="At least one of password or keytab must be specified"
|
||||
when: not result_ipaclient_test_keytab.krb5_keytab_ok and (ipaadmin_password is undefined or ipaadmin_password == "") and (ipaclient_keytab is undefined or ipaclient_keytab == "")
|
||||
when: not result_ipaclient_test_keytab.krb5_keytab_ok and
|
||||
(ipaadmin_password is undefined or ipaadmin_password|length == 0)
|
||||
and (ipaclient_keytab is undefined or ipaclient_keytab|length == 0)
|
||||
when: not ipaclient_on_master | bool
|
||||
|
||||
- name: Install - Purge {{ result_ipaclient_test.realm }} from host keytab
|
||||
@@ -161,7 +178,8 @@
|
||||
# Do not fail on error codes 3 and 5:
|
||||
# 3 - Unable to open keytab
|
||||
# 5 - Principal name or realm not found in keytab
|
||||
failed_when: result_ipa_rmkeytab.rc != 0 and result_ipa_rmkeytab.rc != 3 and result_ipa_rmkeytab.rc != 5
|
||||
failed_when: result_ipa_rmkeytab.rc != 0 and
|
||||
result_ipa_rmkeytab.rc != 3 and result_ipa_rmkeytab.rc != 5
|
||||
when: ipaclient_use_otp | bool or ipaclient_force_join | bool
|
||||
|
||||
- name: Install - Backup and set hostname
|
||||
@@ -178,25 +196,36 @@
|
||||
basedn: "{{ result_ipaclient_test.basedn }}"
|
||||
hostname: "{{ result_ipaclient_test.hostname }}"
|
||||
force_join: "{{ ipaclient_force_join | default(omit) }}"
|
||||
principal: "{{ ipaadmin_principal if not ipaclient_use_otp | bool and ipaclient_keytab is not defined else '' }}"
|
||||
principal: "{{ ipaadmin_principal if not ipaclient_use_otp | bool and
|
||||
ipaclient_keytab is not defined else '' }}"
|
||||
password: "{{ ipaadmin_password | default(omit) }}"
|
||||
keytab: "{{ ipaclient_keytab | default(omit) }}"
|
||||
#ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}"
|
||||
# ca_cert_file: "{{ ipaclient_ca_cert_file | default(omit) }}"
|
||||
kinit_attempts: "{{ ipaclient_kinit_attempts | default(omit) }}"
|
||||
register: result_ipaclient_join
|
||||
when: not ipaclient_on_master | bool and (not result_ipaclient_test_keytab.krb5_keytab_ok or ipaclient_force_join)
|
||||
when: not ipaclient_on_master | bool and
|
||||
(not result_ipaclient_test_keytab.krb5_keytab_ok or
|
||||
ipaclient_force_join)
|
||||
|
||||
- block:
|
||||
- fail:
|
||||
msg: "The krb5 configuration is not correct, please enable allow_repair to fix this."
|
||||
msg: >
|
||||
The krb5 configuration is not correct, please enable allow_repair
|
||||
to fix this.
|
||||
when: not result_ipaclient_test_keytab.krb5_conf_ok
|
||||
- fail:
|
||||
msg: "The IPA test failed, please enable allow_repair to fix this."
|
||||
when: not result_ipaclient_test_keytab.ping_test_ok
|
||||
- fail:
|
||||
msg: "The ca.crt file is missing, please enable allow_repair to fix this."
|
||||
msg: >
|
||||
The ca.crt file is missing, please enable allow_repair to fix this.
|
||||
when: not result_ipaclient_test_keytab.ca_crt_exists
|
||||
when: not ipaclient_on_master | bool and not result_ipaclient_join.changed and not ipaclient_allow_repair | bool and (result_ipaclient_test_keytab.krb5_keytab_ok or (result_ipaclient_join.already_joined is defined and result_ipaclient_join.already_joined))
|
||||
when: not ipaclient_on_master | bool and
|
||||
not result_ipaclient_join.changed and
|
||||
not ipaclient_allow_repair | bool and
|
||||
(result_ipaclient_test_keytab.krb5_keytab_ok or
|
||||
(result_ipaclient_join.already_joined is defined and
|
||||
result_ipaclient_join.already_joined))
|
||||
|
||||
- block:
|
||||
- name: Install - Configure IPA default.conf
|
||||
@@ -236,7 +265,7 @@
|
||||
hostname: "{{ result_ipaclient_test.hostname }}"
|
||||
sssd: "{{ result_ipaclient_test.sssd }}"
|
||||
force: "{{ ipaclient_force }}"
|
||||
#on_master: "{{ ipaclient_on_master }}"
|
||||
# on_master: "{{ ipaclient_on_master }}"
|
||||
when: not ipaclient_on_master | bool
|
||||
|
||||
- name: Install - IPA API calls for remaining enrollment parts
|
||||
@@ -244,7 +273,7 @@
|
||||
servers: "{{ result_ipaclient_test.servers }}"
|
||||
realm: "{{ result_ipaclient_test.realm }}"
|
||||
hostname: "{{ result_ipaclient_test.hostname }}"
|
||||
#debug: yes
|
||||
# debug: yes
|
||||
register: result_ipaclient_api
|
||||
|
||||
- name: Install - Fix IPA ca
|
||||
@@ -253,7 +282,9 @@
|
||||
realm: "{{ result_ipaclient_test.realm }}"
|
||||
basedn: "{{ result_ipaclient_test.basedn }}"
|
||||
allow_repair: "{{ ipaclient_allow_repair }}"
|
||||
when: not ipaclient_on_master | bool and result_ipaclient_test_keytab.krb5_keytab_ok and not result_ipaclient_test_keytab.ca_crt_exists
|
||||
when: not ipaclient_on_master | bool and
|
||||
result_ipaclient_test_keytab.krb5_keytab_ok and
|
||||
not result_ipaclient_test_keytab.ca_crt_exists
|
||||
|
||||
- name: Install - Create IPA NSS database
|
||||
ipaclient_setup_nss:
|
||||
@@ -302,16 +333,28 @@
|
||||
- name: Install - Configure NIS
|
||||
ipaclient_setup_nis:
|
||||
domain: "{{ result_ipaclient_test.domain }}"
|
||||
nisdomain: "{{ ipaclient_nisdomain | default(omit)}}"
|
||||
nisdomain: "{{ ipaclient_nisdomain | default(omit) }}"
|
||||
when: not ipaclient_no_nisdomain | bool
|
||||
|
||||
when: not (not ipaclient_on_master | bool and not result_ipaclient_join.changed and not ipaclient_allow_repair | bool and (result_ipaclient_test_keytab.krb5_keytab_ok or (result_ipaclient_join.already_joined is defined and result_ipaclient_join.already_joined)))
|
||||
when: not (not ipaclient_on_master | bool and
|
||||
not result_ipaclient_join.changed and
|
||||
not ipaclient_allow_repair | bool
|
||||
and (result_ipaclient_test_keytab.krb5_keytab_ok
|
||||
or (result_ipaclient_join.already_joined is defined
|
||||
and result_ipaclient_join.already_joined)))
|
||||
|
||||
when: not ansible_check_mode and not (result_ipaclient_test.client_already_configured and not ipaclient_allow_repair | bool and not ipaclient_force_join | bool)
|
||||
when: not ansible_check_mode and
|
||||
not (result_ipaclient_test.client_already_configured and
|
||||
not ipaclient_allow_repair | bool and not ipaclient_force_join | bool)
|
||||
|
||||
always:
|
||||
- name: Install - Restore original admin password if overwritten by OTP
|
||||
no_log: yes
|
||||
set_fact:
|
||||
ipaadmin_password: "{{ ipaadmin_orig_password }}"
|
||||
when: ipaclient_use_otp | bool and ipaadmin_orig_password is defined
|
||||
|
||||
- name: Cleanup leftover ccache
|
||||
file:
|
||||
path: "/etc/ipa/.dns_ccache"
|
||||
state: absent
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
- block:
|
||||
- name: Verify Python3 import
|
||||
script: py3test.py
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
---
|
||||
# tasks to uninstall IPA client
|
||||
|
||||
#- name: Uninstall - Include Python2/3 import test
|
||||
# import_tasks: "{{role_path}}/tasks/python_2_3_test.yml"
|
||||
# - name: Uninstall - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
|
||||
- name: Uninstall - Uninstall IPA client
|
||||
command: >
|
||||
@@ -14,8 +14,8 @@
|
||||
failed_when: uninstall.rc != 0 and uninstall.rc != 2
|
||||
changed_when: uninstall.rc == 0
|
||||
|
||||
#- name: Remove IPA client package
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipaclient_packages }}"
|
||||
# - name: Remove IPA client package
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipaclient_packages }}"
|
||||
|
||||
@@ -1,8 +0,0 @@
|
||||
---
|
||||
ipaconf_default_conf: /etc/ipa/default.conf
|
||||
|
||||
ipaconf_basedn:
|
||||
ipaconf_realm:
|
||||
ipaconf_domain:
|
||||
ipaconf_server:
|
||||
ipaconf_hostname:
|
||||
@@ -1,12 +0,0 @@
|
||||
galaxy_info:
|
||||
author: Thomas Woerner
|
||||
description: A role to configure IPA default.conf
|
||||
company: Red Hat, Inc
|
||||
|
||||
license: GPLv3
|
||||
|
||||
min_ansible_version: 2.0
|
||||
|
||||
galaxy_tags: [ 'identity', 'ipa']
|
||||
|
||||
dependencies: []
|
||||
@@ -1,13 +0,0 @@
|
||||
---
|
||||
- name: Backup IPA default.conf
|
||||
ipaclient_fstore:
|
||||
backup: "{{ ipaconf_default_conf }}"
|
||||
|
||||
- name: Template IPA default.conf
|
||||
template:
|
||||
src: default.conf.j2
|
||||
dest: "{{ ipaconf_default_conf }}"
|
||||
backup: yes
|
||||
owner: root
|
||||
group: root
|
||||
mode: 0644
|
||||
@@ -1,8 +0,0 @@
|
||||
[global]
|
||||
basedn = {{ ipaconf_basedn }}
|
||||
realm = {{ ipaconf_realm }}
|
||||
domain = {{ ipaconf_domain }}
|
||||
server = {{ ipaconf_server }}
|
||||
host = {{ ipaconf_hostname }}
|
||||
xmlrpc_uri = {{ 'https://' + ipaconf_server + '/ipa/xml' }}
|
||||
enable_ra = True
|
||||
@@ -1,2 +0,0 @@
|
||||
krb5_packages:
|
||||
- krb5-workstation
|
||||
@@ -4,6 +4,7 @@
|
||||
### basic ###
|
||||
ipareplica_no_host_dns: no
|
||||
ipareplica_skip_conncheck: no
|
||||
ipareplica_hidden_replica: no
|
||||
### server ###
|
||||
ipareplica_setup_adtrust: no
|
||||
ipareplica_setup_ca: no
|
||||
|
||||
@@ -180,7 +180,7 @@ def main():
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
|
||||
|
||||
@@ -107,7 +107,7 @@ def main():
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
config_setup_ca=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
),
|
||||
|
||||
@@ -69,13 +69,14 @@ def main():
|
||||
ansible_module = AnsibleModule(
|
||||
argument_spec = dict(
|
||||
hostname=dict(required=False),
|
||||
hidden_replica=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
### certificate system ###
|
||||
subject_base=dict(required=True),
|
||||
### additional ###
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
setup_ca=dict(required=True),
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
@@ -88,6 +89,7 @@ def main():
|
||||
|
||||
options = installer
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.hidden_replica = ansible_module.params.get('hidden_replica')
|
||||
### server ###
|
||||
### certificate system ###
|
||||
options.subject_base = ansible_module.params.get('subject_base')
|
||||
@@ -112,6 +114,7 @@ def main():
|
||||
env = gen_env_boostrap_finalize_core(paths.ETC_IPA,
|
||||
constants.DEFAULT_CONFIG)
|
||||
api_bootstrap_finalize(env)
|
||||
config = gen_ReplicaConfig()
|
||||
|
||||
remote_api = gen_remote_api(config_master_host_name, paths.ETC_IPA)
|
||||
installer._remote_api = remote_api
|
||||
@@ -122,11 +125,16 @@ def main():
|
||||
api.Backend.ldap2.connect()
|
||||
|
||||
with redirect_stdout(ansible_log):
|
||||
# Enable configured services and update DNS SRV records
|
||||
service.enable_services(options.host_name)
|
||||
if options.hidden_replica:
|
||||
# Set services to hidden
|
||||
service.hide_services(config.host_name)
|
||||
else:
|
||||
# Enable configured services
|
||||
service.enable_services(config.host_name)
|
||||
# update DNS SRV records. Although it's only really necessary in
|
||||
# enabled-service case, also perform update in hidden replica case.
|
||||
api.Command.dns_update_system_records()
|
||||
ca_servers = service.find_providing_servers('CA', api.Backend.ldap2,
|
||||
api)
|
||||
ca_servers = find_providing_servers('CA', api.Backend.ldap2, api=api)
|
||||
api.Backend.ldap2.disconnect()
|
||||
|
||||
# Everything installed properly, activate ipa service.
|
||||
@@ -134,12 +142,12 @@ def main():
|
||||
|
||||
# Print a warning if CA role is only installed on one server
|
||||
if len(ca_servers) == 1:
|
||||
msg = textwrap.dedent(u'''
|
||||
msg = u'''
|
||||
WARNING: The CA service is only installed on one server ({}).
|
||||
It is strongly recommended to install it on another server.
|
||||
Run ipa-ca-install(1) on another master to accomplish this.
|
||||
'''.format(ca_servers[0]))
|
||||
ansible_module.warn(msg)
|
||||
'''.format(ca_servers[0])
|
||||
ansible_module.debug(msg)
|
||||
|
||||
# done #
|
||||
|
||||
|
||||
@@ -134,11 +134,11 @@ def main():
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
config_setup_ca=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
config_ips=dict(required=False, type='list', default=[]),
|
||||
|
||||
@@ -278,9 +278,6 @@ def main():
|
||||
## check selinux status, http and DS ports, NTP conflicting services
|
||||
#common_check(options.no_ntp)
|
||||
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
|
||||
installer._enrollment_performed = False
|
||||
installer._top_dir = tempfile.mkdtemp("ipa")
|
||||
|
||||
@@ -296,10 +293,14 @@ def main():
|
||||
|
||||
# pylint: disable=no-member
|
||||
xmlrpc_uri = 'https://{}/ipa/xml'.format(ipautil.format_netloc(env.host))
|
||||
if hasattr(ipaldap, "realm_to_ldapi_uri"):
|
||||
realm_to_ldapi_uri = ipaldap.realm_to_ldapi_uri
|
||||
else:
|
||||
realm_to_ldapi_uri = installutils.realm_to_ldapi_uri
|
||||
api.bootstrap(in_server=True,
|
||||
context='installer',
|
||||
confdir=paths.ETC_IPA,
|
||||
ldap_uri=installutils.realm_to_ldapi_uri(env.realm),
|
||||
ldap_uri=realm_to_ldapi_uri(env.realm),
|
||||
xmlrpc_uri=xmlrpc_uri)
|
||||
# pylint: enable=no-member
|
||||
api.finalize()
|
||||
@@ -311,13 +312,19 @@ def main():
|
||||
config.host_name = api.env.host
|
||||
config.domain_name = api.env.domain
|
||||
config.master_host_name = api.env.server
|
||||
config.ca_host_name = api.env.ca_host
|
||||
if not api.env.ca_host or api.env.ca_host == api.env.host:
|
||||
# ca_host has not been configured explicitly, prefer source master
|
||||
config.ca_host_name = api.env.server
|
||||
else:
|
||||
# default to ca_host from IPA config
|
||||
config.ca_host_name = api.env.ca_host
|
||||
config.kra_host_name = config.ca_host_name
|
||||
config.ca_ds_port = 389
|
||||
config.setup_ca = options.setup_ca
|
||||
config.setup_kra = options.setup_kra
|
||||
config.dir = installer._top_dir
|
||||
config.basedn = api.env.basedn
|
||||
#config.hidden_replica = options.hidden_replica
|
||||
|
||||
# load and check certificates #
|
||||
|
||||
@@ -553,8 +560,11 @@ def main():
|
||||
ansible_log.debug("-- SEARCH FOR CA --")
|
||||
|
||||
# Find if any server has a CA
|
||||
ca_host = service.find_providing_server(
|
||||
'CA', conn, config.ca_host_name)
|
||||
if not hasattr(service, "find_providing_server"):
|
||||
_host = [config.ca_host_name]
|
||||
else:
|
||||
_host = config.ca_host_name
|
||||
ca_host = find_providing_server('CA', conn, _host)
|
||||
if ca_host is not None:
|
||||
config.ca_host_name = ca_host
|
||||
ca_enabled = True
|
||||
@@ -577,14 +587,17 @@ def main():
|
||||
|
||||
ansible_log.debug("-- SEARCH FOR KRA --")
|
||||
|
||||
kra_host = service.find_providing_server(
|
||||
'KRA', conn, config.kra_host_name)
|
||||
if not hasattr(service, "find_providing_server"):
|
||||
_host = [config.kra_host_name]
|
||||
else:
|
||||
_host = config.kra_host_name
|
||||
kra_host = find_providing_server('KRA', conn, _host)
|
||||
if kra_host is not None:
|
||||
config.kra_host_name = kra_host
|
||||
kra_enabled = True
|
||||
else:
|
||||
if options.setup_kra:
|
||||
logger.error("There is no KRA server in the domain, "
|
||||
logger.error("There is no active KRA server in the domain, "
|
||||
"can't setup a KRA clone")
|
||||
raise ScriptError(rval=3)
|
||||
kra_enabled = False
|
||||
@@ -676,6 +689,10 @@ def main():
|
||||
if add_to_ipaservers:
|
||||
os.environ['KRB5CCNAME'] = ccache
|
||||
|
||||
if hasattr(tasks, "configure_pkcs11_modules"):
|
||||
if tasks.configure_pkcs11_modules(fstore):
|
||||
ansible_log.info("Disabled p11-kit-proxy")
|
||||
|
||||
installer._ca_enabled = ca_enabled
|
||||
installer._kra_enabled = kra_enabled
|
||||
installer._ca_file = cafile
|
||||
|
||||
@@ -78,7 +78,7 @@ def main():
|
||||
### additional ###
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
config_setup_ca=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
|
||||
@@ -78,7 +78,7 @@ def main():
|
||||
### additional ###
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
config_setup_ca=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
|
||||
@@ -124,7 +124,7 @@ def main():
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
config_setup_ca=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
config_ips=dict(required=False, type='list', default=[]),
|
||||
|
||||
@@ -88,7 +88,7 @@ def main():
|
||||
### additional ###
|
||||
ccache=dict(required=True),
|
||||
_top_dir = dict(required=True),
|
||||
setup_ca=dict(required=True),
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
),
|
||||
supports_check_mode = True,
|
||||
|
||||
@@ -181,11 +181,11 @@ def main():
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
dirman_password=dict(required=True, no_log=True),
|
||||
config_setup_ca=dict(required=True),
|
||||
config_setup_ca=dict(required=True, type='bool'),
|
||||
config_master_host_name=dict(required=True),
|
||||
config_ca_host_name=dict(required=True),
|
||||
config_ips=dict(required=False, type='list', default=[]),
|
||||
|
||||
@@ -119,7 +119,7 @@ def main():
|
||||
_http_pkcs12_info = dict(required=False),
|
||||
_pkinit_pkcs12_info = dict(required=False),
|
||||
_top_dir = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True),
|
||||
_add_to_ipaservers = dict(required=True, type='bool'),
|
||||
_ca_subject=dict(required=True),
|
||||
_subject_base=dict(required=True),
|
||||
),
|
||||
|
||||
@@ -64,6 +64,7 @@ def main():
|
||||
realm=dict(required=False),
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
hidden_replica=dict(required=False, type='bool', default=False),
|
||||
### server ###
|
||||
setup_adtrust=dict(required=False, type='bool', default=False),
|
||||
setup_kra=dict(required=False, type='bool', default=False),
|
||||
@@ -106,6 +107,7 @@ def main():
|
||||
options.realm_name = ansible_module.params.get('realm')
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.hidden_replica = ansible_module.params.get('hidden_replica')
|
||||
### server ###
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
@@ -173,6 +175,10 @@ def main():
|
||||
# # options.setup_kra = False
|
||||
# # ansible_module.warn(msg="kra is not supported, disabling")
|
||||
|
||||
if options.hidden_replica and not hasattr(service, "hide_services"):
|
||||
ansible_module.fail_json(
|
||||
msg="Hidden replica is not supported in this version.")
|
||||
|
||||
# From ipa installer classes
|
||||
|
||||
# pkinit is not supported on DL0, don't allow related options
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
dependencies: []
|
||||
|
||||
galaxy_info:
|
||||
author: Thomas Woerner
|
||||
description: A role to setup an IPA domain replica
|
||||
company: Red Hat, Inc
|
||||
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
license: GPLv3
|
||||
|
||||
min_ansible_version: 2.0
|
||||
|
||||
#github_branch:
|
||||
|
||||
min_ansible_version: 2.8
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- 25
|
||||
- 26
|
||||
- 27
|
||||
- name: rhel
|
||||
- all
|
||||
- name: EL
|
||||
versions:
|
||||
- 7.3
|
||||
- 7.4
|
||||
|
||||
galaxy_tags: [ 'identity', 'ipa']
|
||||
|
||||
dependencies: []
|
||||
- 7
|
||||
- 8
|
||||
galaxy_tags:
|
||||
- identity
|
||||
- ipa
|
||||
- freeipa
|
||||
|
||||
@@ -79,6 +79,12 @@ if NUM_VERSION >= 40600:
|
||||
adtrust, bindinstance, ca, certs, dns, dsinstance, httpinstance,
|
||||
installutils, kra, krbinstance,
|
||||
otpdinstance, custodiainstance, service, upgradeinstance)
|
||||
try:
|
||||
from ipaserver.masters import (
|
||||
find_providing_servers, find_providing_server)
|
||||
except ImportError:
|
||||
from ipaserver.install.service import (
|
||||
find_providing_servers, find_providing_server)
|
||||
from ipaserver.install.installutils import (
|
||||
ReplicaConfig, load_pkcs12, is_ipa_configured)
|
||||
from ipaserver.install.replication import (
|
||||
@@ -162,6 +168,9 @@ class AnsibleModuleLog():
|
||||
def debug(self, msg):
|
||||
self.module.debug(msg)
|
||||
|
||||
def info(self, msg):
|
||||
self.module.debug(msg)
|
||||
|
||||
def write(self, msg):
|
||||
self.module.debug(msg)
|
||||
#self.module.warn(msg)
|
||||
|
||||
@@ -25,8 +25,8 @@
|
||||
|
||||
when: ipareplica_install_packages | bool
|
||||
|
||||
- name: Install - Include Python2/3 import test
|
||||
import_tasks: "{{role_path}}/tasks/python_2_3_test.yml"
|
||||
#- name: Install - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
|
||||
- name: Install - Set default principal if no keytab is given
|
||||
set_fact:
|
||||
@@ -36,14 +36,17 @@
|
||||
- name: Install - Replica installation test
|
||||
ipareplica_test:
|
||||
### basic ###
|
||||
#dm_password: "{{ ipadm_password | default(omit) }}"
|
||||
#password: "{{ ipaadmin_password | default(omit) }}"
|
||||
# dm_password: "{{ ipadm_password | default(omit) }}"
|
||||
# password: "{{ ipaadmin_password | default(omit) }}"
|
||||
ip_addresses: "{{ ipareplica_ip_addresses | default([]) }}"
|
||||
domain: "{{ ipareplica_domain | default(ipaserver_domain) | default(omit) }}"
|
||||
servers: "{{ groups.ipaservers | default(groups.ipaserver) | default(omit) }}"
|
||||
domain: "{{ ipareplica_domain | default(ipaserver_domain) |
|
||||
default(omit) }}"
|
||||
servers: "{{ groups.ipaservers | default(groups.ipaserver) |
|
||||
default(omit) }}"
|
||||
realm: "{{ ipareplica_realm | default(omit) }}"
|
||||
hostname: "{{ ipareplica_hostname | default(ansible_fqdn) }}"
|
||||
ca_cert_files: "{{ ipareplica_ca_cert_files | default([]) }}"
|
||||
hidden_replica: "{{ ipareplica_hidden_replica }}"
|
||||
### server ###
|
||||
setup_adtrust: "{{ ipareplica_setup_adtrust }}"
|
||||
setup_kra: "{{ ipareplica_setup_kra }}"
|
||||
@@ -83,15 +86,8 @@
|
||||
ipaclient_realm: "{{ result_ipareplica_test.realm }}"
|
||||
ipaclient_servers: ["{{ result_ipareplica_test.server }}"]
|
||||
ipaclient_hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
#ipaclient_keytab: "{{ ipaclient_keytab }}"
|
||||
#ipaclient_mkhomedir: "{{ ipaclient_mkhomedir }}"
|
||||
#ipaclient_force_join: "{{ ipaclient_force_join }}"
|
||||
##ipaclient_no_ntp: "{{ ipaclient_no_ntp }}"
|
||||
ipaclient_no_ntp: "{{ result_ipareplica_test.ipa_python_version < 40690 }}"
|
||||
#ipaclient_ssh_trust_dns: "{{ ipaclient_ssh_trust_dns }}"
|
||||
##ipaclient_no_ssh: "{{ ipaclient_no_ssh }}"
|
||||
##ipaclient_no_sshd: "{{ ipaclient_no_sshd }}"
|
||||
##ipaclient_no_dns_sshfp: "{{ ipaclient_no_dns_sshfp }}"
|
||||
ipaclient_no_ntp: "{{ result_ipareplica_test.ipa_python_version
|
||||
< 40690 }}"
|
||||
ipaclient_install_packages: "{{ ipareplica_install_packages }}"
|
||||
when: not result_ipareplica_test.client_enrolled
|
||||
|
||||
@@ -101,7 +97,8 @@
|
||||
--permanent
|
||||
--add-service=freeipa-ldap
|
||||
--add-service=freeipa-ldaps
|
||||
--add-service=freeipa-replication
|
||||
{{ "--add-service=freeipa-trust" if result_ipareplica_test.setup_adtrust
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipareplica_setup_dns | bool else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipareplica_setup_firewalld | bool
|
||||
@@ -111,7 +108,8 @@
|
||||
firewall-cmd
|
||||
--add-service=freeipa-ldap
|
||||
--add-service=freeipa-ldaps
|
||||
--add-service=freeipa-replication
|
||||
{{ "--add-service=freeipa-trust" if result_ipareplica_test.setup_adtrust
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipareplica_setup_dns | bool else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipareplica_setup_firewalld | bool
|
||||
@@ -173,7 +171,8 @@
|
||||
### server ###
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
@@ -189,7 +188,8 @@
|
||||
- name: Install - Set dirman password
|
||||
no_log: yes
|
||||
set_fact:
|
||||
ipareplica_dirman_password: "{{ result_ipareplica_master_password.password }}"
|
||||
ipareplica_dirman_password:
|
||||
"{{ result_ipareplica_master_password.password }}"
|
||||
|
||||
- name: Install - Setup certmonger
|
||||
ipareplica_setup_certmonger:
|
||||
@@ -234,7 +234,8 @@
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||
config_ips: "{{ result_ipareplica_prepare.config_ips }}"
|
||||
register: result_ipareplica_install_ca_certs
|
||||
@@ -280,7 +281,8 @@
|
||||
_subject_base: "{{ result_ipareplica_prepare._subject_base }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||
config_ips: "{{ result_ipareplica_prepare.config_ips }}"
|
||||
register: result_ipareplica_setup_ds
|
||||
@@ -310,7 +312,8 @@
|
||||
secondary_rid_base: "{{ ipareplica_secondary_rid_base | default(omit) }}"
|
||||
### additional ###
|
||||
server: "{{ result_ipareplica_test.server }}"
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
@@ -334,7 +337,8 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
@@ -349,7 +353,8 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
@@ -368,7 +373,8 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
@@ -387,7 +393,8 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
@@ -404,7 +411,8 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
@@ -431,8 +439,10 @@
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_install_ca_certs.config_ca_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_ca_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_ca_host_name }}"
|
||||
config_ips: "{{ result_ipareplica_prepare.config_ips }}"
|
||||
when: result_ipareplica_prepare._ca_enabled
|
||||
|
||||
@@ -442,11 +452,12 @@
|
||||
setup_ca: "{{ ipareplica_setup_ca }}"
|
||||
setup_kra: "{{ result_ipareplica_test.setup_kra }}"
|
||||
no_pkinit: "{{ ipareplica_no_pkinit }}"
|
||||
#no_ui_redirect: "{{ ipareplica_no_ui_redirect }}"
|
||||
# no_ui_redirect: "{{ ipareplica_no_ui_redirect }}"
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
@@ -465,7 +476,8 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
@@ -498,7 +510,8 @@
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
server: "{{ result_ipareplica_test.server }}"
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
installer_ccache: "{{ result_ipareplica_prepare.installer_ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
@@ -522,11 +535,12 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_install_ca_certs.config_master_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
_ca_file: "{{ result_ipareplica_prepare._ca_file }}"
|
||||
#_pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
# _pkinit_pkcs12_info: "{{ result_ipareplica_prepare._pkinit_pkcs12_info }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
dirman_password: "{{ ipareplica_dirman_password }}"
|
||||
|
||||
@@ -540,7 +554,8 @@
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_ca_host_name: "{{ result_ipareplica_prepare.config_ca_host_name }}"
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_ca_enabled: "{{ result_ipareplica_prepare._ca_enabled }}"
|
||||
@@ -560,7 +575,8 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
|
||||
- name: Install - Promote openldap.conf
|
||||
ipareplica_promote_openldap_conf:
|
||||
@@ -572,7 +588,8 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
config_setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
|
||||
- name: Install - Setup DNS
|
||||
ipareplica_setup_dns:
|
||||
@@ -585,13 +602,16 @@
|
||||
### dns ###
|
||||
zonemgr: "{{ ipareplica_zonemgr | default(omit) }}"
|
||||
forwarders: "{{ ipareplica_forwarders | default([]) }}"
|
||||
forward_policy: "{{ result_ipareplica_prepare.forward_policy if result_ipareplica_prepare.forward_policy is not none else omit }}"
|
||||
forward_policy: "{{ result_ipareplica_prepare.forward_policy if
|
||||
result_ipareplica_prepare.forward_policy is
|
||||
not none else omit }}"
|
||||
no_dnssec_validation: "{{ ipareplica_no_dnssec_validation }}"
|
||||
### additional ###
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
|
||||
- name: Install - Setup adtrust
|
||||
ipareplica_setup_adtrust:
|
||||
@@ -607,24 +627,27 @@
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
adtrust_netbios_name: "{{ result_ipareplica_prepare.adtrust_netbios_name }}"
|
||||
adtrust_reset_netbios_name: "{{ result_ipareplica_prepare.adtrust_reset_netbios_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
adtrust_netbios_name:
|
||||
"{{ result_ipareplica_prepare.adtrust_netbios_name }}"
|
||||
adtrust_reset_netbios_name:
|
||||
"{{ result_ipareplica_prepare.adtrust_reset_netbios_name }}"
|
||||
when: result_ipareplica_test.setup_adtrust
|
||||
|
||||
#- name: Install - Disconnect backend
|
||||
# ipareplica_backend_disconnect:
|
||||
|
||||
- name: Install - Enable IPA
|
||||
ipareplica_enable_ipa:
|
||||
hostname: "{{ result_ipareplica_test.hostname }}"
|
||||
hidden_replica: "{{ ipareplica_hidden_replica }}"
|
||||
### server ###
|
||||
### certificate system ###
|
||||
subject_base: "{{ result_ipareplica_prepare.subject_base }}"
|
||||
### additional ###
|
||||
ccache: "{{ result_ipareplica_prepare.ccache }}"
|
||||
_top_dir: "{{ result_ipareplica_prepare._top_dir }}"
|
||||
setup_ca: "{{ result_ipareplica_prepare.config_setup_ca }}"
|
||||
config_master_host_name: "{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
config_master_host_name:
|
||||
"{{ result_ipareplica_prepare.config_master_host_name }}"
|
||||
register: result_ipareplica_enable_ipa
|
||||
|
||||
- name: Install - Cleanup root IPA cache
|
||||
@@ -633,4 +656,6 @@
|
||||
state: absent
|
||||
when: result_ipareplica_enable_ipa.changed
|
||||
|
||||
when: not ansible_check_mode and not (result_ipareplica_test.client_already_configured is defined or result_ipareplica_test.server_already_configured is defined)
|
||||
when: not ansible_check_mode and
|
||||
not (result_ipareplica_test.client_already_configured is defined or
|
||||
result_ipareplica_test.server_already_configured is defined)
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
- block:
|
||||
- name: Verify Python3 import
|
||||
script: py3test.py
|
||||
@@ -13,7 +14,8 @@
|
||||
|
||||
- name: Fail for IPA 4.5.90
|
||||
fail: msg="You need to install python2 bindings for ipa server usage"
|
||||
when: result_py3test.rc != 0 and "not usable with python3" in result_py3test.stdout
|
||||
when: result_py3test.rc != 0 and "not usable with python3" in
|
||||
result_py3test.stdout
|
||||
|
||||
- name: Set python interpreter to 2
|
||||
set_fact:
|
||||
|
||||
@@ -1,37 +1,41 @@
|
||||
---
|
||||
# tasks to uninstall IPA replica
|
||||
|
||||
#- name: Uninstall - Include Python2/3 import test
|
||||
# import_tasks: "{{role_path}}/tasks/python_2_3_test.yml"
|
||||
# - name: Uninstall - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
|
||||
- name: Uninstall - Uninstall IPA replica
|
||||
command: >
|
||||
/usr/sbin/ipa-server-install
|
||||
--uninstall
|
||||
-U
|
||||
{{ "--ignore-topology-disconnect" if ipareplica_ignore_topology_disconnect | bool else "" }}
|
||||
{{ "--ignore-last-of-role" if ipareplica_ignore_last_of_role | bool else "" }}
|
||||
{{ "--ignore-topology-disconnect" if
|
||||
ipareplica_ignore_topology_disconnect | bool else "" }}
|
||||
{{ "--ignore-last-of-role" if ipareplica_ignore_last_of_role | bool
|
||||
else "" }}
|
||||
register: result_uninstall
|
||||
# 2 means that uninstall failed because IPA replica was not configured
|
||||
failed_when: result_uninstall.rc != 0 and "'Env' object has no attribute 'basedn'" not in result_uninstall.stderr
|
||||
#IPA server is not configured on this system" not in result_uninstall.stdout_lines
|
||||
#changed_when: result_uninstall.rc == 0
|
||||
#until: result_uninstall.rc == 0
|
||||
failed_when: result_uninstall.rc != 0 and "'Env' object
|
||||
has no attribute 'basedn'" not in result_uninstall.stderr
|
||||
# IPA server is not configured on this system" not in
|
||||
# result_uninstall.stdout_lines
|
||||
changed_when: result_uninstall.rc == 0
|
||||
# until: result_uninstall.rc == 0
|
||||
retries: 2
|
||||
delay: 1
|
||||
|
||||
- name: Uninstall - Remove all replication agreements and data about replica
|
||||
command: >
|
||||
/usr/sbin/ipa-replica-manage
|
||||
del
|
||||
{{ ipareplica_hostname | default(ansible_fqdn) }}
|
||||
--force
|
||||
--password={{ ipadm_password }}
|
||||
failed_when: False
|
||||
delegate_to: "{{ groups.ipaserver[0] | default(fail) }}"
|
||||
#- name: Uninstall - Remove all replication agreements and data about replica
|
||||
# command: >
|
||||
# /usr/sbin/ipa-replica-manage
|
||||
# del
|
||||
# {{ ipareplica_hostname | default(ansible_fqdn) }}
|
||||
# --force
|
||||
# --password={{ ipadm_password }}
|
||||
# failed_when: False
|
||||
# delegate_to: "{{ groups.ipaserver[0] | default(fail) }}"
|
||||
|
||||
#- name: Remove IPA replica packages
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipareplica_packages }}"
|
||||
# - name: Remove IPA replica packages
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipareplica_packages }}"
|
||||
|
||||
@@ -129,6 +129,9 @@ Variables
|
||||
**ipaserver_no_host_dns** - Do not use DNS for hostname lookup during installation.
|
||||
(bool, optional)
|
||||
|
||||
**ipaserver_pki_config_override** - Path to ini file with config overrides.
|
||||
(string, optional)
|
||||
|
||||
**ipaserver_no_dnssec_validation** - Disable DNSSEC validation on this server.
|
||||
(bool, optional)
|
||||
|
||||
@@ -109,7 +109,7 @@ def main():
|
||||
forwarders=dict(required=False, type='list', default=[]),
|
||||
no_forwarders=dict(required=False, type='bool', default=False),
|
||||
auto_forwarders=dict(required=False, type='bool', default=False),
|
||||
forward_policy=dict(required=False),
|
||||
forward_policy=dict(default=None, choices=['first', 'only']),
|
||||
no_dnssec_validation=dict(required=False, type='bool',
|
||||
default=False),
|
||||
### ad trust ###
|
||||
@@ -181,6 +181,15 @@ def main():
|
||||
fstore = sysrestore.FileStore(paths.SYSRESTORE)
|
||||
sstore = sysrestore.StateFile(paths.SYSRESTORE)
|
||||
|
||||
# subject_base
|
||||
if not options.subject_base:
|
||||
options.subject_base = str(default_subject_base(options.realm_name))
|
||||
# set options.subject for old ipa releases
|
||||
options.subject = options.subject_base
|
||||
|
||||
if not options.ca_subject:
|
||||
options.ca_subject = str(default_ca_subject_dn(options.subject_base))
|
||||
|
||||
# Configuration for ipalib, we will bootstrap and finalize later, after
|
||||
# we are sure we have the configuration file ready.
|
||||
cfg = dict(
|
||||
@@ -268,7 +277,29 @@ def main():
|
||||
if _update_hosts_file:
|
||||
update_hosts_file(ip_addresses, options.host_name, fstore)
|
||||
|
||||
ansible_module.exit_json(changed=True)
|
||||
if hasattr(tasks, "configure_pkcs11_modules"):
|
||||
if tasks.configure_pkcs11_modules(fstore):
|
||||
ansible_log.info("Disabled p11-kit-proxy")
|
||||
|
||||
ansible_module.exit_json(changed=True,
|
||||
### basic ###
|
||||
ip_addresses=[ str(ip) for ip in ip_addresses ],
|
||||
### certificate system ###
|
||||
subject_base=options.subject_base,
|
||||
_subject_base=options._subject_base,
|
||||
ca_subject=options.ca_subject,
|
||||
_ca_subject=options._ca_subject,
|
||||
### dns ###
|
||||
reverse_zones=options.reverse_zones,
|
||||
forward_policy=options.forward_policy,
|
||||
forwarders=options.forwarders,
|
||||
no_dnssec_validation=options.no_dnssec_validation,
|
||||
### additional ###
|
||||
dns_ip_addresses=[ str(ip) for ip
|
||||
in dns.ip_addresses ],
|
||||
dns_reverse_zones=dns.reverse_zones,
|
||||
adtrust_netbios_name=adtrust.netbios_name,
|
||||
adtrust_reset_netbios_name=adtrust.reset_netbios_name)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -91,6 +91,7 @@ def main():
|
||||
realm=dict(required=True),
|
||||
hostname=dict(required=False),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
pki_config_override=dict(required=False),
|
||||
### server ###
|
||||
setup_adtrust=dict(required=False, type='bool', default=False),
|
||||
setup_kra=dict(required=False, type='bool', default=False),
|
||||
@@ -101,7 +102,7 @@ def main():
|
||||
no_hbac_allow=dict(required=False, type='bool', default=False),
|
||||
no_pkinit=dict(required=False, type='bool', default=False),
|
||||
dirsrv_config_file=dict(required=False),
|
||||
dirsrv_cert_files=dict(required=False),
|
||||
dirsrv_cert_files=dict(required=False, type='list'),
|
||||
_dirsrv_pkcs12_info=dict(required=False),
|
||||
### certificate system ###
|
||||
external_ca=dict(required=False, type='bool', default=False),
|
||||
@@ -136,6 +137,8 @@ def main():
|
||||
options.realm_name = ansible_module.params.get('realm')
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
options.pki_config_override = ansible_module.params.get(
|
||||
'pki_config_override')
|
||||
### server ###
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
|
||||
@@ -183,7 +183,8 @@ def main():
|
||||
subject_base=options.subject_base,
|
||||
auto_redirect=not options.no_ui_redirect,
|
||||
ca_is_configured=options.setup_ca)
|
||||
tasks.restore_context(paths.CACHE_IPA_SESSIONS)
|
||||
if hasattr(paths, "CACHE_IPA_SESSIONS"):
|
||||
tasks.restore_context(paths.CACHE_IPA_SESSIONS)
|
||||
|
||||
ca.set_subject_base_in_config(options.subject_base)
|
||||
|
||||
|
||||
@@ -58,6 +58,7 @@ def main():
|
||||
setup_ca=dict(required=True, type='bool'),
|
||||
setup_kra=dict(required=True, type='bool'),
|
||||
realm=dict(required=True),
|
||||
pki_config_override=dict(required=False),
|
||||
),
|
||||
)
|
||||
|
||||
@@ -71,6 +72,8 @@ def main():
|
||||
options.setup_ca = ansible_module.params.get('setup_ca')
|
||||
options.setup_kra = ansible_module.params.get('setup_kra')
|
||||
options.realm_name = ansible_module.params.get('realm')
|
||||
options.pki_config_override = ansible_module.params.get(
|
||||
'pki_config_override')
|
||||
options.promote = False # first master, no promotion
|
||||
|
||||
# init ##########################################################
|
||||
|
||||
@@ -60,12 +60,12 @@ def main():
|
||||
dm_password=dict(required=True, no_log=True),
|
||||
password=dict(required=True, no_log=True),
|
||||
master_password=dict(required=False, no_log=True),
|
||||
ip_addresses=dict(required=False, type='list', default=[]),
|
||||
domain=dict(required=False),
|
||||
realm=dict(required=False),
|
||||
hostname=dict(required=False),
|
||||
ca_cert_files=dict(required=False, type='list', default=[]),
|
||||
no_host_dns=dict(required=False, type='bool', default=False),
|
||||
pki_config_override=dict(required=False),
|
||||
### server ###
|
||||
setup_adtrust=dict(required=False, type='bool', default=False),
|
||||
setup_kra=dict(required=False, type='bool', default=False),
|
||||
@@ -134,13 +134,13 @@ def main():
|
||||
options.dm_password = ansible_module.params.get('dm_password')
|
||||
options.admin_password = ansible_module.params.get('password')
|
||||
options.master_password = ansible_module.params.get('master_password')
|
||||
options.ip_addresses = ansible_module_get_parsed_ip_addresses(
|
||||
ansible_module)
|
||||
options.domain_name = ansible_module.params.get('domain')
|
||||
options.realm_name = ansible_module.params.get('realm')
|
||||
options.host_name = ansible_module.params.get('hostname')
|
||||
options.ca_cert_files = ansible_module.params.get('ca_cert_files')
|
||||
options.no_host_dns = ansible_module.params.get('no_host_dns')
|
||||
options.pki_config_override = ansible_module.params.get(
|
||||
'pki_config_override')
|
||||
### server ###
|
||||
options.setup_adtrust = ansible_module.params.get('setup_adtrust')
|
||||
options.setup_dns = ansible_module.params.get('setup_dns')
|
||||
@@ -213,6 +213,19 @@ def main():
|
||||
# options.setup_kra = False
|
||||
# ansible_module.warn(msg="kra is not supported, disabling")
|
||||
|
||||
if options.pki_config_override is not None:
|
||||
if PKIIniLoader is None:
|
||||
ansible_module.warn("The use of pki_config_override is not "
|
||||
"supported for this IPA version")
|
||||
else:
|
||||
# From DogtagInstallInterface @pki_config_override.validator
|
||||
try:
|
||||
PKIIniLoader.verify_pki_config_override(
|
||||
options.pki_config_override)
|
||||
except ValueError as e:
|
||||
ansible_module.fail_json(
|
||||
msg="pki_config_override: %s" % str(e))
|
||||
|
||||
# validation #############################################################
|
||||
|
||||
if options.dm_password is None:
|
||||
@@ -544,33 +557,39 @@ def main():
|
||||
|
||||
# host name
|
||||
if options.host_name:
|
||||
options.host_default = options.host_name
|
||||
host_default = options.host_name
|
||||
else:
|
||||
options.host_default = get_fqdn()
|
||||
host_default = get_fqdn()
|
||||
|
||||
try:
|
||||
verify_fqdn(options.host_default, options.no_host_dns)
|
||||
options.host_name = options.host_default
|
||||
verify_fqdn(host_default, options.no_host_dns)
|
||||
host_name = host_default
|
||||
except BadHostError as e:
|
||||
ansible_module.fail_json(msg=e)
|
||||
options.host_name = options.host_name.lower()
|
||||
|
||||
host_name = host_name.lower()
|
||||
|
||||
if not options.domain_name:
|
||||
options.domain_name = options.host_name[options.host_name.find(".")+1:]
|
||||
domain_name = host_name[host_name.find(".")+1:]
|
||||
try:
|
||||
validate_domain_name(options.domain_name)
|
||||
validate_domain_name(domain_name)
|
||||
except ValueError as e:
|
||||
ansible_module.fail_json(msg="Invalid domain name: %s" % unicode(e))
|
||||
options.domain_name = options.domain_name.lower()
|
||||
else:
|
||||
domain_name = options.domain_name
|
||||
|
||||
domain_name = domain_name.lower()
|
||||
|
||||
if not options.realm_name:
|
||||
options.realm_name = options.domain_name
|
||||
options.realm_name = options.realm_name.upper()
|
||||
realm_name = domain_name.upper()
|
||||
else:
|
||||
realm_name = options.realm_name.upper()
|
||||
|
||||
argspec = inspect.getargspec(validate_domain_name)
|
||||
if "entity" in argspec.args:
|
||||
# NUM_VERSION >= 40690:
|
||||
try:
|
||||
validate_domain_name(options.realm_name, entity="realm")
|
||||
validate_domain_name(realm_name, entity="realm")
|
||||
except ValueError as e:
|
||||
raise ScriptError("Invalid realm name: {}".format(unicode(e)))
|
||||
|
||||
@@ -578,7 +597,7 @@ def main():
|
||||
# If domain name and realm does not match, IPA server will not be able
|
||||
# to establish trust with Active Directory. Fail.
|
||||
|
||||
if options.domain_name.upper() != options.realm_name:
|
||||
if domain_name.upper() != realm_name:
|
||||
ansible_module.warn(
|
||||
"Realm name does not match the domain name: "
|
||||
"You will not be able to establish trusts with Active "
|
||||
@@ -605,7 +624,7 @@ def main():
|
||||
key_password=options.http_pin,
|
||||
key_nickname=options.http_cert_name,
|
||||
ca_cert_files=options.ca_cert_files,
|
||||
host_name=options.host_name)
|
||||
host_name=host_name)
|
||||
http_pkcs12_info = (http_pkcs12_file.name, options.http_pin)
|
||||
|
||||
if options.dirsrv_cert_files:
|
||||
@@ -617,7 +636,7 @@ def main():
|
||||
key_password=options.dirsrv_pin,
|
||||
key_nickname=options.dirsrv_cert_name,
|
||||
ca_cert_files=options.ca_cert_files,
|
||||
host_name=options.host_name)
|
||||
host_name=host_name)
|
||||
dirsrv_pkcs12_info = (dirsrv_pkcs12_file.name, options.dirsrv_pin)
|
||||
|
||||
if options.pkinit_cert_files:
|
||||
@@ -629,7 +648,7 @@ def main():
|
||||
key_password=options.pkinit_pin,
|
||||
key_nickname=options.pkinit_cert_name,
|
||||
ca_cert_files=options.ca_cert_files,
|
||||
realm_name=options.realm_name)
|
||||
realm_name=realm_name)
|
||||
pkinit_pkcs12_info = (pkinit_pkcs12_file.name, options.pkinit_pin)
|
||||
|
||||
if (options.http_cert_files and options.dirsrv_cert_files and
|
||||
@@ -644,114 +663,15 @@ def main():
|
||||
"Apache Server SSL certificate and PKINIT KDC "
|
||||
"certificate are not signed by the same CA certificate")
|
||||
|
||||
# subject_base
|
||||
if not options.subject_base:
|
||||
options.subject_base = str(default_subject_base(options.realm_name))
|
||||
# set options.subject for old ipa releases
|
||||
options.subject = options.subject_base
|
||||
|
||||
if not options.ca_subject:
|
||||
options.ca_subject = str(default_ca_subject_dn(options.subject_base))
|
||||
|
||||
# temporary ipa configuration ###########################################
|
||||
|
||||
ipa_tempdir = tempfile.mkdtemp(prefix="ipaconf")
|
||||
try:
|
||||
# Configuration for ipalib, we will bootstrap and finalize later, after
|
||||
# we are sure we have the configuration file ready.
|
||||
cfg = dict(
|
||||
context='installer',
|
||||
confdir=ipa_tempdir,
|
||||
in_server=True,
|
||||
# make sure host name specified by user is used instead of default
|
||||
host=options.host_name,
|
||||
)
|
||||
if options.setup_ca:
|
||||
# we have an IPA-integrated CA
|
||||
cfg['ca_host'] = options.host_name
|
||||
|
||||
# Create the management framework config file and finalize api
|
||||
target_fname = "%s/default.conf" % ipa_tempdir
|
||||
fd = open(target_fname, "w")
|
||||
fd.write("[global]\n")
|
||||
fd.write("host=%s\n" % options.host_name)
|
||||
fd.write("basedn=%s\n" % ipautil.realm_to_suffix(options.realm_name))
|
||||
fd.write("realm=%s\n" % options.realm_name)
|
||||
fd.write("domain=%s\n" % options.domain_name)
|
||||
fd.write("xmlrpc_uri=https://%s/ipa/xml\n" % ipautil.format_netloc(options.host_name))
|
||||
fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" %
|
||||
installutils.realm_to_serverid(options.realm_name))
|
||||
if options.setup_ca:
|
||||
fd.write("enable_ra=True\n")
|
||||
fd.write("ra_plugin=dogtag\n")
|
||||
fd.write("dogtag_version=10\n")
|
||||
else:
|
||||
fd.write("enable_ra=False\n")
|
||||
fd.write("ra_plugin=none\n")
|
||||
fd.write("mode=production\n")
|
||||
fd.close()
|
||||
|
||||
# Must be readable for everyone
|
||||
os.chmod(target_fname, 0o644)
|
||||
|
||||
api.bootstrap(**cfg)
|
||||
api.finalize()
|
||||
|
||||
# install checks ####################################################
|
||||
|
||||
if options.setup_ca:
|
||||
ca.install_check(False, None, options)
|
||||
|
||||
if options.setup_kra:
|
||||
kra.install_check(api, None, options)
|
||||
|
||||
if options.setup_dns:
|
||||
with redirect_stdout(ansible_log):
|
||||
dns.install_check(False, api, False, options, options.host_name)
|
||||
ip_addresses = dns.ip_addresses
|
||||
else:
|
||||
ip_addresses = get_server_ip_address(options.host_name,
|
||||
False, False,
|
||||
options.ip_addresses)
|
||||
|
||||
# check addresses here, dns ansible_module is doing own check
|
||||
no_matching_interface_for_ip_address_warning(ip_addresses)
|
||||
|
||||
options.ip_addresses = ip_addresses
|
||||
options.reverse_zones = dns.reverse_zones
|
||||
instance_name = "-".join(options.realm_name.split("."))
|
||||
dirsrv = services.knownservices.dirsrv
|
||||
if (options.external_cert_files
|
||||
and dirsrv.is_installed(instance_name)
|
||||
and not dirsrv.is_running(instance_name)):
|
||||
logger.debug('Starting Directory Server')
|
||||
services.knownservices.dirsrv.start(instance_name)
|
||||
|
||||
if options.setup_adtrust:
|
||||
adtrust.install_check(False, options, api)
|
||||
|
||||
except (RuntimeError, ValueError, ScriptError) as e:
|
||||
ansible_module.fail_json(msg=str(e))
|
||||
|
||||
finally:
|
||||
try:
|
||||
shutil.rmtree(ipa_tempdir, ignore_errors=True)
|
||||
except OSError:
|
||||
ansible_module.fail_json(msg="Could not remove %s" % ipa_tempdir)
|
||||
|
||||
# Always set _host_name_overridden
|
||||
options._host_name_overridden = bool(options.host_name)
|
||||
|
||||
# done ##################################################################
|
||||
|
||||
ansible_module.exit_json(changed=False,
|
||||
ipa_python_version=IPA_PYTHON_VERSION,
|
||||
### basic ###
|
||||
domain=options.domain_name,
|
||||
realm=options.realm_name,
|
||||
ip_addresses=[ str(ip) for ip in ip_addresses ],
|
||||
hostname=options.host_name,
|
||||
_hostname_overridden=options._host_name_overridden,
|
||||
realm=realm_name,
|
||||
hostname=host_name,
|
||||
_hostname_overridden=bool(options.host_name),
|
||||
no_host_dns=options.no_host_dns,
|
||||
### server ###
|
||||
setup_adtrust=options.setup_adtrust,
|
||||
@@ -770,27 +690,12 @@ def main():
|
||||
_pkinit_pkcs12_file=pkinit_pkcs12_file,
|
||||
_pkinit_pkcs12_info=pkinit_pkcs12_info,
|
||||
_pkinit_ca_cert=pkinit_ca_cert,
|
||||
### certificate system ###
|
||||
subject_base=options.subject_base,
|
||||
_subject_base=options._subject_base,
|
||||
ca_subject=options.ca_subject,
|
||||
_ca_subject=options._ca_subject,
|
||||
### dns ###
|
||||
reverse_zones=options.reverse_zones,
|
||||
forward_policy=options.forward_policy,
|
||||
forwarders=options.forwarders,
|
||||
no_dnssec_validation=options.no_dnssec_validation,
|
||||
### ad trust ###
|
||||
rid_base=options.rid_base,
|
||||
secondary_rid_base=options.secondary_rid_base,
|
||||
### additional ###
|
||||
_installation_cleanup=_installation_cleanup,
|
||||
domainlevel=options.domainlevel,
|
||||
dns_ip_addresses=[ str(ip) for ip
|
||||
in dns.ip_addresses ],
|
||||
dns_reverse_zones=dns.reverse_zones,
|
||||
adtrust_netbios_name=adtrust.netbios_name,
|
||||
adtrust_reset_netbios_name=adtrust.reset_netbios_name)
|
||||
domainlevel=options.domainlevel)
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
||||
@@ -1,27 +1,20 @@
|
||||
dependencies: []
|
||||
|
||||
galaxy_info:
|
||||
author: Thomas Woerner
|
||||
description: A role to setup an iPA domain server
|
||||
company: Red Hat, Inc
|
||||
|
||||
# issue_tracker_url: http://example.com/issue/tracker
|
||||
|
||||
license: GPLv3
|
||||
|
||||
min_ansible_version: 2.0
|
||||
|
||||
#github_branch:
|
||||
|
||||
min_ansible_version: 2.8
|
||||
platforms:
|
||||
- name: Fedora
|
||||
versions:
|
||||
- 25
|
||||
- 26
|
||||
- 27
|
||||
- name: rhel
|
||||
- all
|
||||
- name: EL
|
||||
versions:
|
||||
- 7.3
|
||||
- 7.4
|
||||
|
||||
galaxy_tags: [ 'identity', 'ipa']
|
||||
|
||||
dependencies: []
|
||||
- 7
|
||||
- 8
|
||||
galaxy_tags:
|
||||
- identity
|
||||
- ipa
|
||||
- freeipa
|
||||
|
||||
@@ -101,6 +101,10 @@ if NUM_VERSION >= 40500:
|
||||
from ipaserver.install.server.install import (
|
||||
check_dirsrv, validate_admin_password, validate_dm_password,
|
||||
write_cache)
|
||||
try:
|
||||
from ipaserver.install.dogtaginstance import PKIIniLoader
|
||||
except ImportError:
|
||||
PKIIniLoader = None
|
||||
try:
|
||||
from ipaserver.install.installutils import default_subject_base
|
||||
except ImportError:
|
||||
@@ -167,6 +171,16 @@ class AnsibleModuleLog():
|
||||
def flush(self):
|
||||
pass
|
||||
|
||||
def log(self, msg):
|
||||
#self.write(msg+"\n")
|
||||
self.write(msg)
|
||||
|
||||
def debug(self, msg):
|
||||
self.module.debug(msg)
|
||||
|
||||
def info(self, msg):
|
||||
self.module.debug(msg)
|
||||
|
||||
def write(self, msg):
|
||||
self.module.debug(msg)
|
||||
#self.module.warn(msg)
|
||||
|
||||
@@ -24,8 +24,8 @@
|
||||
|
||||
when: ipaserver_install_packages | bool
|
||||
|
||||
- name: Install - Include Python2/3 import test
|
||||
import_tasks: "{{role_path}}/tasks/python_2_3_test.yml"
|
||||
#- name: Install - Include Python2/3 import test
|
||||
# import_tasks: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
|
||||
- name: Install - Server installation test
|
||||
ipaserver_test:
|
||||
@@ -33,12 +33,12 @@
|
||||
dm_password: "{{ ipadm_password }}"
|
||||
password: "{{ ipaadmin_password }}"
|
||||
master_password: "{{ ipaserver_master_password | default(omit) }}"
|
||||
ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}"
|
||||
domain: "{{ ipaserver_domain | default(omit) }}"
|
||||
realm: "{{ ipaserver_realm | default(omit) }}"
|
||||
hostname: "{{ ipaserver_hostname | default(ansible_fqdn) }}"
|
||||
ca_cert_files: "{{ ipaserver_ca_cert_files | default(omit) }}"
|
||||
no_host_dns: "{{ ipaserver_no_host_dns }}"
|
||||
pki_config_override: "{{ ipaserver_pki_config_override | default(omit) }}"
|
||||
### server ###
|
||||
setup_adtrust: "{{ ipaserver_setup_adtrust }}"
|
||||
setup_kra: "{{ ipaserver_setup_kra }}"
|
||||
@@ -111,7 +111,8 @@
|
||||
- name: Install - Use new master password
|
||||
no_log: yes
|
||||
set_fact:
|
||||
ipaserver_master_password: "{{ result_ipaserver_master_password.password }}"
|
||||
ipaserver_master_password:
|
||||
"{{ result_ipaserver_master_password.password }}"
|
||||
|
||||
when: ipaserver_master_password is undefined
|
||||
|
||||
@@ -120,34 +121,36 @@
|
||||
### basic ###
|
||||
dm_password: "{{ ipadm_password }}"
|
||||
password: "{{ ipaadmin_password }}"
|
||||
#ip_addresses: "{{ result_ipaserver_test.ip_addresses }}"
|
||||
ip_addresses: "{{ ipaserver_ip_addresses | default([]) }}"
|
||||
domain: "{{ result_ipaserver_test.domain }}"
|
||||
realm: "{{ result_ipaserver_test.realm }}"
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
||||
### server ###
|
||||
setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
|
||||
setup_kra: "{{ result_ipaserver_test.setup_kra }}"
|
||||
setup_adtrust: "{{ ipaserver_setup_adtrust }}"
|
||||
setup_kra: "{{ ipaserver_setup_kra }}"
|
||||
setup_dns: "{{ ipaserver_setup_dns }}"
|
||||
### certificate system ###
|
||||
# external_ca
|
||||
# external_cert_files
|
||||
subject_base: "{{ result_ipaserver_test.subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_test.ca_subject }}"
|
||||
subject_base: "{{ ipaserver_subject_base | default(omit) }}"
|
||||
ca_subject: "{{ ipaserver_ca_subject | default(omit) }}"
|
||||
### dns ###
|
||||
allow_zone_overlap: "{{ ipaserver_allow_zone_overlap }}"
|
||||
reverse_zones: "{{ result_ipaserver_test.reverse_zones }}"
|
||||
reverse_zones: "{{ ipaserver_reverse_zones | default([]) }}"
|
||||
no_reverse: "{{ ipaserver_no_reverse }}"
|
||||
auto_reverse: "{{ ipaserver_auto_reverse }}"
|
||||
zonemgr: "{{ ipaserver_zonemgr | default(omit) }}"
|
||||
forwarders: "{{ ipaserver_forwarders | default([]) }}"
|
||||
no_forwarders: "{{ ipaserver_no_forwarders }}"
|
||||
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
no_dnssec_validation: "{{ result_ipaserver_test.no_dnssec_validation }}"
|
||||
forward_policy: "{{ ipaserver_forward_policy | default(omit) }}"
|
||||
no_dnssec_validation: "{{ ipaserver_no_dnssec_validation }}"
|
||||
### ad trust ###
|
||||
enable_compat: "{{ ipaserver_enable_compat }}"
|
||||
netbios_name: "{{ ipaserver_netbios_name | default(omit) }}"
|
||||
# rid_base
|
||||
# secondary_rid_base
|
||||
rid_base: "{{ ipaserver_rid_base | default(omit) }}"
|
||||
secondary_rid_base: "{{ ipaserver_secondary_rid_base | default(omit) }}"
|
||||
### additional ###
|
||||
setup_ca: "{{ result_ipaserver_test.setup_ca }}"
|
||||
_hostname_overridden: "{{ result_ipaserver_test._hostname_overridden }}"
|
||||
@@ -155,30 +158,31 @@
|
||||
|
||||
- name: Install - Setup NTP
|
||||
ipaserver_setup_ntp:
|
||||
when: not ipaclient_no_ntp | bool and (ipaserver_external_cert_files is undefined or ipaserver_external_cert_files|length < 1)
|
||||
when: not ipaclient_no_ntp | bool and (ipaserver_external_cert_files
|
||||
is undefined or ipaserver_external_cert_files|length < 1)
|
||||
|
||||
- name: Install - Setup DS
|
||||
ipaserver_setup_ds:
|
||||
dm_password: "{{ ipadm_password }}"
|
||||
password: "{{ ipaadmin_password }}"
|
||||
#master_password: "{{ ipaserver_master_password }}"
|
||||
# master_password: "{{ ipaserver_master_password }}"
|
||||
domain: "{{ result_ipaserver_test.domain }}"
|
||||
realm: "{{ result_ipaserver_test.realm | default(omit) }}"
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
#ip_addresses: "{{ result_ipaserver_test.ip_addresses }}"
|
||||
#reverse_zones: "{{ result_ipaserver_test.reverse_zones }}"
|
||||
#setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
|
||||
#setup_kra: "{{ result_ipaserver_test.setup_kra }}"
|
||||
#setup_dns: "{{ ipaserver_setup_dns }}"
|
||||
# ip_addresses: "{{ result_ipaserver_prepare.ip_addresses }}"
|
||||
# reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}"
|
||||
# setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
|
||||
# setup_kra: "{{ result_ipaserver_test.setup_kra }}"
|
||||
# setup_dns: "{{ ipaserver_setup_dns }}"
|
||||
setup_ca: "{{ result_ipaserver_test.setup_ca }}"
|
||||
#no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
||||
# no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
||||
dirsrv_config_file: "{{ ipaserver_dirsrv_config_file | default(omit) }}"
|
||||
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}"
|
||||
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}"
|
||||
subject_base: "{{ result_ipaserver_test.subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_test.ca_subject }}"
|
||||
#no_reverse: "{{ ipaserver_no_reverse }}"
|
||||
#auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
|
||||
# no_reverse: "{{ ipaserver_no_reverse }}"
|
||||
# auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
|
||||
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
|
||||
idstart: "{{ result_ipaserver_test.idstart }}"
|
||||
@@ -192,16 +196,16 @@
|
||||
domain: "{{ result_ipaserver_test.domain }}"
|
||||
realm: "{{ result_ipaserver_test.realm }}"
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
#ip_addresses: "{{ result_ipaserver_test.ip_addresses }}"
|
||||
reverse_zones: "{{ result_ipaserver_test.reverse_zones }}"
|
||||
# ip_addresses: "{{ result_ipaserver_prepare.ip_addresses }}"
|
||||
reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}"
|
||||
setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
|
||||
setup_kra: "{{ result_ipaserver_test.setup_kra }}"
|
||||
setup_dns: "{{ ipaserver_setup_dns }}"
|
||||
setup_ca: "{{ result_ipaserver_test.setup_ca }}"
|
||||
no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
||||
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}"
|
||||
subject_base: "{{ result_ipaserver_test.subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_test.ca_subject }}"
|
||||
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
|
||||
no_reverse: "{{ ipaserver_no_reverse }}"
|
||||
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
|
||||
@@ -221,11 +225,13 @@
|
||||
dm_password: "{{ ipadm_password }}"
|
||||
password: "{{ ipaadmin_password }}"
|
||||
master_password: "{{ ipaserver_master_password }}"
|
||||
#ip_addresses: "{{ result_ipaserver_test.ip_addresses }}"
|
||||
# ip_addresses: "{{ result_ipaserver_prepare.ip_addresses }}"
|
||||
domain: "{{ result_ipaserver_test.domain }}"
|
||||
realm: "{{ result_ipaserver_test.realm }}"
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
||||
pki_config_override: "{{ ipaserver_pki_config_override |
|
||||
default(omit) }}"
|
||||
setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
|
||||
setup_kra: "{{ result_ipaserver_test.setup_kra }}"
|
||||
setup_dns: "{{ ipaserver_setup_dns }}"
|
||||
@@ -239,13 +245,13 @@
|
||||
_dirsrv_pkcs12_info: "{{ result_ipaserver_test._dirsrv_pkcs12_info }}"
|
||||
external_ca: "{{ ipaserver_external_ca }}"
|
||||
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}"
|
||||
subject_base: "{{ result_ipaserver_test.subject_base }}"
|
||||
_subject_base: "{{ result_ipaserver_test._subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_test.ca_subject }}"
|
||||
_ca_subject: "{{ result_ipaserver_test._ca_subject }}"
|
||||
ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm | default(omit) }}"
|
||||
|
||||
reverse_zones: "{{ result_ipaserver_test.reverse_zones }}"
|
||||
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
||||
_subject_base: "{{ result_ipaserver_prepare._subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
|
||||
_ca_subject: "{{ result_ipaserver_prepare._ca_subject }}"
|
||||
ca_signing_algorithm: "{{ ipaserver_ca_signing_algorithm |
|
||||
default(omit) }}"
|
||||
reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}"
|
||||
no_reverse: "{{ ipaserver_no_reverse }}"
|
||||
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
|
||||
@@ -263,8 +269,8 @@
|
||||
domain: "{{ result_ipaserver_test.domain }}"
|
||||
realm: "{{ result_ipaserver_test.realm }}"
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
#ip_addresses: "{{ result_ipaserver_test.ip_addresses }}"
|
||||
reverse_zones: "{{ result_ipaserver_test.reverse_zones }}"
|
||||
# ip_addresses: "{{ result_ipaserver_prepare.ip_addresses }}"
|
||||
reverse_zones: "{{ result_ipaserver_prepare.reverse_zones }}"
|
||||
setup_adtrust: "{{ result_ipaserver_test.setup_adtrust }}"
|
||||
setup_kra: "{{ result_ipaserver_test.setup_kra }}"
|
||||
setup_dns: "{{ ipaserver_setup_dns }}"
|
||||
@@ -272,10 +278,10 @@
|
||||
no_host_dns: "{{ result_ipaserver_test.no_host_dns }}"
|
||||
dirsrv_cert_files: "{{ ipaserver_dirsrv_cert_files | default([]) }}"
|
||||
external_cert_files: "{{ ipaserver_external_cert_files | default([]) }}"
|
||||
subject_base: "{{ result_ipaserver_test.subject_base }}"
|
||||
_subject_base: "{{ result_ipaserver_test._subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_test.ca_subject }}"
|
||||
_ca_subject: "{{ result_ipaserver_test._ca_subject }}"
|
||||
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
||||
_subject_base: "{{ result_ipaserver_prepare._subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
|
||||
_ca_subject: "{{ result_ipaserver_prepare._ca_subject }}"
|
||||
no_reverse: "{{ ipaserver_no_reverse }}"
|
||||
auto_forwarders: "{{ ipaserver_auto_forwarders }}"
|
||||
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
|
||||
@@ -292,6 +298,8 @@
|
||||
dm_password: "{{ ipadm_password }}"
|
||||
setup_kra: "{{ result_ipaserver_test.setup_kra }}"
|
||||
realm: "{{ result_ipaserver_test.realm }}"
|
||||
pki_config_override: "{{ ipaserver_pki_config_override |
|
||||
default(omit) }}"
|
||||
when: result_ipaserver_test.setup_kra | bool
|
||||
|
||||
- name: Install - Setup DNS
|
||||
@@ -299,13 +307,13 @@
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
setup_ca: "{{ result_ipaserver_test.setup_ca }}"
|
||||
setup_dns: "{{ ipaserver_setup_dns }}"
|
||||
forwarders: "{{ result_ipaserver_test.forwarders }}"
|
||||
forward_policy: "{{ result_ipaserver_test.forward_policy }}"
|
||||
forwarders: "{{ result_ipaserver_prepare.forwarders }}"
|
||||
forward_policy: "{{ result_ipaserver_prepare.forward_policy }}"
|
||||
zonemgr: "{{ ipaserver_zonemgr | default(omit) }}"
|
||||
no_dnssec_validation: "{{ result_ipaserver_test.no_dnssec_validation }}"
|
||||
no_dnssec_validation: "{{ result_ipaserver_prepare.no_dnssec_validation }}"
|
||||
### additional ###
|
||||
dns_ip_addresses: "{{ result_ipaserver_test.dns_ip_addresses }}"
|
||||
dns_reverse_zones: "{{ result_ipaserver_test.dns_reverse_zones }}"
|
||||
dns_ip_addresses: "{{ result_ipaserver_prepare.dns_ip_addresses }}"
|
||||
dns_reverse_zones: "{{ result_ipaserver_prepare.dns_reverse_zones }}"
|
||||
when: ipaserver_setup_dns | bool
|
||||
|
||||
- name: Install - Setup ADTRUST
|
||||
@@ -318,8 +326,9 @@
|
||||
rid_base: "{{ result_ipaserver_test.rid_base }}"
|
||||
secondary_rid_base: "{{ result_ipaserver_test.secondary_rid_base }}"
|
||||
### additional ###
|
||||
adtrust_netbios_name: "{{ result_ipaserver_test.adtrust_netbios_name }}"
|
||||
adtrust_reset_netbios_name: "{{ result_ipaserver_test.adtrust_reset_netbios_name }}"
|
||||
adtrust_netbios_name: "{{ result_ipaserver_prepare.adtrust_netbios_name }}"
|
||||
adtrust_reset_netbios_name:
|
||||
"{{ result_ipaserver_prepare.adtrust_reset_netbios_name }}"
|
||||
when: result_ipaserver_test.setup_adtrust
|
||||
|
||||
- name: Install - Set DS password
|
||||
@@ -330,8 +339,8 @@
|
||||
realm: "{{ result_ipaserver_test.realm }}"
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
setup_ca: "{{ result_ipaserver_test.setup_ca }}"
|
||||
subject_base: "{{ result_ipaserver_test.subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_test.ca_subject }}"
|
||||
subject_base: "{{ result_ipaserver_prepare.subject_base }}"
|
||||
ca_subject: "{{ result_ipaserver_prepare.ca_subject }}"
|
||||
no_pkinit: "{{ result_ipaserver_test.no_pkinit }}"
|
||||
no_hbac_allow: "{{ ipaserver_no_hbac_allow }}"
|
||||
idstart: "{{ result_ipaserver_test.idstart }}"
|
||||
@@ -347,26 +356,13 @@
|
||||
ipaclient_on_master: yes
|
||||
ipaclient_domain: "{{ result_ipaserver_test.domain }}"
|
||||
ipaclient_realm: "{{ result_ipaserver_test.realm }}"
|
||||
ipaclient_servers: [ "{{ result_ipaserver_test.hostname }}" ]
|
||||
ipaclient_servers: ["{{ result_ipaserver_test.hostname }}"]
|
||||
ipaclient_hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
ipaclient_no_ntp: "{{ 'true' if result_ipaserver_test.ipa_python_version >= 40690 else 'false' }}"
|
||||
ipaclient_no_ntp:
|
||||
"{{ 'true' if result_ipaserver_test.ipa_python_version >= 40690
|
||||
else 'false' }}"
|
||||
ipaclient_install_packages: "{{ ipaserver_install_packages }}"
|
||||
|
||||
#- name: Install - Setup client
|
||||
# command: >
|
||||
# /usr/sbin/ipa-client-install
|
||||
# --unattended
|
||||
# --on-master
|
||||
# --domain "{{ result_ipaserver_test.domain }}"
|
||||
# --realm "{{ result_ipaserver_test.realm }}"
|
||||
# --server "{{ result_ipaserver_test.hostname }}"
|
||||
# --hostname "{{ result_ipaserver_test.hostname }}"
|
||||
# {{ "--mkhomedir" if ipaclient_mkhomedir | bool else "" }}
|
||||
# # {{ "--no-dns-sshfp" if ipaclient_no_dns_sshfp | bool else "" }}
|
||||
# # {{ "--ssh-trust-dns" if ipaclient_ssh_trust_dns | bool else "" }}
|
||||
# # {{ "--no-ssh" if ipaclient_no_ssh | bool else "" }}
|
||||
# # {{ "--no-sshd" if ipaclient_no_sshd | bool else "" }}
|
||||
|
||||
- name: Install - Enable IPA
|
||||
ipaserver_enable_ipa:
|
||||
hostname: "{{ result_ipaserver_test.hostname }}"
|
||||
@@ -386,6 +382,8 @@
|
||||
--permanent
|
||||
--add-service=freeipa-ldap
|
||||
--add-service=freeipa-ldaps
|
||||
{{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipaserver_setup_firewalld | bool
|
||||
@@ -395,8 +393,13 @@
|
||||
firewall-cmd
|
||||
--add-service=freeipa-ldap
|
||||
--add-service=freeipa-ldaps
|
||||
{{ "--add-service=freeipa-trust" if ipaserver_setup_adtrust | bool
|
||||
else "" }}
|
||||
{{ "--add-service=dns" if ipaserver_setup_dns | bool else "" }}
|
||||
{{ "--add-service=ntp" if not ipaclient_no_ntp | bool else "" }}
|
||||
when: ipaserver_setup_firewalld | bool
|
||||
|
||||
when: not ansible_check_mode and not (not result_ipaserver_test.changed and (result_ipaserver_test.client_already_configured is defined or result_ipaserver_test.server_already_configured is defined))
|
||||
when: not ansible_check_mode and not
|
||||
(not result_ipaserver_test.changed and
|
||||
(result_ipaserver_test.client_already_configured is defined or
|
||||
result_ipaserver_test.server_already_configured is defined))
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
---
|
||||
- block:
|
||||
- name: Verify Python3 import
|
||||
script: py3test.py
|
||||
@@ -13,7 +14,8 @@
|
||||
|
||||
- name: Fail for IPA 4.5.90
|
||||
fail: msg="You need to install python2 bindings for ipa server usage"
|
||||
when: result_py3test.rc != 0 and "not usable with python3" in result_py3test.stdout
|
||||
when: result_py3test.rc != 0 and "not usable with python3"
|
||||
in result_py3test.stdout
|
||||
|
||||
- name: Set python interpreter to 2
|
||||
set_fact:
|
||||
|
||||
@@ -1,23 +1,24 @@
|
||||
---
|
||||
# tasks to uninstall IPA server
|
||||
|
||||
#- name: Uninstall - Include Python2/3 import test
|
||||
# import: "{{role_path}}/tasks/python_2_3_test.yml"
|
||||
# - name: Uninstall - Include Python2/3 import test
|
||||
# import: "{{ role_path }}/tasks/python_2_3_test.yml"
|
||||
|
||||
- name: Uninstall - Uninstall IPA server
|
||||
command: >
|
||||
/usr/sbin/ipa-server-install
|
||||
--uninstall
|
||||
-U
|
||||
{{ '--ignore-topology-disconnect' if ipaserver_ignore_topology_disconnect | bool else '' }}
|
||||
{{ '--ignore-topology-disconnect' if ipaserver_ignore_topology_disconnect
|
||||
| bool else '' }}
|
||||
{{ '--ignore-last-of-role' if ipaserver_ignore_last_of_role | bool else ''}}
|
||||
register: uninstall
|
||||
# 1 means that uninstall failed because IPA server was not configured
|
||||
failed_when: uninstall.rc != 0 and uninstall.rc != 1
|
||||
changed_when: uninstall.rc == 0
|
||||
|
||||
#- name: Remove IPA server packages
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipaserver_packages }}"
|
||||
# - name: Remove IPA server packages
|
||||
# package:
|
||||
# name: "{{ item }}"
|
||||
# state: absent
|
||||
# with_items: "{{ ipaserver_packages }}"
|
||||
|
||||
Reference in New Issue
Block a user