class AutomountInstallInterface(service.ServiceInstallInterface): """ Interface of the automount installer Knobs defined here will be available in: * ipa-client-install * ipa-client-automount """ automount_location = knob( str, 'default', description="Automount location", ) automount_location = enroll_only(automount_location)
class SSSDInstallInterface(service.ServiceInstallInterface): description = "SSSD" fixed_primary = knob( None, description="Configure sssd to use fixed server as primary IPA server", ) fixed_primary = enroll_only(fixed_primary) permit = knob( None, description="disable access rules by default, permit all access.", ) permit = enroll_only(permit) enable_dns_updates = knob( None, description="Configures the machine to attempt dns updates when the " "ip address changes.", ) enable_dns_updates = enroll_only(enable_dns_updates) no_krb5_offline_passwords = knob( None, description="Configure SSSD not to store user password when the " "server is offline", ) no_krb5_offline_passwords = enroll_only(no_krb5_offline_passwords) preserve_sssd = knob( None, description="Preserve old SSSD configuration if possible", ) preserve_sssd = enroll_only(preserve_sssd) no_sssd = False
class CAInstallInterface(dogtag.DogtagInstallInterface, conncheck.ConnCheckInterface): """ Interface of the CA installer Knobs defined here will be available in: * ipa-server-install * ipa-replica-prepare * ipa-replica-install * ipa-ca-install """ description = "Certificate system" principal = conncheck.ConnCheckInterface.principal principal = extend_knob( principal, description="User allowed to manage replicas", cli_names=list(principal.cli_names) + ['-P'], ) principal = enroll_only(principal) principal = replica_install_only(principal) admin_password = conncheck.ConnCheckInterface.admin_password admin_password = extend_knob( admin_password, description="Admin user Kerberos password used for connection check", cli_names=list(admin_password.cli_names) + ['-w'], ) admin_password = enroll_only(admin_password) external_ca = knob( None, description=("Generate a CSR for the IPA CA certificate to be signed " "by an external CA"), ) external_ca = master_install_only(external_ca) external_ca_type = knob(x509.ExternalCAType, None, description="Type of the external CA") external_ca_type = master_install_only(external_ca_type) external_ca_profile = knob( type=x509.ExternalCAProfile, default=None, description=("Specify the certificate profile/template to use at the " "external CA"), ) external_ca_profile = master_install_only(external_ca_profile) external_cert_files = knob( typing.List[str], None, description=("File containing the IPA CA certificate and the external " "CA certificate chain"), cli_names='--external-cert-file', cli_deprecated_names=['--external_cert_file', '--external_ca_file'], cli_metavar='FILE', ) external_cert_files = master_install_only(external_cert_files) @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") subject_base = knob( str, None, description=("The certificate subject base (default O=<realm-name>). " "RDNs are in LDAP order (most specific RDN first)."), cli_deprecated_names=['--subject'], ) subject_base = master_install_only(subject_base) @subject_base.validator def subject_base(self, value): subject_validator(VALID_SUBJECT_BASE_ATTRS, value) ca_subject = knob( str, None, description=("The CA certificate subject DN " "(default CN=Certificate Authority,O=<realm-name>). " "RDNs are in LDAP order (most specific RDN first)."), ) ca_subject = master_install_only(ca_subject) @ca_subject.validator def ca_subject(self, value): subject_validator(VALID_SUBJECT_ATTRS, value) ca_signing_algorithm = knob( CASigningAlgorithm, None, description="Signing algorithm of the IPA CA certificate", ) ca_signing_algorithm = master_install_only(ca_signing_algorithm) skip_schema_check = knob( None, description="skip check for updated CA DS schema on the remote master", ) skip_schema_check = enroll_only(skip_schema_check) skip_schema_check = replica_install_only(skip_schema_check)
class ServerInstallInterface( ServerCertificateInstallInterface, client.ClientInstallInterface, ca.CAInstallInterface, kra.KRAInstallInterface, dns.DNSInstallInterface, adtrust.ADTrustInstallInterface, conncheck.ConnCheckInterface, ServerUninstallInterface): """ Interface of server installers Knobs defined here will be available in: * ipa-server-install * ipa-replica-prepare * ipa-replica-install """ description = "Server" kinit_attempts = 1 fixed_primary = True permit = False enable_dns_updates = False no_krb5_offline_passwords = False preserve_sssd = False no_sssd = False domain_name = client.ClientInstallInterface.domain_name domain_name = extend_knob( domain_name, # pylint: disable=no-member cli_names=list(domain_name.cli_names) + ['-n'], ) servers = extend_knob( client.ClientInstallInterface.servers, description="fully qualified name of IPA server to enroll to", ) servers = enroll_only(servers) realm_name = client.ClientInstallInterface.realm_name realm_name = extend_knob( realm_name, cli_names=list(realm_name.cli_names) + ['-r'], ) host_name = extend_knob( client.ClientInstallInterface.host_name, description="fully qualified name of this host", ) ca_cert_files = extend_knob( client.ClientInstallInterface.ca_cert_files, description="File containing CA certificates for the service " "certificate files", cli_deprecated_names='--root-ca-file', ) ca_cert_files = prepare_only(ca_cert_files) dm_password = extend_knob( client.ClientInstallInterface.dm_password, description="Directory Manager password", ) ip_addresses = extend_knob( client.ClientInstallInterface.ip_addresses, description="Server IP Address. This option can be used multiple " "times", ) principal = client.ClientInstallInterface.principal principal = extend_knob( principal, description="User Principal allowed to promote replicas and join IPA " "realm", cli_names=list(principal.cli_names) + ['-P'], ) principal = replica_install_only(principal) admin_password = extend_knob( client.ClientInstallInterface.admin_password, ) master_password = knob( str, None, sensitive=True, deprecated=True, description="kerberos master password (normally autogenerated)", ) master_password = master_install_only(master_password) domain_level = knob( int, constants.MAX_DOMAIN_LEVEL, description="IPA domain level", deprecated=True, ) domain_level = master_install_only(domain_level) @domain_level.validator def domain_level(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)) setup_adtrust = knob(None, description="configure AD trust capability") setup_ca = knob( None, description="configure a dogtag CA", ) setup_ca = enroll_only(setup_ca) setup_kra = knob( None, description="configure a dogtag KRA", ) setup_kra = enroll_only(setup_kra) setup_dns = knob( None, description="configure bind with our zone", ) setup_dns = enroll_only(setup_dns) idstart = knob( int, random.randint(1, 10000) * 200000, description="The starting value for the IDs range (default random)", ) idstart = master_install_only(idstart) idmax = knob( int, description=("The max value for the IDs range (default: " "idstart+199999)"), ) idmax = master_install_only(idmax) @idmax.default_getter def idmax(self): return self.idstart + 200000 - 1 no_hbac_allow = knob( None, description="Don't install allow_all HBAC rule", cli_deprecated_names='--no_hbac_allow', ) no_hbac_allow = master_install_only(no_hbac_allow) no_pkinit = knob( None, description="disables pkinit setup steps", ) no_pkinit = prepare_only(no_pkinit) no_ui_redirect = knob( None, description="Do not automatically redirect to the Web UI", ) no_ui_redirect = enroll_only(no_ui_redirect) 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 = enroll_only(dirsrv_config_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 _is_promote(self): """ :returns: True if domain level options correspond to domain level > 0 """ raise NotImplementedError() def __init__(self, **kwargs): super(ServerInstallInterface, self).__init__(**kwargs) # pkinit is not supported on DL0, don't allow related options if not self._is_promote(): if (self.no_pkinit or self.pkinit_cert_files is not None or self.pkinit_pin is not None): raise RuntimeError( "pkinit on domain level 0 is not supported. Please " "don't use any pkinit-related options.") self.no_pkinit = True # If any of the key file options are selected, all are required. cert_file_req = (self.dirsrv_cert_files, self.http_cert_files) cert_file_opt = (self.pkinit_cert_files, ) if not self.no_pkinit: cert_file_req += cert_file_opt if self.no_pkinit and self.pkinit_cert_files: raise RuntimeError( "--no-pkinit and --pkinit-cert-file cannot be specified " "together") if any(cert_file_req + cert_file_opt) and not all(cert_file_req): raise RuntimeError( "--dirsrv-cert-file, --http-cert-file, and --pkinit-cert-file " "or --no-pkinit are required if any key file options are used." ) if not self.interactive: if self.dirsrv_cert_files and self.dirsrv_pin is None: raise RuntimeError( "You must specify --dirsrv-pin with --dirsrv-cert-file") if self.http_cert_files and self.http_pin is None: raise RuntimeError( "You must specify --http-pin with --http-cert-file") if self.pkinit_cert_files and self.pkinit_pin is None: raise RuntimeError( "You must specify --pkinit-pin with --pkinit-cert-file") if not self.setup_dns: if self.forwarders: raise RuntimeError( "You cannot specify a --forwarder option without the " "--setup-dns option") if self.auto_forwarders: raise RuntimeError( "You cannot specify a --auto-forwarders option without " "the --setup-dns option") if self.no_forwarders: raise RuntimeError( "You cannot specify a --no-forwarders option without the " "--setup-dns option") if self.forward_policy: raise RuntimeError( "You cannot specify a --forward-policy option without the " "--setup-dns option") if self.reverse_zones: raise RuntimeError( "You cannot specify a --reverse-zone option without the " "--setup-dns option") if self.auto_reverse: raise RuntimeError( "You cannot specify a --auto-reverse option without the " "--setup-dns option") if self.no_reverse: raise RuntimeError( "You cannot specify a --no-reverse option without the " "--setup-dns option") if self.no_dnssec_validation: raise RuntimeError( "You cannot specify a --no-dnssec-validation option " "without the --setup-dns option") elif self.forwarders and self.no_forwarders: raise RuntimeError( "You cannot specify a --forwarder option together with " "--no-forwarders") elif self.auto_forwarders and self.no_forwarders: raise RuntimeError( "You cannot specify a --auto-forwarders option together with " "--no-forwarders") elif self.reverse_zones and self.no_reverse: raise RuntimeError( "You cannot specify a --reverse-zone option together with " "--no-reverse") elif self.auto_reverse and self.no_reverse: raise RuntimeError( "You cannot specify a --auto-reverse option together with " "--no-reverse") if not self.setup_adtrust: if self.add_agents: raise RuntimeError( "You cannot specify an --add-agents option without the " "--setup-adtrust option") if self.enable_compat: raise RuntimeError( "You cannot specify an --enable-compat option without the " "--setup-adtrust option") if self.netbios_name: raise RuntimeError( "You cannot specify a --netbios-name option without the " "--setup-adtrust option") if self.no_msdcs: raise RuntimeError( "You cannot specify a --no-msdcs option without the " "--setup-adtrust option") if not hasattr(self, 'replica_file'): if self.external_cert_files and self.dirsrv_cert_files: raise RuntimeError( "Service certificate file options cannot be used with the " "external CA options.") if self.external_ca_type and not self.external_ca: raise RuntimeError( "You cannot specify --external-ca-type without " "--external-ca") if self.external_ca_profile and not self.external_ca: raise RuntimeError( "You cannot specify --external-ca-profile without " "--external-ca") 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.forwarders and not self.no_forwarders and not self.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)) else: # replica installers if self.replica_file is None: if self.servers and not self.domain_name: raise RuntimeError( "The --server option cannot be used without providing " "domain via the --domain option") else: if not os.path.isfile(self.replica_file): raise RuntimeError("Replica file %s does not exist" % self.replica_file) 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.servers, '--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.forwarders and not self.no_forwarders and not self.auto_forwarders): raise RuntimeError( "You must specify at least one of --forwarder, " "--auto-forwarders, or --no-forwarders options")
class DNSInstallInterface(hostname.HostNameInstallInterface): """ Interface of the DNS installer Knobs defined here will be available in: * ipa-server-install * ipa-replica-prepare * ipa-replica-install * ipa-dns-install """ description = "DNS" allow_zone_overlap = knob( None, description="Create DNS zone even if it already exists", ) allow_zone_overlap = prepare_only(allow_zone_overlap) reverse_zones = knob( # pylint: disable=invalid-sequence-index typing.List[str], [], description=("The reverse DNS zone to use. This option can be used " "multiple times"), cli_names='--reverse-zone', cli_metavar='REVERSE_ZONE', ) reverse_zones = prepare_only(reverse_zones) @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( None, description="Do not create new reverse DNS zone", ) no_reverse = prepare_only(no_reverse) auto_reverse = knob( None, description="Create necessary reverse zones", ) auto_reverse = prepare_only(auto_reverse) zonemgr = knob( str, None, description=("DNS zone manager e-mail address. Defaults to " "hostmaster@DOMAIN"), ) zonemgr = prepare_only(zonemgr) @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 is string in py2 and py3 if not isinstance(value, unicode): 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) forwarders = knob( # pylint: disable=invalid-sequence-index typing.List[ipautil.CheckedIPAddressLoopback], None, description=("Add a DNS forwarder. This option can be used multiple " "times"), cli_names='--forwarder', ) forwarders = enroll_only(forwarders) no_forwarders = knob( None, description="Do not add any DNS forwarders, use root servers instead", ) no_forwarders = enroll_only(no_forwarders) auto_forwarders = knob( None, description="Use DNS forwarders configured in /etc/resolv.conf", ) auto_forwarders = enroll_only(auto_forwarders) forward_policy = knob( DNSForwardPolicy, None, description=("DNS forwarding policy for global forwarders"), ) forward_policy = enroll_only(forward_policy) no_dnssec_validation = knob( None, description="Disable DNSSEC validation", ) no_dnssec_validation = enroll_only(no_dnssec_validation) dnssec_master = False disable_dnssec_master = False kasp_db_file = None force = False
class ServerInstallInterface(client.ClientInstallInterface, ca.CAInstallInterface, kra.KRAInstallInterface, dns.DNSInstallInterface, conncheck.ConnCheckInterface): """ Interface of server installers Knobs defined here will be available in: * ipa-server-install * ipa-replica-prepare * ipa-replica-install """ force_join = False kinit_attempts = 1 fixed_primary = True ntp_servers = None force_ntpd = False permit = False enable_dns_updates = False no_krb5_offline_passwords = False preserve_sssd = False domain_name = knob( bases=client.ClientInstallInterface.domain_name, # pylint: disable=no-member cli_names=(list(client.ClientInstallInterface.domain_name.cli_names) + ['-n']), ) servers = knob( bases=client.ClientInstallInterface.servers, description="fully qualified name of IPA server to enroll to", ) servers = enroll_only(servers) realm_name = knob( bases=client.ClientInstallInterface.realm_name, cli_names=(list(client.ClientInstallInterface.realm_name.cli_names) + ['-r']), ) host_name = knob( bases=client.ClientInstallInterface.host_name, description="fully qualified name of this host", ) ca_cert_files = knob( bases=client.ClientInstallInterface.ca_cert_files, description="File containing CA certificates for the service " "certificate files", cli_deprecated_names='--root-ca-file', ) ca_cert_files = prepare_only(ca_cert_files) dm_password = knob( bases=client.ClientInstallInterface.dm_password, description="Directory Manager password", ) ip_addresses = knob( bases=client.ClientInstallInterface.ip_addresses, description="Server IP Address. This option can be used multiple " "times", ) principal = knob( bases=client.ClientInstallInterface.principal, description="User Principal allowed to promote replicas and join IPA " "realm", cli_names=(list(client.ClientInstallInterface.principal.cli_names) + ['-P']), ) principal = replica_install_only(principal) master_password = knob( str, None, sensitive=True, deprecated=True, description="kerberos master password (normally autogenerated)", ) master_password = master_install_only(master_password) domain_level = knob( int, constants.MAX_DOMAIN_LEVEL, description="IPA domain level", deprecated=True, ) domain_level = master_install_only(domain_level) @domain_level.validator def domain_level(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)) setup_ca = knob( None, description="configure a dogtag CA", ) setup_ca = enroll_only(setup_ca) setup_kra = knob( None, description="configure a dogtag KRA", ) setup_kra = enroll_only(setup_kra) setup_dns = knob( None, description="configure bind with our zone", ) setup_dns = enroll_only(setup_dns) idstart = knob( int, random.randint(1, 10000) * 200000, description="The starting value for the IDs range (default random)", ) idstart = master_install_only(idstart) idmax = knob( int, description=("The max value for the IDs range (default: " "idstart+199999)"), ) idmax = master_install_only(idmax) @idmax.default_getter def idmax(self): return self.idstart + 200000 - 1 no_hbac_allow = knob( None, description="Don't install allow_all HBAC rule", cli_deprecated_names='--no_hbac_allow', ) no_hbac_allow = master_install_only(no_hbac_allow) ignore_topology_disconnect = knob( None, description="do not check whether server uninstall disconnects the " "topology (domain level 1+)", ) ignore_topology_disconnect = master_install_only( ignore_topology_disconnect) ignore_last_of_role = knob( None, description="do not check whether server uninstall removes last " "CA/DNS server or DNSSec master (domain level 1+)", ) ignore_last_of_role = master_install_only(ignore_last_of_role) no_pkinit = knob( None, description="disables pkinit setup steps", ) no_pkinit = prepare_only(no_pkinit) no_ui_redirect = knob( None, description="Do not automatically redirect to the Web UI", ) no_ui_redirect = enroll_only(no_ui_redirect) ssh_trust_dns = knob( None, description="configure OpenSSH client to trust DNS SSHFP records", ) ssh_trust_dns = enroll_only(ssh_trust_dns) no_ssh = knob( None, description="do not configure OpenSSH client", ) no_ssh = enroll_only(no_ssh) no_sshd = knob( None, description="do not configure OpenSSH server", ) no_sshd = enroll_only(no_sshd) no_dns_sshfp = knob( None, description="Do not automatically create DNS SSHFP records", ) no_dns_sshfp = enroll_only(no_dns_sshfp) 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 = enroll_only(dirsrv_config_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) dirsrv_cert_files = knob( # pylint: disable=invalid-sequence-index typing.List[str], None, description=("File containing the Directory Server SSL certificate " "and private key"), cli_names='--dirsrv-cert-file', cli_deprecated_names='--dirsrv_pkcs12', cli_metavar='FILE', ) dirsrv_cert_files = prepare_only(dirsrv_cert_files) http_cert_files = knob( # pylint: disable=invalid-sequence-index typing.List[str], None, description=("File containing the Apache Server SSL certificate and " "private key"), cli_names='--http-cert-file', cli_deprecated_names='--http_pkcs12', cli_metavar='FILE', ) http_cert_files = prepare_only(http_cert_files) pkinit_cert_files = knob( # pylint: disable=invalid-sequence-index typing.List[str], None, description=("File containing the Kerberos KDC SSL certificate and " "private key"), cli_names='--pkinit-cert-file', cli_deprecated_names='--pkinit_pkcs12', cli_metavar='FILE', ) pkinit_cert_files = prepare_only(pkinit_cert_files) dirsrv_pin = knob( str, None, sensitive=True, description="The password to unlock the Directory Server private key", cli_deprecated_names='--dirsrv_pin', cli_metavar='PIN', ) dirsrv_pin = prepare_only(dirsrv_pin) http_pin = knob( str, None, sensitive=True, description="The password to unlock the Apache Server private key", cli_deprecated_names='--http_pin', cli_metavar='PIN', ) http_pin = prepare_only(http_pin) pkinit_pin = knob( str, None, sensitive=True, description="The password to unlock the Kerberos KDC private key", cli_deprecated_names='--pkinit_pin', cli_metavar='PIN', ) pkinit_pin = prepare_only(pkinit_pin) dirsrv_cert_name = knob( str, None, description="Name of the Directory Server SSL certificate to install", cli_metavar='NAME', ) dirsrv_cert_name = prepare_only(dirsrv_cert_name) http_cert_name = knob( str, None, description="Name of the Apache Server SSL certificate to install", cli_metavar='NAME', ) http_cert_name = prepare_only(http_cert_name) pkinit_cert_name = knob( str, None, description="Name of the Kerberos KDC SSL certificate to install", cli_metavar='NAME', ) pkinit_cert_name = prepare_only(pkinit_cert_name) def __init__(self, **kwargs): super(ServerInstallInterface, self).__init__(**kwargs) # If any of the key file options are selected, all are required. cert_file_req = (self.dirsrv_cert_files, self.http_cert_files) cert_file_opt = (self.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.dirsrv_cert_files and self.dirsrv_pin is None: raise RuntimeError( "You must specify --dirsrv-pin with --dirsrv-cert-file") if self.http_cert_files and self.http_pin is None: raise RuntimeError( "You must specify --http-pin with --http-cert-file") if self.pkinit_cert_files and self.pkinit_pin is None: raise RuntimeError( "You must specify --pkinit-pin with --pkinit-cert-file") if not self.setup_dns: if self.forwarders: raise RuntimeError( "You cannot specify a --forwarder option without the " "--setup-dns option") if self.auto_forwarders: raise RuntimeError( "You cannot specify a --auto-forwarders option without " "the --setup-dns option") if self.no_forwarders: raise RuntimeError( "You cannot specify a --no-forwarders option without the " "--setup-dns option") if self.forward_policy: raise RuntimeError( "You cannot specify a --forward-policy option without the " "--setup-dns option") if self.reverse_zones: raise RuntimeError( "You cannot specify a --reverse-zone option without the " "--setup-dns option") if self.auto_reverse: raise RuntimeError( "You cannot specify a --auto-reverse option without the " "--setup-dns option") if self.no_reverse: raise RuntimeError( "You cannot specify a --no-reverse option without the " "--setup-dns option") if self.no_dnssec_validation: raise RuntimeError( "You cannot specify a --no-dnssec-validation option " "without the --setup-dns option") elif self.forwarders and self.no_forwarders: raise RuntimeError( "You cannot specify a --forwarder option together with " "--no-forwarders") elif self.auto_forwarders and self.no_forwarders: raise RuntimeError( "You cannot specify a --auto-forwarders option together with " "--no-forwarders") elif self.reverse_zones and self.no_reverse: raise RuntimeError( "You cannot specify a --reverse-zone option together with " "--no-reverse") elif self.auto_reverse and self.no_reverse: raise RuntimeError( "You cannot specify a --auto-reverse option together with " "--no-reverse") if not hasattr(self, 'replica_file'): if self.external_cert_files and self.dirsrv_cert_files: raise RuntimeError( "Service certificate file options cannot be used with the " "external CA options.") if self.external_ca_type and not self.external_ca: raise RuntimeError( "You cannot specify --external-ca-type without " "--external-ca") 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.forwarders and not self.no_forwarders and not self.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)) else: cert_file_req = (self.dirsrv_cert_files, self.http_cert_files) cert_file_opt = (self.pkinit_cert_files, ) if self.replica_file is 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.servers and not self.domain_name: raise RuntimeError( "The --server option cannot be used without providing " "domain via the --domain option") else: if not ipautil.file_exists(self.replica_file): raise RuntimeError("Replica file %s does not exist" % self.replica_file) 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.servers, '--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.forwarders and not self.no_forwarders and not self.auto_forwarders): raise RuntimeError( "You must specify at least one of --forwarder, " "--auto-forwarders, or --no-forwarders options") # Automatically enable pkinit w/ dogtag self.no_pkinit = not self.setup_ca
class CAInstallInterface(dogtag.DogtagInstallInterface, conncheck.ConnCheckInterface): """ Interface of the CA installer Knobs defined here will be available in: * ipa-server-install * ipa-replica-prepare * ipa-replica-install * ipa-ca-install """ principal = knob( bases=conncheck.ConnCheckInterface.principal, description="User allowed to manage replicas", cli_names=(list(conncheck.ConnCheckInterface.principal.cli_names) + ['-P']), ) principal = enroll_only(principal) principal = replica_install_only(principal) admin_password = knob( bases=conncheck.ConnCheckInterface.admin_password, description="Admin user Kerberos password used for connection check", cli_names=( list(conncheck.ConnCheckInterface.admin_password.cli_names) + ['-w']), ) admin_password = enroll_only(admin_password) external_ca = knob( None, description=("Generate a CSR for the IPA CA certificate to be signed " "by an external CA"), ) external_ca = master_install_only(external_ca) external_ca_type = knob( ExternalCAType, None, description="Type of the external CA", ) external_ca_type = master_install_only(external_ca_type) external_cert_files = knob( # pylint: disable=invalid-sequence-index typing.List[str], None, description=("File containing the IPA CA certificate and the external " "CA certificate chain"), cli_names='--external-cert-file', cli_deprecated_names=['--external_cert_file', '--external_ca_file'], cli_metavar='FILE', ) external_cert_files = master_install_only(external_cert_files) @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") subject = knob( str, None, description="The certificate subject base (default O=<realm-name>)", ) subject = master_install_only(subject) @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( CASigningAlgorithm, None, description="Signing algorithm of the IPA CA certificate", ) ca_signing_algorithm = master_install_only(ca_signing_algorithm) skip_schema_check = knob( None, description="skip check for updated CA DS schema on the remote master", ) skip_schema_check = enroll_only(skip_schema_check) skip_schema_check = replica_install_only(skip_schema_check)