mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Add option to specify LDIF file that contains DS configuration changes
This allows to user modify configuration changes of the directory server instance during installation of DS https://fedorahosted.org/freeipa/ticket/4949 Also fixes: https://fedorahosted.org/freeipa/ticket/4048 https://fedorahosted.org/freeipa/ticket/1930 Reviewed-By: Martin Babinsky <mbabinsk@redhat.com>
This commit is contained in:
@@ -74,6 +74,9 @@ Enable debug logging when more verbose output is needed
|
|||||||
.TP
|
.TP
|
||||||
\fB\-U\fR, \fB\-\-unattended\fR
|
\fB\-U\fR, \fB\-\-unattended\fR
|
||||||
An unattended installation that will never prompt for user input
|
An unattended installation that will never prompt for user input
|
||||||
|
.TP
|
||||||
|
\fB\-\-dirsrv-config-mods\fR
|
||||||
|
The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance
|
||||||
|
|
||||||
.SS "CERTIFICATE SYSTEM OPTIONS"
|
.SS "CERTIFICATE SYSTEM OPTIONS"
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
@@ -78,7 +78,9 @@ Enable debug logging when more verbose output is needed
|
|||||||
.TP
|
.TP
|
||||||
\fB\-U\fR, \fB\-\-unattended\fR
|
\fB\-U\fR, \fB\-\-unattended\fR
|
||||||
An unattended installation that will never prompt for user input
|
An unattended installation that will never prompt for user input
|
||||||
|
.TP
|
||||||
|
\fB\-\-dirsrv-config-mods\fR
|
||||||
|
The path to LDIF file that will be used to modify configuration of dse.ldif during installation of the directory server instance
|
||||||
|
|
||||||
.SS "CERTIFICATE SYSTEM OPTIONS"
|
.SS "CERTIFICATE SYSTEM OPTIONS"
|
||||||
.TP
|
.TP
|
||||||
|
|||||||
@@ -206,7 +206,7 @@ info: IPA V2.0
|
|||||||
|
|
||||||
class DsInstance(service.Service):
|
class DsInstance(service.Service):
|
||||||
def __init__(self, realm_name=None, domain_name=None, dm_password=None,
|
def __init__(self, realm_name=None, domain_name=None, dm_password=None,
|
||||||
fstore=None, domainlevel=None):
|
fstore=None, domainlevel=None, config_ldif=None):
|
||||||
service.Service.__init__(self, "dirsrv",
|
service.Service.__init__(self, "dirsrv",
|
||||||
service_desc="directory server",
|
service_desc="directory server",
|
||||||
dm_password=dm_password,
|
dm_password=dm_password,
|
||||||
@@ -229,6 +229,7 @@ class DsInstance(service.Service):
|
|||||||
self.subject_base = None
|
self.subject_base = None
|
||||||
self.open_ports = []
|
self.open_ports = []
|
||||||
self.run_init_memberof = True
|
self.run_init_memberof = True
|
||||||
|
self.config_ldif = config_ldif # updates for dse.ldif
|
||||||
self.domainlevel = domainlevel
|
self.domainlevel = domainlevel
|
||||||
if realm_name:
|
if realm_name:
|
||||||
self.suffix = ipautil.realm_to_suffix(self.realm)
|
self.suffix = ipautil.realm_to_suffix(self.realm)
|
||||||
@@ -248,6 +249,9 @@ class DsInstance(service.Service):
|
|||||||
|
|
||||||
self.step("creating directory server user", create_ds_user)
|
self.step("creating directory server user", create_ds_user)
|
||||||
self.step("creating directory server instance", self.__create_instance)
|
self.step("creating directory server instance", self.__create_instance)
|
||||||
|
if self.config_ldif:
|
||||||
|
self.step("updating configuration in dse.ldif", self.__update_dse_ldif)
|
||||||
|
self.step("restarting directory server", self.__restart_instance)
|
||||||
self.step("adding default schema", self.__add_default_schemas)
|
self.step("adding default schema", self.__add_default_schemas)
|
||||||
self.step("enabling memberof plugin", self.__add_memberof_module)
|
self.step("enabling memberof plugin", self.__add_memberof_module)
|
||||||
self.step("enabling winsync plugin", self.__add_winsync_module)
|
self.step("enabling winsync plugin", self.__add_winsync_module)
|
||||||
@@ -544,16 +548,39 @@ class DsInstance(service.Service):
|
|||||||
# check for open port 389 from now on
|
# check for open port 389 from now on
|
||||||
self.open_ports.append(389)
|
self.open_ports.append(389)
|
||||||
|
|
||||||
root_logger.debug("restarting ds instance")
|
|
||||||
try:
|
|
||||||
self.__restart_instance()
|
|
||||||
root_logger.debug("done restarting ds instance")
|
|
||||||
except ipautil.CalledProcessError as e:
|
|
||||||
print("failed to restart ds instance", e)
|
|
||||||
root_logger.debug("failed to restart ds instance %s" % e)
|
|
||||||
inf_fd.close()
|
inf_fd.close()
|
||||||
os.remove(paths.DIRSRV_BOOT_LDIF)
|
os.remove(paths.DIRSRV_BOOT_LDIF)
|
||||||
|
|
||||||
|
def __update_dse_ldif(self):
|
||||||
|
"""
|
||||||
|
This method updates dse.ldif right after instance creation. This is
|
||||||
|
supposed to allow admin modify configuration of the DS which has to be
|
||||||
|
done before IPA is fully installed (for example: settings for
|
||||||
|
replication on replicas)
|
||||||
|
DS must be turned off.
|
||||||
|
"""
|
||||||
|
self.stop()
|
||||||
|
|
||||||
|
dse_filename = os.path.join(
|
||||||
|
paths.ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE % self.serverid,
|
||||||
|
'dse.ldif'
|
||||||
|
)
|
||||||
|
|
||||||
|
with tempfile.NamedTemporaryFile(delete=False) as new_dse_ldif:
|
||||||
|
temp_filename = new_dse_ldif.name
|
||||||
|
with open(dse_filename, "r") as input_file:
|
||||||
|
parser = installutils.ModifyLDIF(input_file, new_dse_ldif)
|
||||||
|
# parse modification from config ldif
|
||||||
|
with open(self.config_ldif, "r") as config_ldif:
|
||||||
|
parser.modifications_from_ldif(config_ldif)
|
||||||
|
parser.parse()
|
||||||
|
new_dse_ldif.flush()
|
||||||
|
shutil.copy2(temp_filename, dse_filename)
|
||||||
|
try:
|
||||||
|
os.remove(temp_filename)
|
||||||
|
except OSError as e:
|
||||||
|
root_logger.debug("Failed to clean temporary file: %s" % e)
|
||||||
|
|
||||||
def __add_default_schemas(self):
|
def __add_default_schemas(self):
|
||||||
pent = pwd.getpwnam(DS_USER)
|
pent = pwd.getpwnam(DS_USER)
|
||||||
for schema_fname in IPA_SCHEMA_FILES:
|
for schema_fname in IPA_SCHEMA_FILES:
|
||||||
|
|||||||
@@ -343,6 +343,20 @@ class BaseServer(common.Installable, common.Interactive, core.Composite):
|
|||||||
description="Do not automatically create DNS SSHFP records",
|
description="Do not automatically create DNS SSHFP records",
|
||||||
)
|
)
|
||||||
|
|
||||||
|
dirsrv_config_mods = Knob(
|
||||||
|
str, None,
|
||||||
|
description="The path to LDIF file that will be used to modify "
|
||||||
|
"configuration of dse.ldif during installation of the "
|
||||||
|
"directory server instance",
|
||||||
|
cli_metavar='FILE',
|
||||||
|
)
|
||||||
|
|
||||||
|
@dirsrv_config_mods.validator
|
||||||
|
def dirsrv_config_mods(self, value):
|
||||||
|
if not os.path.exists(value):
|
||||||
|
raise ValueError("File %s does not exist." % value)
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super(BaseServer, self).__init__(**kwargs)
|
super(BaseServer, self).__init__(**kwargs)
|
||||||
|
|
||||||
|
|||||||
@@ -734,7 +734,8 @@ def install(installer):
|
|||||||
|
|
||||||
if options.dirsrv_cert_files:
|
if options.dirsrv_cert_files:
|
||||||
ds = dsinstance.DsInstance(fstore=fstore,
|
ds = dsinstance.DsInstance(fstore=fstore,
|
||||||
domainlevel=options.domainlevel)
|
domainlevel=options.domainlevel,
|
||||||
|
config_ldif=options.dirsrv_config_mods)
|
||||||
installer._ds = ds
|
installer._ds = ds
|
||||||
ds.create_instance(realm_name, host_name, domain_name,
|
ds.create_instance(realm_name, host_name, domain_name,
|
||||||
dm_password, dirsrv_pkcs12_info,
|
dm_password, dirsrv_pkcs12_info,
|
||||||
@@ -743,7 +744,8 @@ def install(installer):
|
|||||||
hbac_allow=not options.no_hbac_allow)
|
hbac_allow=not options.no_hbac_allow)
|
||||||
else:
|
else:
|
||||||
ds = dsinstance.DsInstance(fstore=fstore,
|
ds = dsinstance.DsInstance(fstore=fstore,
|
||||||
domainlevel=options.domainlevel)
|
domainlevel=options.domainlevel,
|
||||||
|
config_ldif=options.dirsrv_config_mods)
|
||||||
installer._ds = ds
|
installer._ds = ds
|
||||||
ds.create_instance(realm_name, host_name, domain_name,
|
ds.create_instance(realm_name, host_name, domain_name,
|
||||||
dm_password,
|
dm_password,
|
||||||
|
|||||||
@@ -87,7 +87,7 @@ def install_http_certs(config, fstore):
|
|||||||
# FIXME: need Signing-Cert too ?
|
# FIXME: need Signing-Cert too ?
|
||||||
|
|
||||||
|
|
||||||
def install_replica_ds(config, promote=False):
|
def install_replica_ds(config, options, promote=False):
|
||||||
dsinstance.check_ports()
|
dsinstance.check_ports()
|
||||||
|
|
||||||
# if we have a pkcs12 file, create the cert db from
|
# if we have a pkcs12 file, create the cert db from
|
||||||
@@ -95,7 +95,8 @@ def install_replica_ds(config, promote=False):
|
|||||||
# cert
|
# cert
|
||||||
pkcs12_info = make_pkcs12_info(config.dir, "dscert.p12", "dirsrv_pin.txt")
|
pkcs12_info = make_pkcs12_info(config.dir, "dscert.p12", "dirsrv_pin.txt")
|
||||||
|
|
||||||
ds = dsinstance.DsInstance()
|
ds = dsinstance.DsInstance(
|
||||||
|
config_ldif=options.dirsrv_config_mods)
|
||||||
ds.create_replica(
|
ds.create_replica(
|
||||||
realm_name=config.realm_name,
|
realm_name=config.realm_name,
|
||||||
master_fqdn=config.master_host_name,
|
master_fqdn=config.master_host_name,
|
||||||
@@ -668,7 +669,7 @@ def install(installer):
|
|||||||
ntp.create_instance()
|
ntp.create_instance()
|
||||||
|
|
||||||
# Configure dirsrv
|
# Configure dirsrv
|
||||||
ds = install_replica_ds(config)
|
ds = install_replica_ds(config, options)
|
||||||
|
|
||||||
# Always try to install DNS records
|
# Always try to install DNS records
|
||||||
install_dns_records(config, options, remote_api)
|
install_dns_records(config, options, remote_api)
|
||||||
@@ -1015,7 +1016,7 @@ def promote(installer):
|
|||||||
ntp.create_instance()
|
ntp.create_instance()
|
||||||
|
|
||||||
# Configure dirsrv
|
# Configure dirsrv
|
||||||
ds = install_replica_ds(config, promote=True)
|
ds = install_replica_ds(config, options, promote=True)
|
||||||
|
|
||||||
# Always try to install DNS records
|
# Always try to install DNS records
|
||||||
install_dns_records(config, options, api)
|
install_dns_records(config, options, api)
|
||||||
|
|||||||
Reference in New Issue
Block a user