URL: https://github.com/freeipa/freeipa/pull/1723
Author: frasertweedale
 Title: #1723: replica-install: warn when there is only one CA in topology
Action: opened

PR body:
"""
For redundancy and security against catastrophic failure of a CA
master, there must be more than one CA master in a topology.
Replica installation is a good time to warn about this situation.
Print a warning at the end of ipa-replica-install, if there is only
one CA replica in the topology.

Fixes: https://pagure.io/freeipa/issue/7459
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1723/head:pr1723
git checkout pr1723
From 1f12e62e7d89d052be7be29bacfc36f7efba53c4 Mon Sep 17 00:00:00 2001
From: Fraser Tweedale <ftwee...@redhat.com>
Date: Mon, 19 Mar 2018 12:23:15 +1100
Subject: [PATCH] replica-install: warn when there is only one CA in topology

For redundancy and security against catastrophic failure of a CA
master, there must be more than one CA master in a topology.
Replica installation is a good time to warn about this situation.
Print a warning at the end of ipa-replica-install, if there is only
one CA replica in the topology.

Fixes: https://pagure.io/freeipa/issue/7459
---
 ipaserver/install/server/replicainstall.py |  9 ++++++++
 ipaserver/install/service.py               | 35 ++++++++++++++++++++----------
 2 files changed, 32 insertions(+), 12 deletions(-)

diff --git a/ipaserver/install/server/replicainstall.py b/ipaserver/install/server/replicainstall.py
index 4dc9435258..3ed9ecfe6c 100644
--- a/ipaserver/install/server/replicainstall.py
+++ b/ipaserver/install/server/replicainstall.py
@@ -1517,6 +1517,7 @@ def install(installer):
     if options.setup_adtrust:
         adtrust.install(False, options, fstore, api)
 
+    ca_servers = service.find_providing_servers('CA', api.Backend.ldap2, api)
     api.Backend.ldap2.disconnect()
 
     if not promote:
@@ -1549,6 +1550,14 @@ def install(installer):
     # Everything installed properly, activate ipa service.
     services.knownservices.ipa.enable()
 
+    # Print a warning if CA role is only installed on one server
+    if len(ca_servers) == 1:
+        print()
+        print("WARNING: The CA service is only installed on one server ({})."
+                .format(ca_servers[0]))
+        print("It is strongly recommended to install it on another server.")
+        print("Run ipa-ca-install(1) on another master to accomplish this.")
+
 
 def init(installer):
     installer.unattended = not installer.interactive
diff --git a/ipaserver/install/service.py b/ipaserver/install/service.py
index 327bbf1b26..d2ad87c859 100644
--- a/ipaserver/install/service.py
+++ b/ipaserver/install/service.py
@@ -112,14 +112,14 @@ def add_principals_to_group(admin_conn, group, member_attr, principals):
         pass
 
 
-def find_providing_server(svcname, conn, host_name=None, api=api):
+def find_providing_servers(svcname, conn, api):
     """
+    Find servers that provide the given service.
+
     :param svcname: The service to find
     :param conn: a connection to the LDAP server
-    :param host_name: the preferred server
-    :return: the selected host name
+    :return: list of host names (possibly empty)
 
-    Find a server that is a CA.
     """
     dn = DN(('cn', 'masters'), ('cn', 'ipa'), ('cn', 'etc'), api.env.basedn)
     query_filter = conn.make_filter({'objectClass': 'ipaConfigObject',
@@ -127,16 +127,27 @@ def find_providing_server(svcname, conn, host_name=None, api=api):
                                      'cn': svcname}, rules='&')
     try:
         entries, _trunc = conn.find_entries(filter=query_filter, base_dn=dn)
+        return [entry.dn[1].value for entry in entries]
     except errors.NotFound:
+        return []
+
+
+def find_providing_server(svcname, conn, host_name=None, api=api):
+    """
+    Find a server that provides the given service.
+
+    :param svcname: The service to find
+    :param conn: a connection to the LDAP server
+    :param host_name: the preferred server
+    :return: the selected host name
+
+    """
+    servers = find_providing_servers(svcname, conn, api)
+    if len(servers) == 0:
         return None
-    if len(entries):
-        if host_name is not None:
-            for entry in entries:
-                if entry.dn[1].value == host_name:
-                    return host_name
-        # if the preferred is not found, return the first in the list
-        return entries[0].dn[1].value
-    return None
+    if host_name in servers:
+        return host_name
+    return servers[0]
 
 
 def case_insensitive_attr_has_value(attr, value):
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to