From 9d0e6991fc23c073efc0db6bf10e1081f6725e55 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 5 Feb 2013 12:13:20 -0500 Subject: abstracted similar digit range classes in POSIXUsers/GroupPatterns into Bcfg2.Utils --- src/lib/Bcfg2/Client/Tools/POSIXUsers.py | 45 ++---------------- src/lib/Bcfg2/Server/Plugins/GroupPatterns.py | 23 +-------- src/lib/Bcfg2/Utils.py | 67 +++++++++++++++++++++++++++ 3 files changed, 73 insertions(+), 62 deletions(-) create mode 100644 src/lib/Bcfg2/Utils.py (limited to 'src/lib') diff --git a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py index 7c8a4d578..849785e4a 100644 --- a/src/lib/Bcfg2/Client/Tools/POSIXUsers.py +++ b/src/lib/Bcfg2/Client/Tools/POSIXUsers.py @@ -5,44 +5,9 @@ import sys import pwd import grp import subprocess +from Bcfg2.Utils import PackedDigitRange import Bcfg2.Client.XML import Bcfg2.Client.Tools -from Bcfg2.Compat import any # pylint: disable=W0622 - - -class IDRangeSet(object): - """ Representation of a set of integer ranges. Used to describe - which UID/GID ranges are managed or unmanaged. """ - - def __init__(self, *ranges): - self.ranges = [] - self.ints = [] - self.str = ",".join(str(r) for r in ranges) - for item in ranges: - item = str(item).strip() - if item.endswith("-"): - self.ranges.append((int(item[:-1]), None)) - elif '-' in str(item): - self.ranges.append(tuple(int(x) for x in item.split('-'))) - else: - self.ints.append(int(item)) - - def __contains__(self, other): - other = int(other) - if other in self.ints: - return True - return any((end is None and other >= start) or - (end is not None and other >= start and other <= end) - for start, end in self.ranges) - - def __repr__(self): - return "%s:%s" % (self.__class__.__name__, str(self)) - - def __str__(self): - return "[%s]" % self.str - - def __len__(self): - return len(self.ranges) + len(self.ints) class ExecutionError(Exception): @@ -124,16 +89,16 @@ class POSIXUsers(Bcfg2.Client.Tools.Tool): self._blacklist = dict(POSIXUser=None, POSIXGroup=None) if self.setup['posix_uid_whitelist']: self._whitelist['POSIXUser'] = \ - IDRangeSet(*self.setup['posix_uid_whitelist']) + PackedDigitRange(*self.setup['posix_uid_whitelist']) else: self._blacklist['POSIXUser'] = \ - IDRangeSet(*self.setup['posix_uid_blacklist']) + PackedDigitRange(*self.setup['posix_uid_blacklist']) if self.setup['posix_gid_whitelist']: self._whitelist['POSIXGroup'] = \ - IDRangeSet(*self.setup['posix_gid_whitelist']) + PackedDigitRange(*self.setup['posix_gid_whitelist']) else: self._blacklist['POSIXGroup'] = \ - IDRangeSet(*self.setup['posix_gid_blacklist']) + PackedDigitRange(*self.setup['posix_gid_blacklist']) @property def existing(self): diff --git a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py index 1b12e590a..5716a134f 100644 --- a/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py +++ b/src/lib/Bcfg2/Server/Plugins/GroupPatterns.py @@ -6,28 +6,7 @@ import sys import logging import Bcfg2.Server.Lint import Bcfg2.Server.Plugin -from Bcfg2.Compat import any # pylint: disable=W0622 - - -class PackedDigitRange(object): - """ Helper object for NameRange entries """ - - def __init__(self, digit_range): - self.sparse = list() - self.ranges = list() - for item in digit_range.split(','): - if '-' in item: - self.ranges.append(tuple([int(x) for x in item.split('-')])) - else: - self.sparse.append(int(item)) - - def includes(self, other): - """ return True if other is included in this range """ - iother = int(other) - if iother in self.sparse: - return True - return any(iother in range(start, end + 1) - for start, end in self.ranges) +from Bcfg2.Utils import PackedDigitRange class PatternMap(object): diff --git a/src/lib/Bcfg2/Utils.py b/src/lib/Bcfg2/Utils.py new file mode 100644 index 000000000..ba17e1a63 --- /dev/null +++ b/src/lib/Bcfg2/Utils.py @@ -0,0 +1,67 @@ +""" Miscellaneous useful utility functions, classes, etc., that are +used by both client and server. Stuff that doesn't fit anywhere +else. """ + +from Bcfg2.Compat import any # pylint: disable=W0622 + + +class PackedDigitRange(object): + """ Representation of a set of integer ranges. A range is + described by a comma-delimited string of integers and ranges, + e.g.:: + + 1,10-12,15-20 + + Ranges are inclusive on both bounds, and may include 0. Negative + numbers are not supported.""" + + def __init__(self, *ranges): + """ May be instantiated in one of two ways:: + + PackedDigitRange() + + Or:: + + PackedDigitRange([, [, ...]]) + + E.g., both of the following are valid:: + + PackedDigitRange("1-5,7, 10-12") + PackedDigitRange("1-5", 7, "10-12") + """ + self.ranges = [] + self.ints = [] + self.str = ",".join(str(r) for r in ranges) + if len(ranges) == 1 and "," in ranges[0]: + ranges = ranges[0].split(",") + for item in ranges: + item = str(item).strip() + if item.endswith("-"): + self.ranges.append((int(item[:-1]), None)) + elif '-' in str(item): + self.ranges.append(tuple(int(x) for x in item.split('-'))) + else: + self.ints.append(int(item)) + + def includes(self, other): + """ Return True if ``other`` is included in this range. + Functionally equivalent to ``other in range``, which should be + used instead. """ + return other in self + + def __contains__(self, other): + other = int(other) + if other in self.ints: + return True + return any((end is None and other >= start) or + (end is not None and other >= start and other <= end) + for start, end in self.ranges) + + def __repr__(self): + return "%s:%s" % (self.__class__.__name__, str(self)) + + def __str__(self): + return "[%s]" % self.str + + def __len__(self): + return sum(r[1] - r[0] + 1 for r in self.ranges) + len(self.ints) -- cgit v1.2.3-1-g7c22