#!/usr/bin/env python # Zarko, 2018 # see the algorithm # --------------------------------------- from time import gmtime, strftime import os import getpass import subprocess import sys import paramiko import argparse import logging, logging.handlers # for sending email import smtplib from email.mime.image import MIMEImage from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText # ------------ define colors class color: PURPLE = '\033[95m' CYAN = '\033[96m' DARKCYAN = '\033[36m' BLUE = '\033[94m' GREEN = '\033[92m' YELLOW = '\033[93m' RED = '\033[91m' BOLD = '\033[1m' UNDERLINE = '\033[4m' END = '\033[0m' # ------------------ define LOGGING ----------- LOG_FILE = '/var/log/mkipahome/mkipahome.log' formatter = logging.Formatter('%(asctime)s:%(levelname)s: %(message)s') handler = logging.handlers.TimedRotatingFileHandler(LOG_FILE, when='MIDNIGHT', backupCount=50, utc=False) handler.setFormatter(formatter) # Set up a specific logger with our desired output level logger = logging.getLogger(__name__) #logger = logging.getLogger('MyLogger') logger.addHandler(handler) logger.setLevel(logging.DEBUG) # -- BASIC logging, no rotation #logging.basicConfig(filename=LOG_FILE, level=logging.DEBUG, format='%(asctime)s : %(message)s') # -- if you don't want log into file, but on screen #logging.basicConfig(level=logging.DEBUG, format='%(asctime)s : %(message)s') # ---------------------------------------------- logger.debug("") logger.debug(color.GREEN + "START AT : " + strftime("%a, %d %b %Y %H:%M:%S", gmtime()) + color.END) # -------------- Am I root ? def i_am_root(): """ Check if root runs script """ i_am=getpass.getuser() return True if i_am != "root" else False if not i_am_root(): logger.debug(color.RED + "Root can't run this script, quitting." + color.END + " Do it as yourself, since you'll need to SSH to other systems.") sys.exit(color.RED + "\nRoot can't run this script, quitting." + color.END + "\nDo it as yourself, since you'll need to SSH to other systems.\n") # ---------------- get who runs script i_am=getpass.getuser() logger.debug("The script is run by " + i_am) # --------------- check for kerberos ticket def has_kerberos_ticket(): """ Does a user who runs the script have valid kerberos ticket? """ return True if subprocess.call(['klist', '-s']) == 0 else False logger.debug("Check if operator has kerberos ticket") if not has_kerberos_ticket(): logger.debug("You do not have a kerberos ticket! Run 'kinit' to obtain one. Quitting.") sys.exit("You do not have a kerberos ticket! Run 'kinit' to obtain one. Quitting.") logger.debug("Seems that operator has kerberos ticket") # ------------------ argument work parser = argparse.ArgumentParser(description='Creation of CA-LDAP home.') parser.add_argument("-u", "--username", help="User who needs CA-LDAP home, must be CA-LDAP user login", required=True) args = parser.parse_args() user_name=args.username # ------------ user in IPA ? def user_in_ipa(): """ Check if user has IPA account """ return True if subprocess.call(['ipa', 'user-find', '--login', '%s' % user_name]) == 0 else False if not user_in_ipa(): logger.debug(color.RED + "User " + user_name + " doesn't exist in CA-LDAP, exiting!" + color.END) sys.exit(color.RED + "User with login name %s doesn't exist in CA-LDAP, exiting!" % user_name + color.END) else: print (color.GREEN + "OK : Good, user %s exists in CA-LDAP" % user_name + color.END) logger.debug("OK : Good, user %s exists in CA-LDAP" % user_name) # ---------------- ask for passwords logger.debug(color.CYAN + "Start asking for dsee/ca-ldap passwords" + color.END) print("\nGood day " + color.YELLOW + i_am + color.END + ". You'll need " + color.BOLD + color.RED + "CA-LDAP" + color.END + " and " + color.BOLD + color.RED + "DSEE" + color.END + " account for this to work. \n" + "Since you are here, you have CA-LDAP one, but if you don't have DSEE one, \n" + "then exit with ctrl+d and get DSEE account " + color.UNDERLINE + "ASAP." + color.END + "\n" + "Meanwhile, ask CA-LDAP SME for help. \n" + "\n") my_dsee_passwd=raw_input(color.GREEN + "Enter DSEE password: " + color.END + "\n" + "Note: if you use public key to SSH to DSEE systems (used to check for DSEE home)," + " then anything you type here will work." + "\n") my_ipa_passwd=raw_input(color.GREEN + "Enter CA-LDAP password: " + color.END + "\n" + "Note: if you use public key to SSH to ca-server4 (used to create CA-LDAP home)," + " then anything you type here will work." + "\n") logger.debug(color.CYAN + "Done with asking for dsee/ca-ldap passwords" + color.END) # -------------------------------------------------------------------------------------- dsee_server="dsee-server-whq.us.domain.com" print("INFO : Using DSEE server : %s") % dsee_server logger.debug(color.CYAN + "Using DSEE server " + dsee_server + color.END) def user_in_dsee(): """ Check if user has DSEE account. """ try: client = paramiko.SSHClient() print("INFO : Checking if %s exist in DSEE") % user_name logger.debug(color.CYAN + "Checking if " + user_name + " exist in DSEE" + color.END) client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=dsee_server, username=i_am, password=my_dsee_passwd) stdin, stdout, stderr = client.exec_command('/usr/bin/id %s' % user_name, get_pty=True) if stdout.channel.recv_exit_status() == 0: print("INFO : User %s has DSEE account.") % user_name logger.debug(color.CYAN + "User " + user_name + " has DSEE account." + color.END) automount_in_dsee() else: print("INFO : User %s does not have DSEE account.") % user_name logger.debug(color.CYAN + "User " + user_name + " does not have DSEE account." + color.END) ipa_home_exist() except paramiko.AuthenticationException: print ("ERROR : DSEE Auth failed") logger.debug(color.RED + "DSEE Auth failed" + color.END) sys.exit(10) except: print ("ERROR : DSEE connection failed for %s") % dsee_server logger.debug(color.RED + "DSEE connection failed for " + dsee_server + color.END) sys.exit(15) close() def automount_in_dsee(): """ Check existance of DSEE automount. Need to define one global variable, to use in other functions """ global dsee_automount_info try: client = paramiko.SSHClient() print ("INFO : Check if %s has DSEE automount") % user_name logger.debug(color.CYAN + "Check if " + user_name + " has DSEE automount" + color.END) client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname=dsee_server, username=i_am, password=my_dsee_passwd) stdin, stdout, stderr = client.exec_command('/usr/bin/ldaplist -l auto_home %s | grep automountInformation' % user_name, get_pty=True) # exit status of remote command # print stdout.channel.recv_exit_status() if stdout.channel.recv_exit_status() == 0: lines = stdout.readlines() for line in lines: dsee_automount_info=line.replace("automountInformation:", "").strip() print ("OK : DSEE automount for %s is %s") % (user_name, dsee_automount_info) logger.debug(color.GREEN + "DSEE automount for " + user_name + " is " + dsee_automount_info + color.END) create_ipa_automount_dsee_home() else: print("INFO : User %s does not have DSEE automount.") % user_name logger.debug(color.CYAN + "User " + user_name + " does not have DSEE automount." + color.END) ipa_home_exist() except paramiko.AuthenticationException: print ("ERROR : DSEE Auth failed") logger.debug(color.RED + "DSEE Auth failed" + color.END) sys.exit(20) except: print ("ERROR : DSEE connection failed for %s") % dsee_server logger.debug(color.RED + "DSEE connection failed for + " + dsee_server + color.END) sys.exit(25) close() def create_ipa_home(): """ Create CA-LDAP or IPA home, via ca-server4 """ try: client = paramiko.SSHClient() client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname="ca-server4.us.domain.com", username=i_am, password=my_ipa_passwd) stdin, stdout, stderr = client.exec_command('sudo mkdir /homefolders/%s ; sudo chmod 700 /homefolders/%s ; sudo chown %s:%s /homefolders/%s' % (user_name, user_name, user_name, user_name, user_name)) print("OK : IPA home is created for user %s ") % user_name logger.debug(color.GREEN + "IPA home is created for user " + user_name + color.END) # ipa home created, now check if automount exist ipa_automount_exist() except paramiko.AuthenticationException: print ("ERROR : ca-server4 Auth failed") logger.debug(color.RED + "ca-server4 Auth failed" + color.END) sys.exit(40) except: print ("ERROR : ca-server4 connection failed") logger.debug(color.RED + "ca-server4 connection failed" + color.END) sys.exit(45) close() def create_ipa_automount_ipa_home(): """ Create IPA automount with IPA home """ try: subprocess.call(['ipa automountkey-add default auto.home --key %s --info "-rw,intr,soft,wsize=32768,rsize=32768,vers=3,tcp ca-sunstor1.us.domain.com:/export/home/%s"' % (user_name, user_name)], shell=True) print ("OK : CA-LDAP automount created for %s") % user_name logger.debug(color.GREEN + "CA-LDAP automount created for user " + user_name + color.END) except: logger.debug(color.RED + "Can't create CA-LDAP automount for " + user_name + color.END) print(color.RED + "\nERROR : Can't create CA-LDAP automount for %s.\n" + color.END) % user_name def create_ipa_automount_dsee_home(): """ Create IPA automount with DSEE home """ try: print (dsee_automount_info) subprocess.call(['ipa automountkey-add default auto.home --key %s --info "-rw,intr,soft,vers=3 %s"' %(user_name, dsee_automount_info)], shell=True) print ("OK : CA-LDAP automount created for %s with DSEE home") % user_name logger.debug(color.GREEN + "CA-LDAP automount created for user " + user_name + " with DSEE home" + color.END) except: logger.debug(color.RED + "Can't create CA-LDAP automount for " + user_name + " with DSEE home" + color.END) print(color.RED + "\nERROR : Can't create CA-LDAP automount for %s with DSEE home.\n" + color.END) % user_name def ipa_automount_exist(): """ Check if IPA automount exists """ # this is to capture command's output #result = subprocess.check_output(['ipa', 'automountkey-show', 'default', 'auto.home', '--key', '%s' % user_name]) #print result result = subprocess.call(['ipa', 'automountkey-show', 'default', 'auto.home', '--key', '%s' % user_name]) #return True if result == 0 else False if result == 0 : print (color.RED + "INFO : CA-LDAP automount for %s already exists!" % user_name + color.END) logger.debug(color.RED + "CA-LDAP automount for user " + user_name + " already exists!" + color.END) else: print ("INFO : Calling function to create CA-LDAP automount for %s") % user_name logger.debug(color.CYAN + "Calling function to create CA-LDAP automount for " + user_name + color.END) create_ipa_automount_ipa_home() def ipa_home_exist(): """ Check if ca-ldap home exist """ try: client = paramiko.SSHClient() print("INFO : Doing connection check to ca-server4") logger.debug(color.CYAN + "Doing connection check to ca-server4" + color.END) client.set_missing_host_key_policy(paramiko.AutoAddPolicy()) client.connect(hostname="ca-server4.us.domain.com", username=i_am, password=my_ipa_passwd) print ("INFO : Connection to ca-server4: OK") logger.debug(color.CYAN + "Connection to ca-server4: OK" + color.END) print ("INFO : Check if CA-LDAP home already exists for %s") % user_name logger.debug(color.CYAN + "Check if CA-LDAP home already exists for user " + user_name + color.END) stdin, stdout, stderr = client.exec_command('sudo find /homefolders -maxdepth 1 -type d -name "%s"' % user_name) if stdout.channel.recv_exit_status() == 0: lines = stdout.readlines() if len(lines) == 0: # exit=0 but list is empty, so no home exist print ("OK : Creating CA-LDAP home, via ca-server4, for user %s") % user_name logger.debug(color.GREEN + "Creating CA-LDAP home, via ca-server4, for user " + user_name + color.END) create_ipa_home() else: for line in lines: print line.strip() ipa_home=line.strip() print ("INFO : User %s already has CA-LDAP home %s") % (user_name, ipa_home) logger.debug(color.GREEN + "User " + user_name + " already has CA-LDAP home " + ipa_home + color.END) ipa_automount_exist() else: logger.debug(color.RED + " Cannot determine is IPA home exist " + color.END) sys.exit("ERROR : Cannot determine if IPA home exist" ) except paramiko.AuthenticationException: print ("ERROR : ca-server4 Auth failed") logger.debug(color.RED + "ca-server4 Auth failed" + color.END) sys.exit(30) except: print ("ERROR : Seems no change has been done via ca-server4") logger.debug(color.RED + "Seems no change has been done via ca-server4" + color.END) sys.exit(35) close() # ----- MAIN -------------- if __name__ == '__main__': # print 'This program is being run by itself' user_in_dsee() #else: # print 'I am being imported from another module' #logger.debug("\n") sys.exit(0) |