rblanche: allow checking deactivations (-d)
authorAlex Dehnert <adehnert@mit.edu>
Sat, 12 Oct 2013 18:06:19 +0000 (14:06 -0400)
committerAlex Dehnert <adehnert@mit.edu>
Sat, 12 Oct 2013 18:06:19 +0000 (14:06 -0400)
This is the final feature that consult's Perl rblanche has, I believe.

rblanche.py

index 9eb995f186d891313665d52845a54ea9e99ca07f..c6de2de10e71edf0aafbd97e61a232c217488ed2 100755 (executable)
@@ -1,20 +1,28 @@
 #!/usr/bin/python
+import errno
 import optparse
 import sys
 
 import moira
 
+try:
+    import hesiod
+except ImportError:
+    hesiod = None
+
 def get_members_of_list(lst):
     return moira.query('get_members_of_list', lst)
 
 class RBlanche(object):
-    def __init__(self, chpoboxing=False, ):
+    def __init__(self, chpoboxing=False, deactivations=False):
         self.reset_caches()
         self.chpoboxing = chpoboxing
+        self.deactivations = deactivations
 
     def reset_caches(self, ):
         self.cache = {}
         self.chpobox = {}
+        self.user_active = {}
 
     def expand(self, lst):
         if lst in self.cache: return self.cache[lst]
@@ -48,13 +56,29 @@ class RBlanche(object):
         text = ('%8s ' + fmt) % (result['login'], result['address'], )
         return text
 
+    def check_deactivated(self, user):
+        try:
+            passwd = hesiod.PasswdLookup(user)
+            return ""
+        except IOError, e:
+            if e.errno == errno.ENOENT:
+                return " ** deactivated **"
+            else:
+                raise
+
     def format_user(self, user):
         text = user
         if self.chpoboxing:
             if user not in self.chpobox:
                 self.chpobox[user] = self.get_and_format_pobox(user)
             text = self.chpobox[user]
-        return text
+        if self.deactivations:
+            if user not in self.user_active:
+                self.user_active[user] = self.check_deactivated(user)
+            append = self.user_active[user]
+        else:
+            append = ""
+        return text + append
 
     def print_tree(self, path, lst_tree):
         for member in lst_tree:
@@ -84,17 +108,22 @@ def parse_args():
                 dest='chpoboxing', action='store_true', default=False,
                 help='check mail forwarding for each user',
     )
+    parser.add_option('-d', '--deactivated',
+                dest='deactivations', action='store_true', default=False,
+                help='check whether users are deactivated',
+    )
     options, args = parser.parse_args()
 
     if len(args) != 1:
         parser.error("incorrect number of arguments")
-
     if options.auth:
         if options.auth == 'yes': options.auth = True
         elif options.auth == 'try': options.auth = None
         elif options.auth == 'no': options.auth = False
         else:
             parser.error("--auth takes yes, no, and try (default; auth if possible)")
+    if options.deactivations and not hesiod:
+        parser.error("deactivation checking requires python-hesiod, which is not available")
 
     return options, args
 
@@ -108,5 +137,8 @@ if __name__ == '__main__':
             moira.auth('rblnchpy')
         except moira.MoiraException:
             print >>sys.stderr, "Warning: Failed to authenticate to moira"
-    rblanche = RBlanche(chpoboxing=options.chpoboxing)
+    rblanche = RBlanche(
+        chpoboxing=options.chpoboxing,
+        deactivations=options.deactivations,
+    )
     rblanche.rblanche(args[0])