mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
install: migrate server installers to the new class hierarchy
Migrate ipa-server-install and ipa-replica-install from the old installer classes to the new installer class hierarchy classes. https://fedorahosted.org/freeipa/ticket/6392 Reviewed-By: Martin Basti <mbasti@redhat.com>
This commit is contained in:
parent
a8fdb8de82
commit
225fae8418
@ -18,17 +18,6 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
from ipapython.install import cli
|
from ipaserver.install import ipa_replica_install
|
||||||
from ipaplatform.paths import paths
|
|
||||||
from ipaserver.install.server import Replica
|
|
||||||
|
|
||||||
|
ipa_replica_install.run()
|
||||||
ReplicaInstall = cli.install_tool(
|
|
||||||
Replica,
|
|
||||||
command_name='ipa-replica-install',
|
|
||||||
log_file_name=paths.IPAREPLICA_INSTALL_LOG,
|
|
||||||
debug_option=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
ReplicaInstall.run_cli()
|
|
||||||
|
@ -20,18 +20,6 @@
|
|||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
from ipapython.install import cli
|
from ipaserver.install import ipa_server_install
|
||||||
from ipaplatform.paths import paths
|
|
||||||
from ipaserver.install.server import Server
|
|
||||||
|
|
||||||
|
ipa_server_install.run()
|
||||||
ServerInstall = cli.install_tool(
|
|
||||||
Server,
|
|
||||||
command_name='ipa-server-install',
|
|
||||||
log_file_name=paths.IPASERVER_INSTALL_LOG,
|
|
||||||
debug_option=True,
|
|
||||||
uninstall_log_file_name=paths.IPASERVER_UNINSTALL_LOG,
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
ServerInstall.run_cli()
|
|
||||||
|
95
ipaserver/install/ipa_replica_install.py
Normal file
95
ipaserver/install/ipa_replica_install.py
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||||
|
#
|
||||||
|
|
||||||
|
from ipapython.install import cli
|
||||||
|
from ipapython.install.core import knob
|
||||||
|
from ipaplatform.paths import paths
|
||||||
|
from ipaserver.install.server import ServerReplicaInstall
|
||||||
|
|
||||||
|
|
||||||
|
class CompatServerReplicaInstall(ServerReplicaInstall):
|
||||||
|
ca_cert_files = None
|
||||||
|
all_ip_addresses = False
|
||||||
|
no_wait_for_dns = True
|
||||||
|
nisdomain = None
|
||||||
|
no_nisdomain = False
|
||||||
|
no_sudo = False
|
||||||
|
request_cert = False
|
||||||
|
ca_file = None
|
||||||
|
zonemgr = None
|
||||||
|
|
||||||
|
replica_file = knob(
|
||||||
|
# pylint: disable=no-member
|
||||||
|
bases=ServerReplicaInstall.replica_file,
|
||||||
|
cli_names='replica_file',
|
||||||
|
)
|
||||||
|
|
||||||
|
auto_password = knob(
|
||||||
|
str, None,
|
||||||
|
description="Password to join the IPA realm. Assumes bulk password "
|
||||||
|
"unless principal is also set. (domain level 1+) "
|
||||||
|
"Directory Manager (existing master) password. (domain "
|
||||||
|
"level 0)",
|
||||||
|
sensitive=True,
|
||||||
|
cli_names=['--password', '-p'],
|
||||||
|
cli_metavar='PASSWORD',
|
||||||
|
)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def dm_password(self):
|
||||||
|
try:
|
||||||
|
return self.__dm_password
|
||||||
|
except AttributeError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if self.replica_file is not None:
|
||||||
|
return self.auto_password
|
||||||
|
|
||||||
|
return super(CompatServerReplicaInstall, self).dm_password
|
||||||
|
|
||||||
|
@dm_password.setter
|
||||||
|
def dm_password(self, value):
|
||||||
|
self.__dm_password = value
|
||||||
|
|
||||||
|
ip_addresses = knob(
|
||||||
|
# pylint: disable=no-member
|
||||||
|
bases=ServerReplicaInstall.ip_addresses,
|
||||||
|
description="Replica server IP Address. This option can be used "
|
||||||
|
"multiple times",
|
||||||
|
)
|
||||||
|
|
||||||
|
admin_password = knob(
|
||||||
|
# pylint: disable=no-member
|
||||||
|
bases=ServerReplicaInstall.admin_password,
|
||||||
|
cli_names=list(ServerReplicaInstall.admin_password.cli_names) + ['-w'],
|
||||||
|
)
|
||||||
|
|
||||||
|
@admin_password.default_getter
|
||||||
|
def admin_password(self):
|
||||||
|
if self.replica_file is None and self.principal:
|
||||||
|
return self.auto_password
|
||||||
|
|
||||||
|
return super(CompatServerReplicaInstall, self).admin_password
|
||||||
|
|
||||||
|
@property
|
||||||
|
def host_password(self):
|
||||||
|
admin_password = (
|
||||||
|
super(CompatServerReplicaInstall, self).admin_password)
|
||||||
|
if (self.replica_file is None and
|
||||||
|
(not self.principal or admin_password)):
|
||||||
|
return self.auto_password
|
||||||
|
|
||||||
|
return super(CompatServerReplicaInstall, self).host_password
|
||||||
|
|
||||||
|
|
||||||
|
ReplicaInstall = cli.install_tool(
|
||||||
|
CompatServerReplicaInstall,
|
||||||
|
command_name='ipa-replica-install',
|
||||||
|
log_file_name=paths.IPAREPLICA_INSTALL_LOG,
|
||||||
|
debug_option=True,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
ReplicaInstall.run_cli()
|
49
ipaserver/install/ipa_server_install.py
Normal file
49
ipaserver/install/ipa_server_install.py
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
#
|
||||||
|
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
||||||
|
#
|
||||||
|
|
||||||
|
from ipapython.install import cli
|
||||||
|
from ipapython.install.core import knob
|
||||||
|
from ipaplatform.paths import paths
|
||||||
|
from ipaserver.install.server import ServerMasterInstall
|
||||||
|
|
||||||
|
|
||||||
|
class CompatServerMasterInstall(ServerMasterInstall):
|
||||||
|
all_ip_addresses = False
|
||||||
|
nisdomain = None
|
||||||
|
no_nisdomain = False
|
||||||
|
no_sudo = False
|
||||||
|
request_cert = False
|
||||||
|
|
||||||
|
new_dm_password = knob(
|
||||||
|
# pylint: disable=no-member
|
||||||
|
bases=ServerMasterInstall.new_dm_password,
|
||||||
|
cli_names=['--ds-password', '-p'],
|
||||||
|
)
|
||||||
|
|
||||||
|
new_admin_password = knob(
|
||||||
|
# pylint: disable=no-member
|
||||||
|
bases=ServerMasterInstall.new_admin_password,
|
||||||
|
cli_names=(list(ServerMasterInstall.new_admin_password.cli_names) +
|
||||||
|
['-a']),
|
||||||
|
)
|
||||||
|
|
||||||
|
ip_addresses = knob(
|
||||||
|
# pylint: disable=no-member
|
||||||
|
bases=ServerMasterInstall.ip_addresses,
|
||||||
|
description="Master Server IP Address. This option can be used "
|
||||||
|
"multiple times",
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
ServerInstall = cli.install_tool(
|
||||||
|
CompatServerMasterInstall,
|
||||||
|
command_name='ipa-server-install',
|
||||||
|
log_file_name=paths.IPASERVER_INSTALL_LOG,
|
||||||
|
debug_option=True,
|
||||||
|
uninstall_log_file_name=paths.IPASERVER_UNINSTALL_LOG,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def run():
|
||||||
|
ServerInstall.run_cli()
|
@ -15,7 +15,10 @@ import random
|
|||||||
from ipaclient.install import client
|
from ipaclient.install import client
|
||||||
from ipalib import constants
|
from ipalib import constants
|
||||||
from ipalib.install.service import (enroll_only,
|
from ipalib.install.service import (enroll_only,
|
||||||
|
installs_master,
|
||||||
|
installs_replica,
|
||||||
master_install_only,
|
master_install_only,
|
||||||
|
prepares,
|
||||||
prepare_only,
|
prepare_only,
|
||||||
replica_install_only)
|
replica_install_only)
|
||||||
from ipalib.util import validate_domain_name
|
from ipalib.util import validate_domain_name
|
||||||
@ -23,11 +26,17 @@ from ipapython import ipautil
|
|||||||
from ipapython.dnsutil import check_zone_overlap
|
from ipapython.dnsutil import check_zone_overlap
|
||||||
from ipapython.install import typing
|
from ipapython.install import typing
|
||||||
from ipapython.install.core import knob
|
from ipapython.install.core import knob
|
||||||
|
from ipapython.install.common import step
|
||||||
|
|
||||||
from .install import validate_admin_password, validate_dm_password
|
from .install import validate_admin_password, validate_dm_password
|
||||||
from .install import Server
|
from .install import init as master_init
|
||||||
from .replicainstall import Replica
|
from .install import install as master_install
|
||||||
|
from .install import install_check as master_install_check
|
||||||
|
from .install import uninstall, uninstall_check
|
||||||
|
from .replicainstall import init as replica_init
|
||||||
|
from .replicainstall import install as replica_install
|
||||||
|
from .replicainstall import install_check as replica_install_check
|
||||||
|
from .replicainstall import promote_check as replica_promote_check
|
||||||
from .upgrade import upgrade_check, upgrade
|
from .upgrade import upgrade_check, upgrade
|
||||||
|
|
||||||
from .. import ca, conncheck, dns, kra
|
from .. import ca, conncheck, dns, kra
|
||||||
@ -538,3 +547,56 @@ class ServerInstallInterface(client.ClientInstallInterface,
|
|||||||
|
|
||||||
# Automatically disable pkinit w/ dogtag until that is supported
|
# Automatically disable pkinit w/ dogtag until that is supported
|
||||||
self.no_pkinit = True
|
self.no_pkinit = True
|
||||||
|
|
||||||
|
|
||||||
|
class ServerMasterInstall(installs_master(ServerInstallInterface)):
|
||||||
|
"""
|
||||||
|
Server master installer
|
||||||
|
"""
|
||||||
|
|
||||||
|
domain_name = None
|
||||||
|
servers = None
|
||||||
|
dm_password = None
|
||||||
|
no_wait_for_dns = True
|
||||||
|
admin_password = None
|
||||||
|
host_password = None
|
||||||
|
keytab = None
|
||||||
|
setup_ca = True
|
||||||
|
setup_kra = False
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super(ServerMasterInstall, self).__init__(**kwargs)
|
||||||
|
master_init(self)
|
||||||
|
|
||||||
|
@step()
|
||||||
|
def main(self):
|
||||||
|
master_install_check(self)
|
||||||
|
yield
|
||||||
|
master_install(self)
|
||||||
|
|
||||||
|
@main.uninstaller
|
||||||
|
def main(self):
|
||||||
|
uninstall_check(self)
|
||||||
|
yield
|
||||||
|
uninstall(self)
|
||||||
|
|
||||||
|
|
||||||
|
class ServerReplicaInstall(installs_replica(ServerInstallInterface)):
|
||||||
|
"""
|
||||||
|
Server replica installer
|
||||||
|
"""
|
||||||
|
|
||||||
|
subject = None
|
||||||
|
|
||||||
|
def __init__(self, **kwargs):
|
||||||
|
super(ServerReplicaInstall, self).__init__(**kwargs)
|
||||||
|
replica_init(self)
|
||||||
|
|
||||||
|
@step()
|
||||||
|
def main(self):
|
||||||
|
if self.replica_file is None:
|
||||||
|
replica_promote_check(self)
|
||||||
|
else:
|
||||||
|
replica_install_check(self)
|
||||||
|
yield
|
||||||
|
replica_install(self)
|
||||||
|
@ -1,489 +0,0 @@
|
|||||||
#
|
|
||||||
# Copyright (C) 2015 FreeIPA Contributors see COPYING for license
|
|
||||||
#
|
|
||||||
|
|
||||||
from __future__ import print_function
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import six
|
|
||||||
|
|
||||||
from ipapython.dn import DN
|
|
||||||
from ipapython.ipautil import CheckedIPAddress
|
|
||||||
from ipapython.install import common, core
|
|
||||||
from ipapython.install.core import Knob, group
|
|
||||||
from ipalib.util import validate_domain_name
|
|
||||||
from ipaserver.install import bindinstance
|
|
||||||
from ipapython.dnsutil import check_zone_overlap
|
|
||||||
|
|
||||||
if six.PY3:
|
|
||||||
unicode = str
|
|
||||||
|
|
||||||
VALID_SUBJECT_ATTRS = ['st', 'o', 'ou', 'dnqualifier', 'c',
|
|
||||||
'serialnumber', 'l', 'title', 'sn', 'givenname',
|
|
||||||
'initials', 'generationqualifier', 'dc', 'mail',
|
|
||||||
'uid', 'postaladdress', 'postalcode', 'postofficebox',
|
|
||||||
'houseidentifier', 'e', 'street', 'pseudonym',
|
|
||||||
'incorporationlocality', 'incorporationstate',
|
|
||||||
'incorporationcountry', 'businesscategory']
|
|
||||||
|
|
||||||
|
|
||||||
@group
|
|
||||||
class BaseServerCA(common.Installable, core.Composite):
|
|
||||||
description = "certificate system"
|
|
||||||
|
|
||||||
external_ca = Knob(
|
|
||||||
bool, False,
|
|
||||||
description=("Generate a CSR for the IPA CA certificate to be signed "
|
|
||||||
"by an external CA"),
|
|
||||||
)
|
|
||||||
|
|
||||||
external_ca_type = Knob(
|
|
||||||
{'generic', 'ms-cs'}, None,
|
|
||||||
description="Type of the external CA",
|
|
||||||
)
|
|
||||||
|
|
||||||
external_cert_files = Knob(
|
|
||||||
(list, str), None,
|
|
||||||
description=("File containing the IPA CA certificate and the external "
|
|
||||||
"CA certificate chain"),
|
|
||||||
cli_name='external-cert-file',
|
|
||||||
cli_aliases=['external_cert_file', 'external_ca_file'],
|
|
||||||
cli_metavar='FILE',
|
|
||||||
)
|
|
||||||
|
|
||||||
@external_cert_files.validator
|
|
||||||
def external_cert_files(self, value):
|
|
||||||
if any(not os.path.isabs(path) for path in value):
|
|
||||||
raise ValueError("must use an absolute path")
|
|
||||||
|
|
||||||
dirsrv_cert_files = Knob(
|
|
||||||
(list, str), None,
|
|
||||||
description=("File containing the Directory Server SSL certificate "
|
|
||||||
"and private key"),
|
|
||||||
cli_name='dirsrv-cert-file',
|
|
||||||
cli_metavar='FILE',
|
|
||||||
)
|
|
||||||
|
|
||||||
http_cert_files = Knob(
|
|
||||||
(list, str), None,
|
|
||||||
description=("File containing the Apache Server SSL certificate and "
|
|
||||||
"private key"),
|
|
||||||
cli_name='http-cert-file',
|
|
||||||
cli_metavar='FILE',
|
|
||||||
)
|
|
||||||
|
|
||||||
pkinit_cert_files = Knob(
|
|
||||||
(list, str), None,
|
|
||||||
description=("File containing the Kerberos KDC SSL certificate and "
|
|
||||||
"private key"),
|
|
||||||
cli_name='pkinit-cert-file',
|
|
||||||
cli_metavar='FILE',
|
|
||||||
)
|
|
||||||
|
|
||||||
dirsrv_pin = Knob(
|
|
||||||
str, None,
|
|
||||||
sensitive=True,
|
|
||||||
description="The password to unlock the Directory Server private key",
|
|
||||||
cli_metavar='PIN',
|
|
||||||
)
|
|
||||||
|
|
||||||
http_pin = Knob(
|
|
||||||
str, None,
|
|
||||||
sensitive=True,
|
|
||||||
description="The password to unlock the Apache Server private key",
|
|
||||||
cli_metavar='PIN',
|
|
||||||
)
|
|
||||||
|
|
||||||
pkinit_pin = Knob(
|
|
||||||
str, None,
|
|
||||||
sensitive=True,
|
|
||||||
description="The password to unlock the Kerberos KDC private key",
|
|
||||||
cli_metavar='PIN',
|
|
||||||
)
|
|
||||||
|
|
||||||
dirsrv_cert_name = Knob(
|
|
||||||
str, None,
|
|
||||||
description="Name of the Directory Server SSL certificate to install",
|
|
||||||
cli_metavar='NAME',
|
|
||||||
)
|
|
||||||
|
|
||||||
http_cert_name = Knob(
|
|
||||||
str, None,
|
|
||||||
description="Name of the Apache Server SSL certificate to install",
|
|
||||||
cli_metavar='NAME',
|
|
||||||
)
|
|
||||||
|
|
||||||
pkinit_cert_name = Knob(
|
|
||||||
str, None,
|
|
||||||
description="Name of the Kerberos KDC SSL certificate to install",
|
|
||||||
cli_metavar='NAME',
|
|
||||||
)
|
|
||||||
|
|
||||||
ca_cert_files = Knob(
|
|
||||||
(list, str), None,
|
|
||||||
description=("File containing CA certificates for the service "
|
|
||||||
"certificate files"),
|
|
||||||
cli_name='ca-cert-file',
|
|
||||||
cli_aliases=['root-ca-file'],
|
|
||||||
cli_metavar='FILE',
|
|
||||||
)
|
|
||||||
|
|
||||||
subject = Knob(
|
|
||||||
str, None,
|
|
||||||
description="The certificate subject base (default O=<realm-name>)",
|
|
||||||
)
|
|
||||||
|
|
||||||
@subject.validator
|
|
||||||
def subject(self, value):
|
|
||||||
v = unicode(value, 'utf-8')
|
|
||||||
if any(ord(c) < 0x20 for c in v):
|
|
||||||
raise ValueError("must not contain control characters")
|
|
||||||
if '&' in v:
|
|
||||||
raise ValueError("must not contain an ampersand (\"&\")")
|
|
||||||
try:
|
|
||||||
dn = DN(v)
|
|
||||||
for rdn in dn:
|
|
||||||
if rdn.attr.lower() not in VALID_SUBJECT_ATTRS:
|
|
||||||
raise ValueError("invalid attribute: \"%s\"" % rdn.attr)
|
|
||||||
except ValueError as e:
|
|
||||||
raise ValueError("invalid subject base format: %s" % e)
|
|
||||||
|
|
||||||
ca_signing_algorithm = Knob(
|
|
||||||
{'SHA1withRSA', 'SHA256withRSA', 'SHA512withRSA'}, None,
|
|
||||||
description="Signing algorithm of the IPA CA certificate",
|
|
||||||
)
|
|
||||||
|
|
||||||
skip_schema_check = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="skip check for updated CA DS schema on the remote master",
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@group
|
|
||||||
class BaseServerDNS(common.Installable, core.Composite):
|
|
||||||
description = "DNS"
|
|
||||||
|
|
||||||
forwarders = Knob(
|
|
||||||
(list, 'ip'), None,
|
|
||||||
description=("Add a DNS forwarder. This option can be used multiple "
|
|
||||||
"times"),
|
|
||||||
cli_name='forwarder',
|
|
||||||
)
|
|
||||||
|
|
||||||
forward_policy = Knob(
|
|
||||||
{'only', 'first'}, None,
|
|
||||||
description=("DNS forwarding policy for global forwarders"),
|
|
||||||
)
|
|
||||||
|
|
||||||
auto_forwarders = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Use DNS forwarders configured in /etc/resolv.conf",
|
|
||||||
)
|
|
||||||
|
|
||||||
no_forwarders = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Do not add any DNS forwarders, use root servers instead",
|
|
||||||
)
|
|
||||||
|
|
||||||
allow_zone_overlap = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Create DNS zone even if it already exists",
|
|
||||||
)
|
|
||||||
|
|
||||||
reverse_zones = Knob(
|
|
||||||
(list, str), [],
|
|
||||||
description=("The reverse DNS zone to use. This option can be used "
|
|
||||||
"multiple times"),
|
|
||||||
cli_name='reverse-zone',
|
|
||||||
cli_metavar='REVERSE_ZONE',
|
|
||||||
)
|
|
||||||
|
|
||||||
@reverse_zones.validator
|
|
||||||
def reverse_zones(self, values):
|
|
||||||
if not self.allow_zone_overlap:
|
|
||||||
for zone in values:
|
|
||||||
check_zone_overlap(zone)
|
|
||||||
|
|
||||||
no_reverse = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Do not create new reverse DNS zone",
|
|
||||||
)
|
|
||||||
|
|
||||||
auto_reverse = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Create necessary reverse zones",
|
|
||||||
)
|
|
||||||
|
|
||||||
no_dnssec_validation = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Disable DNSSEC validation",
|
|
||||||
)
|
|
||||||
|
|
||||||
dnssec_master = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Setup server to be DNSSEC key master",
|
|
||||||
)
|
|
||||||
|
|
||||||
disable_dnssec_master = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Disable the DNSSEC master on this server",
|
|
||||||
)
|
|
||||||
|
|
||||||
kasp_db_file = Knob(
|
|
||||||
str, None,
|
|
||||||
description="Copy OpenDNSSEC metadata from the specified file (will "
|
|
||||||
"not create a new kasp.db file)",
|
|
||||||
)
|
|
||||||
|
|
||||||
force = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Force install",
|
|
||||||
)
|
|
||||||
|
|
||||||
zonemgr = Knob(
|
|
||||||
str, None,
|
|
||||||
description=("DNS zone manager e-mail address. Defaults to "
|
|
||||||
"hostmaster@DOMAIN"),
|
|
||||||
)
|
|
||||||
|
|
||||||
@zonemgr.validator
|
|
||||||
def zonemgr(self, value):
|
|
||||||
# validate the value first
|
|
||||||
try:
|
|
||||||
# IDNA support requires unicode
|
|
||||||
encoding = getattr(sys.stdin, 'encoding', None)
|
|
||||||
if encoding is None:
|
|
||||||
encoding = 'utf-8'
|
|
||||||
value = value.decode(encoding)
|
|
||||||
bindinstance.validate_zonemgr_str(value)
|
|
||||||
except ValueError as e:
|
|
||||||
# FIXME we can do this in better way
|
|
||||||
# https://fedorahosted.org/freeipa/ticket/4804
|
|
||||||
# decode to proper stderr encoding
|
|
||||||
stderr_encoding = getattr(sys.stderr, 'encoding', None)
|
|
||||||
if stderr_encoding is None:
|
|
||||||
stderr_encoding = 'utf-8'
|
|
||||||
error = unicode(e).encode(stderr_encoding)
|
|
||||||
raise ValueError(error)
|
|
||||||
|
|
||||||
|
|
||||||
class BaseServer(common.Installable, common.Interactive, core.Composite):
|
|
||||||
realm_name = Knob(
|
|
||||||
str, None,
|
|
||||||
description="realm name",
|
|
||||||
cli_name='realm',
|
|
||||||
cli_short_name='r',
|
|
||||||
)
|
|
||||||
|
|
||||||
domain_name = Knob(
|
|
||||||
str, None,
|
|
||||||
description="domain name",
|
|
||||||
cli_name='domain',
|
|
||||||
cli_short_name='n',
|
|
||||||
)
|
|
||||||
|
|
||||||
@domain_name.validator
|
|
||||||
def domain_name(self, value):
|
|
||||||
validate_domain_name(value)
|
|
||||||
|
|
||||||
dm_password = Knob(
|
|
||||||
str, None,
|
|
||||||
sensitive=True,
|
|
||||||
cli_short_name='p',
|
|
||||||
)
|
|
||||||
|
|
||||||
admin_password = Knob(
|
|
||||||
str, None,
|
|
||||||
sensitive=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
mkhomedir = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="create home directories for users on their first login",
|
|
||||||
)
|
|
||||||
|
|
||||||
host_name = Knob(
|
|
||||||
str, None,
|
|
||||||
description="fully qualified name of this host",
|
|
||||||
cli_name='hostname',
|
|
||||||
)
|
|
||||||
|
|
||||||
ip_addresses = Knob(
|
|
||||||
(list, 'ip'), None,
|
|
||||||
description=("Master Server IP Address. This option can be used "
|
|
||||||
"multiple times"),
|
|
||||||
cli_name='ip-address',
|
|
||||||
cli_metavar='IP_ADDRESS',
|
|
||||||
)
|
|
||||||
|
|
||||||
@ip_addresses.validator
|
|
||||||
def ip_addresses(self, values):
|
|
||||||
for value in values:
|
|
||||||
try:
|
|
||||||
CheckedIPAddress(value, match_local=True)
|
|
||||||
except Exception as e:
|
|
||||||
raise ValueError("invalid IP address {0}: {1}".format(
|
|
||||||
value, e))
|
|
||||||
|
|
||||||
no_host_dns = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Do not use DNS for hostname lookup during installation",
|
|
||||||
)
|
|
||||||
|
|
||||||
setup_ca = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="configure a dogtag CA",
|
|
||||||
)
|
|
||||||
|
|
||||||
setup_kra = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="configure a dogtag KRA",
|
|
||||||
)
|
|
||||||
|
|
||||||
setup_dns = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="configure bind with our zone",
|
|
||||||
)
|
|
||||||
|
|
||||||
no_ntp = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="do not configure ntp",
|
|
||||||
cli_short_name='N',
|
|
||||||
)
|
|
||||||
|
|
||||||
no_pkinit = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="disables pkinit setup steps",
|
|
||||||
)
|
|
||||||
|
|
||||||
no_ui_redirect = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Do not automatically redirect to the Web UI",
|
|
||||||
)
|
|
||||||
|
|
||||||
ssh_trust_dns = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="configure OpenSSH client to trust DNS SSHFP records",
|
|
||||||
)
|
|
||||||
|
|
||||||
no_ssh = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="do not configure OpenSSH client",
|
|
||||||
)
|
|
||||||
|
|
||||||
no_sshd = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="do not configure OpenSSH server",
|
|
||||||
)
|
|
||||||
|
|
||||||
no_dns_sshfp = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Do not automatically create DNS SSHFP records",
|
|
||||||
)
|
|
||||||
|
|
||||||
dirsrv_config_file = 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_file.validator
|
|
||||||
def dirsrv_config_file(self, value):
|
|
||||||
if not os.path.exists(value):
|
|
||||||
raise ValueError("File %s does not exist." % value)
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(BaseServer, self).__init__(**kwargs)
|
|
||||||
|
|
||||||
#pylint: disable=no-member
|
|
||||||
|
|
||||||
# If any of the key file options are selected, all are required.
|
|
||||||
cert_file_req = (self.ca.dirsrv_cert_files, self.ca.http_cert_files)
|
|
||||||
cert_file_opt = (self.ca.pkinit_cert_files,)
|
|
||||||
if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
|
|
||||||
raise RuntimeError(
|
|
||||||
"--dirsrv-cert-file and --http-cert-file are required if any "
|
|
||||||
"key file options are used.")
|
|
||||||
|
|
||||||
if not self.interactive:
|
|
||||||
if self.ca.dirsrv_cert_files and self.ca.dirsrv_pin is None:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You must specify --dirsrv-pin with --dirsrv-cert-file")
|
|
||||||
if self.ca.http_cert_files and self.ca.http_pin is None:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You must specify --http-pin with --http-cert-file")
|
|
||||||
if self.ca.pkinit_cert_files and self.ca.pkinit_pin is None:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You must specify --pkinit-pin with --pkinit-cert-file")
|
|
||||||
|
|
||||||
if self.ca.external_cert_files and self.ca.dirsrv_cert_files:
|
|
||||||
raise RuntimeError(
|
|
||||||
"Service certificate file options cannot be used with the "
|
|
||||||
"external CA options.")
|
|
||||||
|
|
||||||
if self.ca.external_ca_type and not self.ca.external_ca:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify --external-ca-type without --external-ca")
|
|
||||||
|
|
||||||
if not self.setup_dns:
|
|
||||||
if self.dns.forwarders:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --forwarder option without the "
|
|
||||||
"--setup-dns option")
|
|
||||||
if self.dns.auto_forwarders:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --auto-forwarders option without "
|
|
||||||
"the --setup-dns option")
|
|
||||||
if self.dns.no_forwarders:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --no-forwarders option without the "
|
|
||||||
"--setup-dns option")
|
|
||||||
if self.dns.forward_policy:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --forward-policy option without the "
|
|
||||||
"--setup-dns option")
|
|
||||||
if self.dns.reverse_zones:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --reverse-zone option without the "
|
|
||||||
"--setup-dns option")
|
|
||||||
if self.dns.auto_reverse:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --auto-reverse option without the "
|
|
||||||
"--setup-dns option")
|
|
||||||
if self.dns.no_reverse:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --no-reverse option without the "
|
|
||||||
"--setup-dns option")
|
|
||||||
if self.dns.no_dnssec_validation:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --no-dnssec-validation option "
|
|
||||||
"without the --setup-dns option")
|
|
||||||
elif self.dns.forwarders and self.dns.no_forwarders:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --forwarder option together with "
|
|
||||||
"--no-forwarders")
|
|
||||||
elif self.dns.auto_forwarders and self.dns.no_forwarders:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --auto-forwarders option together with "
|
|
||||||
"--no-forwarders")
|
|
||||||
elif self.dns.reverse_zones and self.dns.no_reverse:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --reverse-zone option together with "
|
|
||||||
"--no-reverse")
|
|
||||||
elif self.dns.auto_reverse and self.dns.no_reverse:
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify a --auto-reverse option together with "
|
|
||||||
"--no-reverse")
|
|
||||||
|
|
||||||
# Automatically disable pkinit w/ dogtag until that is supported
|
|
||||||
self.no_pkinit = True
|
|
||||||
|
|
||||||
self.unattended = not self.interactive
|
|
||||||
|
|
||||||
ca = core.Component(BaseServerCA)
|
|
||||||
dns = core.Component(BaseServerDNS)
|
|
@ -6,7 +6,6 @@ from __future__ import print_function
|
|||||||
|
|
||||||
import os
|
import os
|
||||||
import pickle
|
import pickle
|
||||||
import random
|
|
||||||
import shutil
|
import shutil
|
||||||
import sys
|
import sys
|
||||||
import tempfile
|
import tempfile
|
||||||
@ -16,10 +15,6 @@ import six
|
|||||||
|
|
||||||
from ipapython import certmonger, ipautil, sysrestore
|
from ipapython import certmonger, ipautil, sysrestore
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython.dnsutil import check_zone_overlap
|
|
||||||
from ipapython.install import core
|
|
||||||
from ipapython.install.common import step
|
|
||||||
from ipapython.install.core import Knob
|
|
||||||
from ipapython.ipa_log_manager import root_logger
|
from ipapython.ipa_log_manager import root_logger
|
||||||
from ipapython.ipautil import (
|
from ipapython.ipautil import (
|
||||||
decrypt_file, format_netloc, ipa_generate_password, run, user_input,
|
decrypt_file, format_netloc, ipa_generate_password, run, user_input,
|
||||||
@ -56,7 +51,7 @@ try:
|
|||||||
except ImportError:
|
except ImportError:
|
||||||
_server_trust_ad_installed = False
|
_server_trust_ad_installed = False
|
||||||
|
|
||||||
from .common import BaseServer, BaseServerCA
|
NoneType = type(None)
|
||||||
|
|
||||||
SYSRESTORE_DIR_PATH = paths.SYSRESTORE
|
SYSRESTORE_DIR_PATH = paths.SYSRESTORE
|
||||||
|
|
||||||
@ -1137,216 +1132,24 @@ def uninstall(installer):
|
|||||||
sys.exit(rv)
|
sys.exit(rv)
|
||||||
|
|
||||||
|
|
||||||
class ServerCA(BaseServerCA):
|
def init(installer):
|
||||||
external_ca = Knob(BaseServerCA.external_ca)
|
installer.unattended = not installer.interactive
|
||||||
external_ca_type = Knob(BaseServerCA.external_ca_type)
|
|
||||||
external_cert_files = Knob(BaseServerCA.external_cert_files)
|
|
||||||
|
|
||||||
dirsrv_cert_files = Knob(
|
installer.domain_name = installer.new_domain_name
|
||||||
BaseServerCA.dirsrv_cert_files,
|
installer.dm_password = installer.new_dm_password
|
||||||
cli_aliases=['dirsrv_pkcs12'],
|
installer.admin_password = installer.new_admin_password
|
||||||
)
|
installer.domainlevel = installer.domain_level
|
||||||
|
|
||||||
http_cert_files = Knob(
|
installer._installation_cleanup = True
|
||||||
BaseServerCA.http_cert_files,
|
installer._ds = None
|
||||||
cli_aliases=['http_pkcs12'],
|
|
||||||
)
|
|
||||||
|
|
||||||
pkinit_cert_files = Knob(
|
installer._dirsrv_pkcs12_file = None
|
||||||
BaseServerCA.pkinit_cert_files,
|
installer._http_pkcs12_file = None
|
||||||
cli_aliases=['pkinit_pkcs12'],
|
installer._pkinit_pkcs12_file = None
|
||||||
)
|
installer._dirsrv_pkcs12_info = None
|
||||||
|
installer._http_pkcs12_info = None
|
||||||
dirsrv_pin = Knob(
|
installer._pkinit_pkcs12_info = None
|
||||||
BaseServerCA.dirsrv_pin,
|
installer._external_cert_file = None
|
||||||
cli_aliases=['dirsrv_pin'],
|
installer._external_ca_file = None
|
||||||
)
|
installer._ca_cert = None
|
||||||
|
installer._update_hosts_file = False
|
||||||
http_pin = Knob(
|
|
||||||
BaseServerCA.http_pin,
|
|
||||||
cli_aliases=['http_pin'],
|
|
||||||
)
|
|
||||||
|
|
||||||
pkinit_pin = Knob(
|
|
||||||
BaseServerCA.pkinit_pin,
|
|
||||||
cli_aliases=['pkinit_pin'],
|
|
||||||
)
|
|
||||||
|
|
||||||
skip_schema_check = None
|
|
||||||
|
|
||||||
|
|
||||||
class Server(BaseServer):
|
|
||||||
setup_ca = None
|
|
||||||
setup_kra = None
|
|
||||||
setup_dns = Knob(BaseServer.setup_dns)
|
|
||||||
|
|
||||||
realm_name = Knob(BaseServer.realm_name)
|
|
||||||
domain_name = Knob(BaseServer.domain_name)
|
|
||||||
|
|
||||||
@domain_name.validator
|
|
||||||
def domain_name(self, value):
|
|
||||||
if (self.setup_dns and
|
|
||||||
not self.dns.allow_zone_overlap): # pylint: disable=no-member
|
|
||||||
print("Checking DNS domain %s, please wait ..." % value)
|
|
||||||
check_zone_overlap(value, False)
|
|
||||||
|
|
||||||
dm_password = Knob(
|
|
||||||
BaseServer.dm_password,
|
|
||||||
description="Directory Manager password",
|
|
||||||
cli_name='ds-password',
|
|
||||||
)
|
|
||||||
|
|
||||||
@dm_password.validator
|
|
||||||
def dm_password(self, value):
|
|
||||||
validate_dm_password(value)
|
|
||||||
|
|
||||||
master_password = Knob(
|
|
||||||
str, None,
|
|
||||||
sensitive=True,
|
|
||||||
deprecated=True,
|
|
||||||
description="kerberos master password (normally autogenerated)",
|
|
||||||
cli_short_name='P',
|
|
||||||
)
|
|
||||||
|
|
||||||
admin_password = Knob(
|
|
||||||
BaseServer.admin_password,
|
|
||||||
description="admin user kerberos password",
|
|
||||||
cli_short_name='a',
|
|
||||||
)
|
|
||||||
|
|
||||||
@admin_password.validator
|
|
||||||
def admin_password(self, value):
|
|
||||||
validate_admin_password(value)
|
|
||||||
|
|
||||||
mkhomedir = Knob(BaseServer.mkhomedir)
|
|
||||||
host_name = Knob(BaseServer.host_name)
|
|
||||||
|
|
||||||
domainlevel = Knob(
|
|
||||||
int, constants.MAX_DOMAIN_LEVEL,
|
|
||||||
description="IPA domain level",
|
|
||||||
cli_name='domain-level',
|
|
||||||
deprecated=True,
|
|
||||||
)
|
|
||||||
|
|
||||||
@domainlevel.validator
|
|
||||||
def domainlevel(self, value):
|
|
||||||
# Check that Domain Level is within the allowed range
|
|
||||||
if value < constants.MIN_DOMAIN_LEVEL:
|
|
||||||
raise ValueError(
|
|
||||||
"Domain Level cannot be lower than {0}".format(
|
|
||||||
constants.MIN_DOMAIN_LEVEL))
|
|
||||||
elif value > constants.MAX_DOMAIN_LEVEL:
|
|
||||||
raise ValueError(
|
|
||||||
"Domain Level cannot be higher than {0}".format(
|
|
||||||
constants.MAX_DOMAIN_LEVEL))
|
|
||||||
|
|
||||||
ip_addresses = Knob(
|
|
||||||
BaseServer.ip_addresses,
|
|
||||||
description=("Master Server IP Address. This option can be used "
|
|
||||||
"multiple times"),
|
|
||||||
)
|
|
||||||
|
|
||||||
no_host_dns = Knob(BaseServer.no_host_dns)
|
|
||||||
no_ntp = Knob(BaseServer.no_ntp)
|
|
||||||
|
|
||||||
idstart = Knob(
|
|
||||||
int, random.randint(1, 10000) * 200000,
|
|
||||||
description="The starting value for the IDs range (default random)",
|
|
||||||
)
|
|
||||||
|
|
||||||
idmax = Knob(
|
|
||||||
int,
|
|
||||||
description=("The max value for the IDs range (default: "
|
|
||||||
"idstart+199999)"),
|
|
||||||
)
|
|
||||||
|
|
||||||
@idmax.default_getter
|
|
||||||
def idmax(self):
|
|
||||||
return self.idstart + 200000 - 1
|
|
||||||
|
|
||||||
no_hbac_allow = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="Don't install allow_all HBAC rule",
|
|
||||||
cli_name='no-hbac-allow',
|
|
||||||
cli_aliases=['no_hbac_allow'],
|
|
||||||
)
|
|
||||||
|
|
||||||
ignore_topology_disconnect = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="do not check whether server uninstall disconnects the "
|
|
||||||
"topology (domain level 1+)",
|
|
||||||
)
|
|
||||||
ignore_last_of_role = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="do not check whether server uninstall removes last "
|
|
||||||
"CA/DNS server or DNSSec master (domain level 1+)",
|
|
||||||
)
|
|
||||||
|
|
||||||
# dns
|
|
||||||
dnssec_master = None
|
|
||||||
disable_dnssec_master = None
|
|
||||||
kasp_db_file = None
|
|
||||||
force = None
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(Server, self).__init__(**kwargs)
|
|
||||||
|
|
||||||
self._installation_cleanup = True
|
|
||||||
self._ds = None
|
|
||||||
|
|
||||||
self._dirsrv_pkcs12_file = None
|
|
||||||
self._http_pkcs12_file = None
|
|
||||||
self._pkinit_pkcs12_file = None
|
|
||||||
self._dirsrv_pkcs12_info = None
|
|
||||||
self._http_pkcs12_info = None
|
|
||||||
self._pkinit_pkcs12_info = None
|
|
||||||
self._external_cert_file = None
|
|
||||||
self._external_ca_file = None
|
|
||||||
self._ca_cert = None
|
|
||||||
self._update_hosts_file = False
|
|
||||||
|
|
||||||
# pylint: disable=no-member
|
|
||||||
|
|
||||||
if self.uninstalling:
|
|
||||||
if (self.realm_name or self.admin_password or
|
|
||||||
self.master_password):
|
|
||||||
raise RuntimeError(
|
|
||||||
"In uninstall mode, -a, -r and -P options are not allowed")
|
|
||||||
elif not self.interactive:
|
|
||||||
if (not self.realm_name or not self.dm_password or
|
|
||||||
not self.admin_password):
|
|
||||||
raise RuntimeError(
|
|
||||||
"In unattended mode you need to provide at least -r, -p "
|
|
||||||
"and -a options")
|
|
||||||
if self.setup_dns:
|
|
||||||
if (not self.dns.forwarders and not self.dns.no_forwarders
|
|
||||||
and not self.dns.auto_forwarders):
|
|
||||||
raise RuntimeError(
|
|
||||||
"You must specify at least one of --forwarder, "
|
|
||||||
"--auto-forwarders, or --no-forwarders options")
|
|
||||||
|
|
||||||
any_ignore_option_true = any(
|
|
||||||
[self.ignore_topology_disconnect, self.ignore_last_of_role])
|
|
||||||
if any_ignore_option_true and not self.uninstalling:
|
|
||||||
raise RuntimeError(
|
|
||||||
"'--ignore-topology-disconnect/--ignore-last-of-role' options "
|
|
||||||
"can be used only during uninstallation")
|
|
||||||
|
|
||||||
if self.idmax < self.idstart:
|
|
||||||
raise RuntimeError(
|
|
||||||
"idmax (%s) cannot be smaller than idstart (%s)" %
|
|
||||||
(self.idmax, self.idstart))
|
|
||||||
|
|
||||||
ca = core.Component(ServerCA)
|
|
||||||
|
|
||||||
@step()
|
|
||||||
def main(self):
|
|
||||||
install_check(self)
|
|
||||||
yield
|
|
||||||
install(self)
|
|
||||||
|
|
||||||
@main.uninstaller
|
|
||||||
def main(self):
|
|
||||||
uninstall_check(self)
|
|
||||||
yield
|
|
||||||
uninstall(self)
|
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
|
|
||||||
from __future__ import print_function
|
from __future__ import print_function
|
||||||
|
|
||||||
import collections
|
|
||||||
from distutils.version import LooseVersion
|
from distutils.version import LooseVersion
|
||||||
import dns.exception as dnsexception
|
import dns.exception as dnsexception
|
||||||
import dns.name as dnsname
|
import dns.name as dnsname
|
||||||
@ -20,8 +19,6 @@ import six
|
|||||||
|
|
||||||
from ipapython import ipaldap, ipautil, sysrestore
|
from ipapython import ipaldap, ipautil, sysrestore
|
||||||
from ipapython.dn import DN
|
from ipapython.dn import DN
|
||||||
from ipapython.install.common import step
|
|
||||||
from ipapython.install.core import Knob
|
|
||||||
from ipapython.ipa_log_manager import root_logger
|
from ipapython.ipa_log_manager import root_logger
|
||||||
from ipapython.admintool import ScriptError
|
from ipapython.admintool import ScriptError
|
||||||
from ipaplatform import services
|
from ipaplatform import services
|
||||||
@ -48,11 +45,11 @@ import SSSDConfig
|
|||||||
from subprocess import CalledProcessError
|
from subprocess import CalledProcessError
|
||||||
from binascii import hexlify
|
from binascii import hexlify
|
||||||
|
|
||||||
from .common import BaseServer
|
|
||||||
|
|
||||||
if six.PY3:
|
if six.PY3:
|
||||||
unicode = str
|
unicode = str
|
||||||
|
|
||||||
|
NoneType = type(None)
|
||||||
|
|
||||||
|
|
||||||
def get_dirman_password():
|
def get_dirman_password():
|
||||||
return installutils.read_password("Directory Manager (existing master)",
|
return installutils.read_password("Directory Manager (existing master)",
|
||||||
@ -1440,173 +1437,27 @@ def install(installer):
|
|||||||
services.knownservices.ipa.enable()
|
services.knownservices.ipa.enable()
|
||||||
|
|
||||||
|
|
||||||
class Replica(BaseServer):
|
def init(installer):
|
||||||
replica_file = Knob(
|
installer.unattended = not installer.interactive
|
||||||
str, None,
|
installer.promote = installer.replica_file is None
|
||||||
description="a file generated by ipa-replica-prepare",
|
|
||||||
cli_positional=True,
|
|
||||||
cli_name='replica_file',
|
|
||||||
)
|
|
||||||
|
|
||||||
setup_ca = Knob(BaseServer.setup_ca)
|
|
||||||
setup_kra = Knob(BaseServer.setup_kra)
|
|
||||||
setup_dns = Knob(BaseServer.setup_dns)
|
|
||||||
|
|
||||||
ip_addresses = Knob(
|
|
||||||
BaseServer.ip_addresses,
|
|
||||||
description=("Replica server IP Address. This option can be used "
|
|
||||||
"multiple times"),
|
|
||||||
)
|
|
||||||
|
|
||||||
dm_password = None
|
|
||||||
|
|
||||||
password = Knob(
|
|
||||||
BaseServer.dm_password,
|
|
||||||
description=("Password to join the IPA realm. Assumes bulk password "
|
|
||||||
"unless principal is also set. (domain level 1+)\n"
|
|
||||||
"Directory Manager (existing master) password. "
|
|
||||||
"(domain level 0)"),
|
|
||||||
)
|
|
||||||
|
|
||||||
admin_password = Knob(
|
|
||||||
BaseServer.admin_password,
|
|
||||||
description="Kerberos password for the specified admin principal",
|
|
||||||
cli_short_name='w',
|
|
||||||
)
|
|
||||||
|
|
||||||
server = Knob(
|
|
||||||
str, None,
|
|
||||||
description="fully qualified name of IPA server to enroll to",
|
|
||||||
)
|
|
||||||
|
|
||||||
mkhomedir = Knob(BaseServer.mkhomedir)
|
|
||||||
no_host_dns = Knob(BaseServer.no_host_dns)
|
|
||||||
no_ntp = Knob(BaseServer.no_ntp)
|
|
||||||
no_pkinit = Knob(BaseServer.no_pkinit)
|
|
||||||
no_ui_redirect = Knob(BaseServer.no_ui_redirect)
|
|
||||||
ssh_trust_dns = Knob(BaseServer.ssh_trust_dns)
|
|
||||||
no_ssh = Knob(BaseServer.no_ssh)
|
|
||||||
no_sshd = Knob(BaseServer.no_sshd)
|
|
||||||
no_dns_sshfp = Knob(BaseServer.no_dns_sshfp)
|
|
||||||
|
|
||||||
skip_conncheck = Knob(
|
|
||||||
bool, False,
|
|
||||||
description="skip connection check to remote master",
|
|
||||||
)
|
|
||||||
|
|
||||||
principal = Knob(
|
|
||||||
str, None,
|
|
||||||
sensitive=True,
|
|
||||||
description="User Principal allowed to promote replicas "
|
|
||||||
"and join IPA realm",
|
|
||||||
cli_short_name='P',
|
|
||||||
)
|
|
||||||
|
|
||||||
keytab = Knob(
|
|
||||||
str, None,
|
|
||||||
description="path to backed up keytab from previous enrollment",
|
|
||||||
cli_short_name='k',
|
|
||||||
)
|
|
||||||
|
|
||||||
promote = False
|
|
||||||
|
|
||||||
# ca
|
|
||||||
external_ca = None
|
|
||||||
external_ca_type = None
|
|
||||||
external_cert_files = None
|
|
||||||
ca_cert_files = None
|
|
||||||
subject = None
|
|
||||||
ca_signing_algorithm = None
|
|
||||||
|
|
||||||
# dns
|
|
||||||
dnssec_master = None
|
|
||||||
disable_dnssec_master = None
|
|
||||||
kasp_db_file = None
|
|
||||||
force = None
|
|
||||||
zonemgr = None
|
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
|
||||||
super(Replica, self).__init__(**kwargs)
|
|
||||||
|
|
||||||
self._ccache = os.environ.get('KRB5CCNAME')
|
|
||||||
|
|
||||||
self._top_dir = None
|
|
||||||
self._config = None
|
|
||||||
self._update_hosts_file = False
|
|
||||||
self._dirsrv_pkcs12_file = None
|
|
||||||
self._http_pkcs12_file = None
|
|
||||||
self._pkinit_pkcs12_file = None
|
|
||||||
self._dirsrv_pkcs12_info = None
|
|
||||||
self._http_pkcs12_info = None
|
|
||||||
self._pkinit_pkcs12_info = None
|
|
||||||
|
|
||||||
# pylint: disable=no-member
|
|
||||||
|
|
||||||
cert_file_req = (self.ca.dirsrv_cert_files, self.ca.http_cert_files)
|
|
||||||
cert_file_opt = (self.ca.pkinit_cert_files,)
|
|
||||||
|
|
||||||
if self.replica_file is None:
|
|
||||||
self.promote = True
|
|
||||||
|
|
||||||
if self.principal and not self.admin_password:
|
|
||||||
self.admin_password = self.password
|
|
||||||
self.password = None
|
|
||||||
|
|
||||||
# If any of the PKCS#12 options are selected, all are required.
|
|
||||||
if any(cert_file_req + cert_file_opt) and not all(cert_file_req):
|
|
||||||
raise RuntimeError("--dirsrv-cert-file and --http-cert-file "
|
|
||||||
"are required if any PKCS#12 options are "
|
|
||||||
"used")
|
|
||||||
|
|
||||||
if self.server and not self.domain_name:
|
|
||||||
raise RuntimeError("The --server option cannot be used "
|
|
||||||
"without providing domain via the --domain "
|
|
||||||
"option")
|
|
||||||
|
|
||||||
|
if installer.servers:
|
||||||
|
installer.server = installer.servers[0]
|
||||||
else:
|
else:
|
||||||
if not ipautil.file_exists(self.replica_file):
|
installer.server = None
|
||||||
raise RuntimeError("Replica file %s does not exist"
|
if installer.replica_file is None:
|
||||||
% self.replica_file)
|
installer.password = installer.host_password
|
||||||
|
|
||||||
if any(cert_file_req + cert_file_opt):
|
|
||||||
raise RuntimeError("You cannot specify any of "
|
|
||||||
"--dirsrv-cert-file, --http-cert-file, or "
|
|
||||||
"--pkinit-cert-file together with replica "
|
|
||||||
"file")
|
|
||||||
|
|
||||||
CLIKnob = collections.namedtuple('CLIKnob', ('value', 'name'))
|
|
||||||
|
|
||||||
conflicting_knobs = (
|
|
||||||
CLIKnob(self.realm_name, '--realm'),
|
|
||||||
CLIKnob(self.domain_name, '--domain'),
|
|
||||||
CLIKnob(self.host_name, '--hostname'),
|
|
||||||
CLIKnob(self.server, '--server'),
|
|
||||||
CLIKnob(self.principal, '--principal'),
|
|
||||||
)
|
|
||||||
|
|
||||||
if any([k.value is not None for k in conflicting_knobs]):
|
|
||||||
conflicting_knob_names = [
|
|
||||||
knob.name for knob in conflicting_knobs
|
|
||||||
if knob.value is not None
|
|
||||||
]
|
|
||||||
|
|
||||||
raise RuntimeError(
|
|
||||||
"You cannot specify '{0}' option(s) with replica file."
|
|
||||||
.format(", ".join(conflicting_knob_names))
|
|
||||||
)
|
|
||||||
|
|
||||||
if self.setup_dns:
|
|
||||||
if (not self.dns.forwarders and not self.dns.no_forwarders
|
|
||||||
and not self.dns.auto_forwarders):
|
|
||||||
raise RuntimeError(
|
|
||||||
"You must specify at least one of --forwarder, "
|
|
||||||
"--auto-forwarders, or --no-forwarders options")
|
|
||||||
|
|
||||||
@step()
|
|
||||||
def main(self):
|
|
||||||
if self.promote:
|
|
||||||
promote_check(self)
|
|
||||||
else:
|
else:
|
||||||
install_check(self)
|
installer.password = installer.dm_password
|
||||||
yield
|
|
||||||
install(self)
|
installer._ccache = os.environ.get('KRB5CCNAME')
|
||||||
|
|
||||||
|
installer._top_dir = None
|
||||||
|
installer._config = None
|
||||||
|
installer._update_hosts_file = False
|
||||||
|
installer._dirsrv_pkcs12_file = None
|
||||||
|
installer._http_pkcs12_file = None
|
||||||
|
installer._pkinit_pkcs12_file = None
|
||||||
|
installer._dirsrv_pkcs12_info = None
|
||||||
|
installer._http_pkcs12_info = None
|
||||||
|
installer._pkinit_pkcs12_info = None
|
||||||
|
Loading…
Reference in New Issue
Block a user