blob: 04648b33fbd916c137d5f2112a29bd374d04ce5b [file] [log] [blame]
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License. See accompanying LICENSE file.
#
import argparse
import os,sys
import pycurl
import getpass
import logging
from StringIO import StringIO as BytesIO
def log(msg,type):
if type == 'info':
logging.info(" %s",msg)
if type == 'debug':
logging.debug(" %s",msg)
if type == 'warning':
logging.warning(" %s",msg)
if type == 'exception':
logging.exception(" %s",msg)
if type == 'error':
logging.error(" %s",msg)
def isPairedSwitch(value):
isSwitch=False
switch_arr =["-groups", "-users","-admin","-url","-sslCertPath"]
if value in switch_arr:
isSwitch=True
return isSwitch
def printUsage():
log("[I] Note : This utility can be used to delete users or groups, To delete groups refer below given first command and to delete users refer second command.","info")
log("[I] Usage(Group delete): deleteUserGroupUtil.py -groups <group file path> -admin <ranger admin user> -url <rangerhosturl> [-force] [-sslCertPath <cert path>] [-debug]","info")
log("[I] Usage(User delete): deleteUserGroupUtil.py -users <user file path> -admin <ranger admin user> -url <rangerhosturl> [-force] [-sslCertPath <cert path>] [-debug]","info")
log("[I] -groups: Delete groups specified in the given file","info")
log("[I] -users: Delete users specified in the given file","info")
log("[I] -admin: Ranger Admin user ID","info")
log("[I] -force: Force delete users/groups, even if they are referenced in policies","info")
log("[I] -url: Ranger Admin URL","info")
log("[I] -sslCertPath: Filepath to ssl certificate to use when Ranger Admin uses HTTPS","info")
log("[I] -debug: Enables debugging","info")
sys.exit(1)
def processRequest(url,usernamepassword,data,method,isHttps,certfile,isDebug):
buffer = BytesIO()
header = BytesIO()
c = pycurl.Curl()
c.setopt(c.URL, url)
c.setopt(pycurl.HTTPHEADER, ['Content-Type: application/json','Accept: application/json'])
c.setopt(pycurl.USERPWD, usernamepassword)
c.setopt(pycurl.VERBOSE, 0)
if isHttps==True:
c.setopt(pycurl.SSL_VERIFYPEER,1)
c.setopt(pycurl.SSL_VERIFYHOST,2)
c.setopt(pycurl.CAINFO, certfile)
c.setopt(c.WRITEFUNCTION ,buffer.write)
c.setopt(c.HEADERFUNCTION,header.write)
# setting proper method and parameters
if method == 'get' :
c.setopt(pycurl.HTTPGET, 1)
elif method == 'delete' :
c.setopt(pycurl.CUSTOMREQUEST, "DELETE")
c.setopt(c.POSTFIELDS, str(data))
else :
log("[E] Unknown Http Request method found, only get or delete method are allowed!","error")
c.perform()
# getting response
response = buffer.getvalue()
headerResponse = header.getvalue()
response_code=0
response_code=str(c.getinfo(pycurl.RESPONSE_CODE))
response_code=int(response_code)
buffer.close()
header.close()
c.close()
if isDebug ==True or (response_code!=200 and response_code!=204):
print 'Request URL = ' + str(url)
print 'Response = ' + str(headerResponse)
return response_code
def validateArgs(argv):
if(len(argv)<7):
log("[E] insufficient number of arguments. Found " + len(argv) + "; expected at least 7","error")
printUsage()
if not "-users" in argv and not "-groups" in argv:
log("[E] -users or -groups switch was missing!","error")
printUsage()
if not "-admin" in argv:
log("[E] -admin switch was missing!","error")
printUsage()
if not "-url" in argv:
log("[E] -url switch was missing!","error")
printUsage()
if "-url" in argv:
try:
host=str(argv[argv.index("-url")+1])
host=host.strip()
if host =="" or host is None or isPairedSwitch(host):
log("[E] invalid Ranger Admin host URL","error")
printUsage()
if host.lower().startswith("https"):
if not "-sslCertPath" in argv:
log("[E] -sslCertPath switch was missing!","error")
printUsage()
except IndexError:
log("[E] missing/invalid Ranger Admin host URL","error")
printUsage()
def main(argv):
FORMAT = '%(asctime)-15s %(message)s'
logging.basicConfig(format=FORMAT, level=logging.DEBUG)
inputPath=""
certfile=""
tail=""
password=""
isHttps=False
isUser=False
isGroup=False
isDebug=False
if "-usage" in argv or "-help" in argv:
printUsage()
validateArgs(argv)
for i in range(1, len(argv)) :
if str(argv[i])== "-groups" :
restpath= "/groups/groupName/"
try:
inputPath=str(argv[i+1])
inputPath=inputPath.strip()
if inputPath =="" or not os.path.exists(inputPath) or not os.path.isfile(inputPath) or not os.access(inputPath, os.R_OK) or isPairedSwitch(inputPath):
log("[E] File '"+inputPath+"' does not exist or could not be read","error")
sys.exit(1)
else:
isGroup=True
if os.stat(inputPath).st_size == 0:
log("[E] File '"+inputPath+"' is empty!","error")
sys.exit(1)
except IndexError:
log("[E] missing filename after '-groups' argument","error")
sys.exit(1)
continue
elif str(argv[i])== "-users" :
restpath= "/users/userName/"
try:
inputPath=str(argv[i+1])
inputPath=inputPath.strip()
if inputPath =="" or not os.path.exists(inputPath) or not os.path.isfile(inputPath) or not os.access(inputPath, os.R_OK) or isPairedSwitch(inputPath):
log("[E] File '"+inputPath+"' does not exist or could not be read","error")
sys.exit(1)
else:
isUser=True
if os.stat(inputPath).st_size == 0:
log("[E] File '"+inputPath+"' is empty!","error")
sys.exit(1)
except IndexError:
log("[E] missing filename after '-users' argument","error")
sys.exit(1)
continue
if str(argv[i])=="-admin" :
try:
user=str(argv[i+1])
if user =="" or user is None or isPairedSwitch(user):
log("[E] missing/invalid Ranger Admin login ID for argument '-admin'","error")
sys.exit(1)
continue
except IndexError:
log("[E] missing/invalid Ranger Admin login ID for argument '-admin'","error")
sys.exit(1)
if str(argv[i])=="-url" :
try:
host=str(argv[i+1])
host=host.strip()
if host =="" or host is None or isPairedSwitch(host):
log("[E] invalid Ranger Admin host URL","error")
sys.exit(1)
if host.lower().startswith("https"):
isHttps=True
continue
except IndexError:
log("[E] missing/invalid Ranger Admin host URL","error")
sys.exit(1)
if str(argv[i])=="-force" :
tail="?forceDelete=true"
continue
if str(argv[i])=="-debug" :
isDebug=True
continue
if isHttps == True and str(argv[i])== "-sslCertPath" :
try:
certfile=str(argv[i+1])
certfile=certfile.strip()
if certfile =="" or not os.path.exists(certfile) or not os.path.isfile(certfile) or not os.access(certfile, os.R_OK) or isPairedSwitch(certfile):
log("[E] Certificate File '"+certfile+"' does not exist or could not be read","error")
sys.exit(1)
except IndexError:
log("[E] missing/invalid SSL certificate path for argument '-sslCertPath'","error")
sys.exit(1)
continue
if isUser==True and isGroup==True:
log("[E] -users and -groups both option were provided, only one is allowed.","error")
printUsage()
if password =="" :
password=getpass.getpass("Enter Ranger Admin password : ")
usernamepassword=user+":"+password
url=host+'/service/xusers/secure/users/roles/userName/'+user
response_code=0
try:
response_code=processRequest(url,usernamepassword,None,'get',isHttps,certfile,False)
except pycurl.error, e:
print e
sys.exit(1)
if response_code == 302 or response_code==401 or response_code==403:
log("[E] Authentication Error:Please try with valid credentials!","error")
sys.exit(1)
if response_code != 200:
log("[E] Failed to contact Ranger Admin with given parameters. Please review the parameters","error")
printUsage()
sys.exit(1)
f=open(inputPath,'r')
processedRows=0
for line in f:
line=line.strip()
if line == "" or line is None:
continue
if isUser==True and line==user:
log("[I] Skipping deletion of user : "+line+", Self account deletion is restricted!","info")
continue
url=host+'/service/xusers'+restpath+line+tail
method='delete'
data=None
response_code=processRequest(url,usernamepassword,data,method,isHttps,certfile,isDebug)
if response_code==302 or response_code==401:
if isUser==True:
log("[E] failed while deleting user '" + line + "'. Please verify the parameters","error")
elif isGroup==True:
log("[E] failed while deleting group '" + line + "'. Please verify the parameters","error")
buffer.close()
header.close()
break
elif response_code==204:
if isUser==True:
log("[I] Deleted user : "+line,"info")
elif isGroup==True:
log("[I] Deleted group : "+line,"info")
processedRows=processedRows+1
elif response_code==404:
if isUser==True:
log("[E] failed while deleting user '" + line + "'. Please verify the parameters","error")
elif isGroup==True:
log("[E] failed while deleting group '" + line + "'. Please verify the parameters","error")
elif response_code==400:
if isUser==True:
log("[I] User not found : "+line,"info")
elif isGroup==True:
log("[I] Group not found : "+line,"info")
f.close()
if processedRows==0:
if isUser==True:
log("[I] No valid user found to delete!","info")
elif isGroup==True:
log("[I] No valid group found to delete!","info")
else:
if isUser==True:
log("[I] Number of user deleted : "+str(processedRows),"info")
elif isGroup==True:
log("[I] Number of group deleted : "+str(processedRows),"info")
main(sys.argv)