Skip to content
Snippets Groups Projects
Commit 5724212b authored by Thomas Woerner's avatar Thomas Woerner
Browse files

library/ipajoin.py: New documentation, debug flag, added missing kdestroy call

parent edd590ca
No related branches found
No related tags found
No related merge requests found
...@@ -22,9 +22,11 @@ ...@@ -22,9 +22,11 @@
# You should have received a copy of the GNU General Public License # You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>. # along with this program. If not, see <http://www.gnu.org/licenses/>.
ANSIBLE_METADATA = {'metadata_version': '1.0', ANSIBLE_METADATA = {
'metadata_version': '1.0',
'supported_by': 'community',
'status': ['preview'], 'status': ['preview'],
'supported_by': 'community'} }
DOCUMENTATION = ''' DOCUMENTATION = '''
--- ---
...@@ -36,28 +38,24 @@ options: ...@@ -36,28 +38,24 @@ options:
servers: servers:
description: The FQDN of the IPA servers to connect to. description: The FQDN of the IPA servers to connect to.
required: false required: false
basedn: domain:
description: The basedn of the IPA server (of the form dc=example,dc=com). description: The primary DNS domain of an existing IPA deployment.
required: false required: false
realm: realm:
description: The Kerberos realm of an existing IPA deployment. description: The Kerberos realm of an existing IPA deployment.
required: true required: true
hostname:
description: The hostname of the machine to join (FQDN).
required: true
kdc: kdc:
description: The name or address of the host running the KDC. description: The name or address of the host running the KDC.
required: true required: true
hostname: basedn:
description: The hostname of the machine to join (FQDN). description: The basedn of the IPA server (of the form dc=example,dc=com).
required: false required: true
domain:
description: The primary DNS domain of an existing IPA deployment.
required: false
force_join:
description: Force enrolling the host even if host entry exists.
required: false
principal: principal:
description: The authorized kerberos principal used to join the IPA realm. description: The authorized kerberos principal used to join the IPA realm.
required: false required: false
default: admin
password: password:
description: The password to use if not using Kerberos to authenticate. description: The password to use if not using Kerberos to authenticate.
required: false required: false
...@@ -67,14 +65,45 @@ options: ...@@ -67,14 +65,45 @@ options:
ca_cert_file: ca_cert_file:
description: A CA certificate to use. Do not acquire the IPA CA certificate via automated means. description: A CA certificate to use. Do not acquire the IPA CA certificate via automated means.
required: false required: false
force_join:
description: Force enrolling the host even if host entry exists.
required: false
kinit_attempts: kinit_attempts:
description: Repeat the request for host Kerberos ticket X times. description: Repeat the request for host Kerberos ticket X times.
required: false required: false
debug:
description: Enable debug mode.
required: false
author: author:
- Thomas Woerner - Thomas Woerner
''' '''
EXAMPLES = ''' EXAMPLES = '''
# Join IPA to get the keytab
- name: Join IPA in force mode with maximum 5 kinit attempts
ipajoin:
servers: ["server1.example.com","server2.example.com"]
domain: example.com
realm: EXAMPLE.COM
kdc: server1.example.com
basedn: dc=example,dc=com
hostname: client1.example.com
principal: admin
password: MySecretPassword
force_join: yes
kinit_attempts: 5
# Join IPA to get the keytab using ipadiscovery return values
- name: Join IPA
ipajoin:
servers: "{{ ipadiscovery.servers }}"
domain: "{{ ipadiscovery.domain }}"
realm: "{{ ipadiscovery.realm }}"
kdc: "{{ ipadiscovery.kdc }}"
basedn: "{{ ipadiscovery.basedn }}"
hostname: "{{ ipadiscovery.hostname }}"
principal: admin
password: MySecretPassword
''' '''
RETURN = ''' RETURN = '''
...@@ -99,35 +128,38 @@ def main(): ...@@ -99,35 +128,38 @@ def main():
module = AnsibleModule( module = AnsibleModule(
argument_spec = dict( argument_spec = dict(
servers=dict(required=True, type='list'), servers=dict(required=True, type='list'),
basedn=dict(required=True), domain=dict(required=True),
realm=dict(required=True), realm=dict(required=True),
kdc=dict(required=True),
hostname=dict(required=True), hostname=dict(required=True),
domain=dict(required=True), kdc=dict(required=True),
force_join=dict(required=False, type='bool'), basedn=dict(required=True),
principal=dict(required=False), principal=dict(required=False),
password=dict(required=False), password=dict(required=False, no_log=True),
keytab=dict(required=False), keytab=dict(required=False),
ca_cert_file=dict(required=False), ca_cert_file=dict(required=False),
force_join=dict(required=False, type='bool'),
kinit_attempts=dict(required=False, type='int'), kinit_attempts=dict(required=False, type='int'),
debug=dict(required=False, type='bool'),
), ),
# required_one_of = ( [ '', '' ] ), required_one_of = (['principal', 'keytab'],
['password', 'keytab']),
supports_check_mode = True, supports_check_mode = True,
) )
module._ansible_debug = True module._ansible_debug = True
servers = module.params.get('servers') servers = module.params.get('servers')
basedn = module.params.get('basedn') domain = module.params.get('domain')
realm = module.params.get('realm') realm = module.params.get('realm')
kdc = module.params.get('kdc')
hostname = module.params.get('hostname') hostname = module.params.get('hostname')
domain = module.params.get('hostname') basedn = module.params.get('basedn')
kdc = module.params.get('kdc')
force_join = module.params.get('force_join') force_join = module.params.get('force_join')
principal = module.params.get('principal') principal = module.params.get('principal')
password = module.params.get('password') password = module.params.get('password')
keytab = module.params.get('keytab') keytab = module.params.get('keytab')
ca_cert_file = module.params.get('ca_cert_file') ca_cert_file = module.params.get('ca_cert_file')
kinit_attempts = module.params.get('kinit_attempts') kinit_attempts = module.params.get('kinit_attempts')
debug = module.params.get('debug')
client_domain = hostname[hostname.find(".")+1:] client_domain = hostname[hostname.find(".")+1:]
nolog = tuple() nolog = tuple()
...@@ -142,8 +174,8 @@ def main(): ...@@ -142,8 +174,8 @@ def main():
options.ca_cert_file = ca_cert_file options.ca_cert_file = ca_cert_file
options.unattended = True options.unattended = True
options.principal = principal options.principal = principal
options.password = password
options.force = False options.force = False
options.password = password
try: try:
(krb_fd, krb_name) = tempfile.mkstemp() (krb_fd, krb_name) = tempfile.mkstemp()
...@@ -166,10 +198,12 @@ def main(): ...@@ -166,10 +198,12 @@ def main():
"-s", servers[0], "-s", servers[0],
"-b", str(realm_to_suffix(realm)), "-b", str(realm_to_suffix(realm)),
"-h", hostname] "-h", hostname]
if debug:
join_args.append("-d")
env['XMLRPC_TRACE_CURL'] = 'yes'
if force_join: if force_join:
join_args.append("-f") join_args.append("-f")
if principal: if principal:
module.log("before kinit_password")
if principal.find('@') == -1: if principal.find('@') == -1:
principal = '%s@%s' % (principal, realm) principal = '%s@%s' % (principal, realm)
try: try:
...@@ -195,9 +229,9 @@ def main(): ...@@ -195,9 +229,9 @@ def main():
msg="Keytab file could not be found: {}".format(keytab)) msg="Keytab file could not be found: {}".format(keytab))
elif password: elif password:
nolog = (password,)
join_args.append("-w") join_args.append("-w")
join_args.append(password) join_args.append(password)
nolog = (password,)
env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name env['KRB5CCNAME'] = os.environ['KRB5CCNAME'] = ccache_name
# Get the CA certificate # Get the CA certificate
...@@ -228,6 +262,9 @@ def main(): ...@@ -228,6 +262,9 @@ def main():
subject_base = subject_base.strip() subject_base = subject_base.strip()
subject_base = DN(subject_base) subject_base = DN(subject_base)
if principal:
run(["kdestroy"], raiseonerr=False, env=env)
# Obtain the TGT. We do it with the temporary krb5.conf, so that # Obtain the TGT. We do it with the temporary krb5.conf, so that
# only the KDC we're installing under is contacted. # only the KDC we're installing under is contacted.
# Other KDCs might not have replicated the principal yet. # Other KDCs might not have replicated the principal yet.
...@@ -256,7 +293,7 @@ def main(): ...@@ -256,7 +293,7 @@ def main():
except OSError: except OSError:
module.fail_json(msg="Could not remove %s.ipabkp" % krb_name) module.fail_json(msg="Could not remove %s.ipabkp" % krb_name)
module.exit_json(changed=True), module.exit_json(changed=True)
if __name__ == '__main__': if __name__ == '__main__':
main() main()
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment