roles/samba-dc: Deploy a Samba AD DC
The *samba-dc* role installs Samba on the managed node and configures it as an Active Directory Domain controller. A custom module, `samba_domain` handles the provisioning using `samba-tool domain provision` in an idempotent way.
This commit is contained in:
124
roles/samba-dc/library/samba_domain
Normal file
124
roles/samba-dc/library/samba_domain
Normal file
@@ -0,0 +1,124 @@
|
||||
# vim: set ft=python :
|
||||
import errno
|
||||
import os
|
||||
import subprocess
|
||||
|
||||
|
||||
def get_samba_paths(samba='samba'):
|
||||
lines = []
|
||||
paths = {}
|
||||
cmd = [samba, '--show-build']
|
||||
with open(os.devnull, 'r') as nul:
|
||||
p = subprocess.Popen(
|
||||
cmd, stdin=nul, stdout=subprocess.PIPE, stderr=subprocess.PIPE
|
||||
)
|
||||
out, err = p.communicate()
|
||||
in_paths = False
|
||||
for line in out.splitlines():
|
||||
out += line
|
||||
if line.startswith(b'Paths:'):
|
||||
in_paths = True
|
||||
continue
|
||||
if in_paths:
|
||||
if line.startswith(b' '):
|
||||
parts = line.decode().split(':', 1)
|
||||
if len(parts) != 2:
|
||||
raise ValueError(
|
||||
'Unexpected output from samba: {}'.format(line)
|
||||
)
|
||||
paths[parts[0].strip()] = parts[1].strip()
|
||||
else:
|
||||
in_paths = False
|
||||
if p.returncode != 0:
|
||||
raise subprocess.CalledProcessError(p.returncode, cmd, out, err)
|
||||
return paths
|
||||
|
||||
|
||||
def main():
|
||||
module = AnsibleModule(
|
||||
argument_spec=dict(
|
||||
realm=dict(
|
||||
required=True,
|
||||
),
|
||||
domain=dict(
|
||||
required=False,
|
||||
),
|
||||
use_rfc2307=dict(
|
||||
required=False,
|
||||
type='bool',
|
||||
default=True,
|
||||
),
|
||||
dns_backend=dict(
|
||||
required=False,
|
||||
choices=[
|
||||
'BIND9_DLZ',
|
||||
'SAMBA_INTERNAL',
|
||||
],
|
||||
),
|
||||
),
|
||||
supports_check_mode=True,
|
||||
)
|
||||
|
||||
realm = module.params['realm']
|
||||
domain = module.params['domain'] or realm.split('.')[0]
|
||||
use_rfc2307 = module.params['use_rfc2307']
|
||||
dns_backend = module.params['dns_backend']
|
||||
|
||||
samba_tool = module.get_bin_path('samba-tool', required=True)
|
||||
samba = module.get_bin_path('samba', required=True)
|
||||
|
||||
try:
|
||||
samba_paths = get_samba_paths(samba)
|
||||
except OSError as e:
|
||||
module.fail_json(msg='Error running samba: {}'.format(e))
|
||||
except subprocess.CalledProcessError as e:
|
||||
module.fail_json(
|
||||
msg='Error running samba: {}'.format(e),
|
||||
stdout=e.stdout,
|
||||
stderr=e.stderr,
|
||||
)
|
||||
|
||||
changed = not os.path.isdir(os.path.join(
|
||||
samba_paths['STATEDIR'],
|
||||
'sysvol',
|
||||
realm.lower(),
|
||||
))
|
||||
|
||||
if changed and not module.check_mode:
|
||||
try:
|
||||
os.unlink(samba_paths['CONFIGFILE'])
|
||||
except OSError as e:
|
||||
if e.errno != errno.ENOENT:
|
||||
raise
|
||||
cmd = [
|
||||
samba_tool,
|
||||
'domain',
|
||||
'provision',
|
||||
'--realm={}'.format(realm),
|
||||
'--domain={}'.format(domain),
|
||||
]
|
||||
if use_rfc2307:
|
||||
cmd.append('--use-rfc2307')
|
||||
if dns_backend:
|
||||
cmd += ('--dns-backend', dns_backend)
|
||||
rc, out, err = module.run_command(cmd, check_rc=True)
|
||||
admin_password = ''
|
||||
domain_sid = ''
|
||||
for line in err.splitlines():
|
||||
if line.startswith('Admin password:'):
|
||||
admin_password = line.split(':', 1)[1].lstrip()
|
||||
if line.startswith('DOMAIN SID:'):
|
||||
domain_sid = line.split(':', 1)[1].lstrip()
|
||||
module.exit_json(
|
||||
changed=True,
|
||||
rc=rc,
|
||||
admin_password=admin_password,
|
||||
domain_sid=domain_sid,
|
||||
)
|
||||
|
||||
module.exit_json(changed=changed)
|
||||
|
||||
|
||||
from ansible.module_utils.basic import *
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
Reference in New Issue
Block a user