summaryrefslogtreecommitdiffstats
path: root/ipaserver
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2013-03-01 15:02:14 -0500
committerRob Crittenden <rcritten@redhat.com>2013-03-13 10:32:36 -0400
commit9005b9bc8aac7c1381aadb7d17107ebbebae005d (patch)
tree15c0b3ce22d95e265130bf8fcb815bdf79e6b4dc /ipaserver
parent63407ed477035765dda38fbead1353d4f47ac26a (diff)
downloadfreeipa-9005b9bc8aac7c1381aadb7d17107ebbebae005d.tar.gz
freeipa-9005b9bc8aac7c1381aadb7d17107ebbebae005d.tar.xz
freeipa-9005b9bc8aac7c1381aadb7d17107ebbebae005d.zip
Extend ipa-replica-manage to be able to manage DNA ranges.
Attempt to automatically save DNA ranges when a master is removed. This is done by trying to find a master that does not yet define a DNA on-deck range. If one can be found then the range on the deleted master is added. If one cannot be found then it is reported as an error. Some validation of the ranges are done to ensure that they do overlap an IPA local range and do not overlap existing DNA ranges configured on other masters. http://freeipa.org/page/V3/Recover_DNA_Ranges https://fedorahosted.org/freeipa/ticket/3321
Diffstat (limited to 'ipaserver')
-rw-r--r--ipaserver/install/dsinstance.py3
-rw-r--r--ipaserver/install/replication.py98
2 files changed, 99 insertions, 2 deletions
diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py
index 23843d759..c744c9ca9 100644
--- a/ipaserver/install/dsinstance.py
+++ b/ipaserver/install/dsinstance.py
@@ -218,6 +218,7 @@ class DsInstance(service.Service):
self.step("adding master entry", self.__add_master_entry)
self.step("configuring Posix uid/gid generation",
self.__config_uidgid_gen)
+ self.step("adding replication acis", self.__add_replication_acis)
self.step("enabling compatibility plugin",
self.__enable_compat_plugin)
self.step("tuning directory server", self.__tuning)
@@ -253,7 +254,6 @@ class DsInstance(service.Service):
self.step("adding default layout", self.__add_default_layout)
self.step("adding delegation layout", self.__add_delegation_layout)
- self.step("adding replication acis", self.__add_replication_acis)
self.step("creating container for managed entries", self.__managed_entries)
self.step("configuring user private groups", self.__user_private_groups)
self.step("configuring netgroups from hostgroups", self.__host_nis_groups)
@@ -284,7 +284,6 @@ class DsInstance(service.Service):
self.__common_setup(True)
self.step("setting up initial replication", self.__setup_replica)
- self.step("adding replication acis", self.__add_replication_acis)
# See LDIFs for automember configuration during replica install
self.step("setting Auto Member configuration", self.__add_replica_automember_config)
self.step("enabling S4U2Proxy delegation", self.__setup_s4u2proxy)
diff --git a/ipaserver/install/replication.py b/ipaserver/install/replication.py
index 076d4f87f..c1ca0aaa6 100644
--- a/ipaserver/install/replication.py
+++ b/ipaserver/install/replication.py
@@ -37,6 +37,7 @@ IPA_USER_CONTAINER = DN(('cn', 'users'), ('cn', 'accounts'))
PORT = 636
TIMEOUT = 120
REPL_MAN_DN = DN(('cn', 'replication manager'), ('cn', 'config'))
+DNA_DN = DN(('cn', 'Posix IDs'), ('cn', 'Distributed Numeric Assignment Plugin'), ('cn', 'plugins'), ('cn', 'config'))
IPA_REPLICA = 1
WINSYNC = 2
@@ -1307,3 +1308,100 @@ class ReplicationManager(object):
print "This may be safely interrupted with Ctrl+C"
wait_for_task(self.conn, dn)
+
+ def get_DNA_range(self, hostname):
+ """
+ Return the DNA range on this server as a tuple, (next, max), or
+ (None, None) if no range has been assigned yet.
+
+ Raises an exception on errors reading an entry.
+ """
+ entry = self.conn.get_entry(DNA_DN)
+
+ nextvalue = int(entry.single_value("dnaNextValue", 0))
+ maxvalue = int(entry.single_value("dnaMaxValue", 0))
+
+ sharedcfgdn = entry.single_value("dnaSharedCfgDN", None)
+ if sharedcfgdn is not None:
+ sharedcfgdn = DN(sharedcfgdn)
+
+ shared_entry = self.conn.get_entry(sharedcfgdn)
+ remaining = int(shared_entry.single_value("dnaRemainingValues", 0))
+ else:
+ remaining = 0
+
+ if nextvalue == 0 and maxvalue == 0:
+ return (None, None)
+
+ # Check the magic values for an unconfigured DNA entry
+ if maxvalue == 1100 and nextvalue == 1101 and remaining == 0:
+ return (None, None)
+ else:
+ return (nextvalue, maxvalue)
+
+ def get_DNA_next_range(self, hostname):
+ """
+ Return the DNA "on-deck" range on this server as a tuple, (next, max),
+ or
+ (None, None) if no range has been assigned yet.
+
+ Raises an exception on errors reading an entry.
+ """
+ entry = self.conn.get_entry(DNA_DN)
+
+ range = entry.single_value("dnaNextRange", None)
+
+ if range is None:
+ return (None, None)
+
+ try:
+ (next, max) = range.split('-')
+ except ValueError:
+ # Should not happen, malformed entry, return nothing.
+ return (None, None)
+
+ return (int(next), int(max))
+
+ def save_DNA_next_range(self, next_start, next_max):
+ """
+ Save a DNA range into the on-deck value.
+
+ This adds a dnaNextRange value to the DNA configuration. This
+ attribute takes the form of start-next.
+
+ Returns True on success.
+ Returns False if the range is already defined.
+ Raises an exception on failure.
+ """
+ entry = self.conn.get_entry(DNA_DN)
+
+ range = entry.single_value("dnaNextRange", None)
+
+ if range is not None and next_start != 0 and next_max != 0:
+ return False
+
+ if next_start == 0 and next_max == 0:
+ entry["dnaNextRange"] = None
+ else:
+ entry["dnaNextRange"] = "%s-%s" % (next_start, next_max)
+
+ self.conn.update_entry(entry)
+
+ return True
+
+ def save_DNA_range(self, next_start, next_max):
+ """
+ Save a DNA range.
+
+ This is potentially very dangerous.
+
+ Returns True on success. Raises an exception on failure.
+ """
+ entry = self.conn.get_entry(DNA_DN)
+
+ entry["dnaNextValue"] = next_start
+ entry["dnaMaxValue"] = next_max
+
+ self.conn.update_entry(entry)
+
+ return True