On Fri, 2010-01-22 at 10:30 -0500, Rob Crittenden wrote:
> Martin Nagy wrote:
> > Hi,
> > these patches will allow one to specify an ip address of the replica to
> > ipa-replica-prepare. The dns records will then be added. This should
> > make life better for QA :)
> > 
> > Martin
> 
> nack, it shouldn't allow the option if DNS is not configured, or at 
> least it shouldn't blow up:
> 
> # ipa-replica-prepare --ip-address=192.168.166.9 replica4.example.com
> Directory Manager (existing master) password:
> 
> Preparing replica for replica4.example.com from luna.example.com
> Creating SSL certificate for the Directory Server
> Creating SSL certificate for the Web Server
> Exporting RA certificate
> Copying additional files
> Finalizing configuration
> Packaging replica information into 
> /var/lib/ipa/replica-info-replica4.example.com.gpg
> Adding DNS records for replica4.example.com
> preparation of replica failed: no such entry
> no such entry
>    File "/usr/sbin/ipa-replica-prepare", line 338, in <module>
>      main()
> 
>    File "/usr/sbin/ipa-replica-prepare", line 329, in main
>      zone = add_zone(domain)
> 
>    File 
> "/usr/lib/python2.6/site-packages/ipaserver/install/bindinstance.py", 
> line 73, in add_zone
>      idnsupdatepolicy=unicode(update_policy))
> 
>    File "/usr/lib/python2.6/site-packages/ipalib/frontend.py", line 412, 
> in __call__
>      ret = self.run(*args, **options)
> 
>    File "/usr/lib/python2.6/site-packages/ipalib/frontend.py", line 680, 
> in run
>      return self.execute(*args, **options)
> 
>    File "/usr/lib/python2.6/site-packages/ipalib/plugins/dns.py", line 
> 203, in execute
>      ldap.add_entry(dn, entry_attrs)
> 
>    File "/usr/lib/python2.6/site-packages/ipalib/encoder.py", line 188, 
> in new_f
>      return f(*new_args, **kwargs)
> 
>    File "/usr/lib/python2.6/site-packages/ipaserver/plugins/ldap2.py", 
> line 334, in add_entry
>      _handle_errors(e, **{})
> 
>    File "/usr/lib/python2.6/site-packages/ipaserver/plugins/ldap2.py", 
> line 71, in _handle_errors
>      raise errors.NotFound(reason='no such entry')
> 
> rob

Thanks, new patches attached.

Martin
>From 738dd1f022a946ff0b574128e9ed358efb5d3451 Mon Sep 17 00:00:00 2001
From: Martin Nagy <mn...@redhat.com>
Date: Mon, 8 Feb 2010 14:21:46 +0100
Subject: [PATCH 1/2] Get rid of ipapython.config in ipa-replica-prepare

Also get rid of functions get_host_name(), get_realm_name() and
get_domain_name(). They used the old ipapython.config. Instead, use the
variables from api.env. We also change them to bootstrap() and
finalize() correctly.

Additionally, we add the dns_container_exists() function that will be
used in ipa-replica-prepare (next patch).
---
 install/tools/ipa-replica-install |   30 ++++++-------
 install/tools/ipa-replica-prepare |   86 ++++++++++---------------------------
 ipaserver/install/bindinstance.py |   52 ++++++++++++-----------
 3 files changed, 63 insertions(+), 105 deletions(-)

diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index af7128c..4b348f6 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -311,12 +311,21 @@ def main():
     except ldap.INVALID_CREDENTIALS, e :
         sys.exit("\nThe password provided is incorrect for LDAP server %s" % config.master_host_name)
 
+    # Create the management framework config file
+    # Note: We must do this before bootstraping and finalizing ipalib.api
+    fd = open("/etc/ipa/default.conf", "w")
+    fd.write("[global]\n")
+    fd.write("basedn=" + util.realm_to_suffix(config.realm_name) + "\n")
+    fd.write("realm=" + config.realm_name + "\n")
+    fd.write("domain=" + config.domain_name + "\n")
+    fd.write("xmlrpc_uri=https://%s/ipa/xml\n"; % config.host_name)
+    fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % dsinstance.realm_to_serverid(config.realm_name))
     if ipautil.file_exists(config.dir + "/ca.p12"):
-        ca_type = 'dogtag'
-    else:
-        ca_type = 'selfsign'
+        fd.write("enable_ra=True\n")
+        fd.write("ra_plugin=dogtag\n")
+    fd.close()
 
-    api.bootstrap(in_server=True, ra_plugin=ca_type)
+    api.bootstrap(in_server=True)
     api.finalize()
 
     # Install CA cert so that we can do SSL connections with ldap
@@ -355,19 +364,6 @@ def main():
     # generated
     ds.add_cert_to_service()
 
-    # Create the management framework config file
-    fd = open("/etc/ipa/default.conf", "w")
-    fd.write("[global]\n")
-    fd.write("basedn=" + util.realm_to_suffix(config.realm_name) + "\n")
-    fd.write("realm=" + config.realm_name + "\n")
-    fd.write("domain=" + config.domain_name + "\n")
-    fd.write("xmlrpc_uri=https://%s/ipa/xml\n"; % config.host_name)
-    fd.write("ldap_uri=ldapi://%%2fvar%%2frun%%2fslapd-%s.socket\n" % dsinstance.realm_to_serverid(config.realm_name))
-    if ipautil.file_exists(config.dir + "/ca.p12"):
-        fd.write("enable_ra=True\n")
-        fd.write("ra_plugin=dogtag\n")
-    fd.close()
-
     # Apply any LDAP updates. Needs to be done after the replica is synced-up
     service.print_msg("Applying LDAP updates")
     ds.apply_updates()
diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare
index f9977ec..d89d1a6 100755
--- a/install/tools/ipa-replica-prepare
+++ b/install/tools/ipa-replica-prepare
@@ -26,12 +26,10 @@ from ConfigParser import SafeConfigParser
 import krbV
 from optparse import OptionParser
 
-import ipapython.config
 from ipapython import ipautil
 from ipaserver.install import dsinstance, installutils, certs, httpinstance
 from ipaserver import ipaldap
 from ipapython import version
-from ipalib.constants import DEFAULT_CONFIG
 from ipalib import api
 from ipalib import util
 import ldap
@@ -51,7 +49,6 @@ def parse_options():
     parser.add_option("-p", "--password", dest="password", 
                       help="Directory Manager (existing master) password")
 
-    ipapython.config.add_standard_options(parser)
     options, args = parser.parse_args()
 
     # If any of the PKCS#12 options are selected, all are required. Create a
@@ -62,39 +59,16 @@ def parse_options():
     if cnt > 0 and cnt < 4:
         parser.error("All PKCS#12 options are required if any are used.")
 
+    if options.ip_address:
+        if not installutils.verify_ip_address(options.ip_address):
+            parser.error("Bad IP address")
+            sys.exit(1)
+
     if len(args) != 1:
         parser.error("must provide the fully-qualified name of the replica")
 
-    ipapython.config.init_config(options)
-
     return options, args
 
-def get_host_name():
-    hostname = installutils.get_fqdn()
-    try:
-        installutils.verify_fqdn(hostname)
-    except RuntimeError, e:
-        logging.error(str(e))
-        sys.exit(1)
-
-    return hostname
-
-def get_realm_name():
-    try:
-        c = krbV.default_context()
-        return c.default_realm
-    except Exception, e:
-        return None
-
-def get_domain_name():
-    try:
-        ipapython.config.init_config()
-        domain_name = ipapython.config.config.get_domain()
-    except Exception, e:
-        return None
-
-    return domain_name
-
 def get_subject_base(host_name, dm_password, suffix):
     try:
         conn = ipaldap.IPAdmin(host_name)
@@ -130,8 +104,8 @@ def export_certdb(realm_name, ds_dir, dir, passwd_fname, fname, hostname, subjec
 #            ca_db = certs.CertDB(dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name)))
 #            db.create_from_cacert(ca_db.cacert_fname)
 #        else:
-#            ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=get_host_name())
-        ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=get_host_name(), subject_base=subject_base)
+#            ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=api.env.host)
+        ca_db = certs.CertDB(httpinstance.NSS_DIR, host_name=api.env.host, subject_base=subject_base)
         db.create_from_cacert(ca_db.cacert_fname)
         db.create_server_cert("Server-Cert", hostname, ca_db)
     except Exception, e:
@@ -169,7 +143,7 @@ def export_ra_pkcs12(dir, dm_password):
 
     try:
         try:
-            db = certs.CertDB(httpinstance.NSS_DIR, host_name=get_host_name())
+            db = certs.CertDB(httpinstance.NSS_DIR, host_name=api.env.host)
 
             if db.has_nickname("ipaCert"):
                 pkcs12_fname = "%s/ra.p12" % dir
@@ -229,31 +203,18 @@ def main():
 
     # Just initialize the environment. This is so the installer can have
     # access to the plugin environment
-    api.env._bootstrap()
-    api.env._finalize_core(**dict(DEFAULT_CONFIG))
+    api.bootstrap(in_server=True)
+    api.finalize()
 
     if not certs.ipa_self_signed() and not ipautil.file_exists("/var/lib/pki-ca/conf/CS.cfg") and not options.dirsrv_pin:
         sys.exit("The replica must be created on the primary IPA server.\nIf you installed IPA with your own certificates using PKCS#12 files you must provide PKCS#12 files for any replicas you create as well.")
 
-    print "Determining current realm name"
-    realm_name = get_realm_name()
-    if realm_name is None:
-        print "Unable to determine default realm"
-        sys.exit(1)
-
-    check_ipa_configuration(realm_name)
-
-    print "Getting domain name from LDAP"
-    domain_name = get_domain_name()
-    if domain_name is None:
-        print "Unable to determine LDAP default domain"
-        sys.exit(1)
+    check_ipa_configuration(api.env.realm)
 
-    host_name = get_host_name()
-    if host_name == replica_fqdn:
+    if api.env.host == replica_fqdn:
         print "You can't create a replica on itself"
         sys.exit(1)
-    ds_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(realm_name))
+    ds_dir = dsinstance.config_dirname(dsinstance.realm_to_serverid(api.env.realm))
     ds_user = get_ds_user(ds_dir)
 
     # get the directory manager password
@@ -266,19 +227,19 @@ def main():
 
     # Try out the password
     try:
-        conn = ipaldap.IPAdmin(host_name)
+        conn = ipaldap.IPAdmin(api.env.host)
         conn.do_simple_bind(bindpw=dirman_password)
         conn.unbind()
     except ldap.CONNECT_ERROR, e:
-        sys.exit("\nUnable to connect to LDAP server %s" % host_name)
+        sys.exit("\nUnable to connect to LDAP server %s" % api.env.host)
     except ldap.SERVER_DOWN, e:
-        sys.exit("\nUnable to connect to LDAP server %s" % host_name)
+        sys.exit("\nUnable to connect to LDAP server %s" % api.env.host)
     except ldap.INVALID_CREDENTIALS, e :
-        sys.exit("\nThe password provided is incorrect for LDAP server %s" % host_name)
+        sys.exit("\nThe password provided is incorrect for LDAP server %s" % api.env.host)
 
-    print "Preparing replica for %s from %s" % (replica_fqdn, host_name)
+    print "Preparing replica for %s from %s" % (replica_fqdn, api.env.host)
 
-    subject_base = get_subject_base(host_name, dirman_password, util.realm_to_suffix(realm_name))
+    subject_base = get_subject_base(api.env.host, dirman_password, util.realm_to_suffix(api.env.realm))
 
     top_dir = tempfile.mkdtemp("ipa")
     dir = top_dir + "/realm_info"
@@ -313,7 +274,7 @@ def main():
             print "Copy failed %s" %  e
             sys.exit(1)
         print "Creating SSL certificate for the Directory Server"
-        export_certdb(realm_name, ds_dir, dir, passwd_fname, "dscert", replica_fqdn, subject_base)
+        export_certdb(api.env.realm, ds_dir, dir, passwd_fname, "dscert", replica_fqdn, subject_base)
 
     if options.http_pin:
         passwd = options.http_pin
@@ -334,15 +295,14 @@ def main():
             sys.exit(1)
     else:
         print "Creating SSL certificate for the Web Server"
-        export_certdb(realm_name, ds_dir, dir, passwd_fname, "httpcert", replica_fqdn, subject_base)
+        export_certdb(api.env.realm, ds_dir, dir, passwd_fname, "httpcert", replica_fqdn, subject_base)
         print "Exporting RA certificate"
         export_ra_pkcs12(dir, dirman_password)
 
     print "Copying additional files"
-    copy_files(realm_name, dir)
-
+    copy_files(api.env.realm, dir)
     print "Finalizing configuration"
-    save_config(dir, realm_name, host_name, ds_user, domain_name, replica_fqdn, subject_base)
+    save_config(dir, api.env.realm, api.env.host, ds_user, api.env.domain, replica_fqdn, subject_base)
 
     replicafile = "/var/lib/ipa/replica-info-" + replica_fqdn
     encfile = replicafile+".gpg"
diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py
index 13e9e16..105cf4e 100644
--- a/ipaserver/install/bindinstance.py
+++ b/ipaserver/install/bindinstance.py
@@ -54,6 +54,31 @@ def check_inst(unattended):
 
     return True
 
+def dns_container_exists(fqdn, realm):
+    """
+    Test whether the dns container exists.
+    """
+
+    def object_exists(dn):
+        """
+        Test whether the given object exists in LDAP.
+        """
+        try:
+            server.search_ext_s(dn, ldap.SCOPE_BASE)
+        except ldap.NO_SUCH_OBJECT:
+            return False
+        else:
+            return True
+
+    server = ldap.initialize("ldap://"; + fqdn)
+    server.simple_bind_s()
+
+    suffix = util.realm_to_suffix(realm)
+    ret = object_exists("cn=dns,%s" % suffix)
+    server.unbind_s()
+
+    return ret
+
 def get_reverse_zone(ip_address):
     tmp = ip_address.split(".")
     tmp.reverse()
@@ -155,7 +180,8 @@ class BindInstance(service.Service):
         except:
             pass
 
-        self.__add_zone_steps()
+        if not dns_container_exists(self.fqdn, self.suffix):
+            self.step("adding DNS container", self.__setup_dns_container)
         self.step("setting up our zone", self.__setup_zone)
         self.step("setting up reverse zone", self.__setup_reverse_zone)
 
@@ -168,30 +194,6 @@ class BindInstance(service.Service):
         self.step("changing resolv.conf to point to ourselves", self.__setup_resolv_conf)
         self.start_creation("Configuring named:")
 
-    def __add_zone_steps(self):
-        """
-        Add a DNS container if it doesn't exist.
-        """
-
-        def object_exists(dn):
-            """
-            Test whether the given object exists in LDAP.
-            """
-            try:
-                server.search_ext_s(dn, ldap.SCOPE_BASE)
-            except ldap.NO_SUCH_OBJECT:
-                return False
-            else:
-                return True
-
-        server = ldap.initialize("ldap://"; + self.fqdn)
-        server.simple_bind_s()
-
-        if not object_exists("cn=dns,%s" % self.suffix):
-            self.step("adding DNS container", self.__setup_dns_container)
-
-        server.unbind_s()
-
     def __start(self):
         try:
             self.backup_state("running", self.is_running())
-- 
1.6.2.5

>From c62879991a383d66e12af2f5097bdc387a780cba Mon Sep 17 00:00:00 2001
From: Martin Nagy <mn...@redhat.com>
Date: Mon, 23 Nov 2009 16:16:58 +0100
Subject: [PATCH 2/2] Add A and PTR records during ipa-replica-prepare

Fixes #528996
---
 install/tools/ipa-replica-prepare       |   23 ++++++++++++++++++++++-
 install/tools/man/ipa-replica-prepare.1 |    3 +++
 2 files changed, 25 insertions(+), 1 deletions(-)

diff --git a/install/tools/ipa-replica-prepare b/install/tools/ipa-replica-prepare
index d89d1a6..c9f1ad0 100755
--- a/install/tools/ipa-replica-prepare
+++ b/install/tools/ipa-replica-prepare
@@ -27,7 +27,8 @@ import krbV
 from optparse import OptionParser
 
 from ipapython import ipautil
-from ipaserver.install import dsinstance, installutils, certs, httpinstance
+from ipaserver.install import bindinstance, dsinstance, installutils, certs, httpinstance
+from ipaserver.install.bindinstance import add_zone, add_reverze_zone, add_rr, add_ptr_rr
 from ipaserver import ipaldap
 from ipapython import version
 from ipalib import api
@@ -48,6 +49,8 @@ def parse_options():
                       help="PIN for the Apache Server PKCS#12 file")
     parser.add_option("-p", "--password", dest="password", 
                       help="Directory Manager (existing master) password")
+    parser.add_option("--ip-address", dest="ip_address",
+                      help="Add A and PTR records of the future replica")
 
     options, args = parser.parse_args()
 
@@ -206,6 +209,11 @@ def main():
     api.bootstrap(in_server=True)
     api.finalize()
 
+    if options.ip_address:
+        if not bindinstance.dns_container_exists(api.env.host, api.env.realm):
+            print "You can't add a DNS record because DNS is not set up."
+            sys.exit(1)
+
     if not certs.ipa_self_signed() and not ipautil.file_exists("/var/lib/pki-ca/conf/CS.cfg") and not options.dirsrv_pin:
         sys.exit("The replica must be created on the primary IPA server.\nIf you installed IPA with your own certificates using PKCS#12 files you must provide PKCS#12 files for any replicas you create as well.")
 
@@ -314,6 +322,19 @@ def main():
     remove_file(replicafile)
     shutil.rmtree(dir)
 
+    if options.ip_address:
+        print "Adding DNS records for %s" % replica_fqdn
+        api.Backend.ldap2.connect(bind_dn="cn=Directory Manager", bind_pw=dirman_password)
+
+        domain = replica_fqdn.split(".")
+        name = domain.pop(0)
+        domain = ".".join(domain)
+
+        zone = add_zone(domain)
+        add_rr(zone, name, "A", options.ip_address)
+        add_reverze_zone(options.ip_address)
+        add_ptr_rr(options.ip_address, replica_fqdn)
+
 try:
     if not os.geteuid()==0:
         sys.exit("\nYou must be root to run this script.\n")
diff --git a/install/tools/man/ipa-replica-prepare.1 b/install/tools/man/ipa-replica-prepare.1
index 8eb4944..5c0e0d1 100644
--- a/install/tools/man/ipa-replica-prepare.1
+++ b/install/tools/man/ipa-replica-prepare.1
@@ -42,6 +42,9 @@ The password of the Directory Server PKCS#12 file
 .TP
 \fB\-\-http_pin\fR=\fIHTTP_PIN\fR
 The password of the Apache Server PKCS#12 file
+.TP
+\fB\-\-ip\-address\fR=\fIIP_ADDRESS\fR
+IP address of the replica server. If you provide this option, the A and PTR records will be added to the DNS.
 .SH "EXIT STATUS"
 0 if the command was successful
 
-- 
1.6.2.5

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to