Внесены незначительные изменения
parent
7d23c372c4
commit
8184dee91d
|
@ -219,7 +219,7 @@ if __name__ == "__main__":
|
|||
MS_AD_ADRESS = 'ldap://cp-vm-dc01.energo.ru'
|
||||
SEARCH_FREE_MS = "dc=energo,dc=ru"
|
||||
MS_USER = 'energo\\administrator'
|
||||
PASSWORD = ""
|
||||
PASSWORD = "P@sww0rd"
|
||||
PATH_SCV = "List_groups.csv"
|
||||
|
||||
SEARCH_FREE_SAMBA = "dc=lenenergo,dc=ru"
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
#!/usr/bin/python3
|
||||
from ldap3 import Server, Connection, ALL, NTLM, SUBTREE, SAFE_SYNC, BASE
|
||||
from samba.samdb import SamDB
|
||||
from samba.auth import system_session
|
||||
|
@ -7,9 +8,11 @@ import samba.param
|
|||
import logging
|
||||
from pprint import pprint
|
||||
import json
|
||||
import subprocess
|
||||
import csv
|
||||
|
||||
import subprocess
|
||||
import sched
|
||||
import time
|
||||
import datetime
|
||||
|
||||
|
||||
|
||||
|
@ -25,11 +28,8 @@ class AD_provaider():
|
|||
logging.warning("status connect AD.........error")
|
||||
|
||||
|
||||
def search_ms_ad(self,search_filter ,filter:list = ["*"], dn = None)->dict:
|
||||
def search_ms_ad(self, search_filter ,filter:list = ["*"])->dict:
|
||||
logging.info("search >>>>>>>>>>>>>> AD")
|
||||
if dn is not None:
|
||||
self.__connect.search(dn, search_filter, SUBTREE, attributes=filter)
|
||||
else:
|
||||
self.__connect.search(self.__ad_serch_tree, search_filter, SUBTREE, attributes=filter)
|
||||
response = self.__connect.response_to_json()
|
||||
response = json.loads(response)
|
||||
|
@ -37,8 +37,6 @@ class AD_provaider():
|
|||
return json.loads(response)
|
||||
|
||||
|
||||
|
||||
|
||||
class Samba_provaider():
|
||||
def __init__(self, path) -> None:
|
||||
self.__lp = samba.param.LoadParm()
|
||||
|
@ -66,81 +64,214 @@ class Samba_provaider():
|
|||
return False
|
||||
|
||||
|
||||
class Manager:
|
||||
def __init__(self, samba_ad:Samba_provaider, ad:AD_provaider) -> None:
|
||||
self._smb = samba_ad
|
||||
class Manager():
|
||||
def __init__(self, samba_prov:Samba_provaider, ad:AD_provaider) -> None:
|
||||
self._smb = samba_prov
|
||||
self.__ad = ad
|
||||
|
||||
|
||||
def creat_branch_ou(self, data_path_list:list):
|
||||
for item in data_path_list:
|
||||
i = item.split(",")
|
||||
date = [m.split("=") for m in i]
|
||||
date_list = list(reversed(date))
|
||||
self.__seach_path_ou_and_add(date_list)
|
||||
def find_user_by_groups(self, name:str, ou:str, base_ou:str)->dict:
|
||||
str_base_ou = self.__get_str_base_ou(base_ou)
|
||||
return self.__ad.search_ms_ad(f"(memberOf=CN={name},{ou},{str_base_ou})")
|
||||
|
||||
|
||||
def __seach_path_ou_and_add(self, ou_list:list):
|
||||
path = ""
|
||||
try:
|
||||
for i in ou_list:
|
||||
if str(i[0]).replace('"', '') == "OU":
|
||||
if len(path) == 0:
|
||||
path = path + i[0].replace('"', '') +"="+i[1]
|
||||
str_add = "add ou -> {} <- status ....ok".format(path)
|
||||
print("***************************************")
|
||||
logging.info(str_add)
|
||||
print("***************************************")
|
||||
self._smb.add_ou(path)
|
||||
def find_group(self, name, ou, base):
|
||||
base_ou = self.__get_str_base_ou(base)
|
||||
return self.__ad.search_ms_ad(f"(&(objectCategory=group)(name={name})(distinguishedName=CN={name},{ou},{base_ou}))")
|
||||
|
||||
|
||||
def __get_str_base_ou(self, base:str)->str:
|
||||
ou_list = []
|
||||
for i in base.split(","):
|
||||
dn = i.split("=")[0]
|
||||
v = i.split("=")[1]
|
||||
out = "{}={}".format( dn.upper(), v)
|
||||
ou_list.append(out)
|
||||
return ",".join(ou_list)
|
||||
|
||||
|
||||
def open_file_list_groups(self, path:str)->dict:
|
||||
list_grups = []
|
||||
with open(path, encoding="utf-8") as sv:
|
||||
render = csv.DictReader(sv)
|
||||
for i in render:
|
||||
list_grups.append(i)
|
||||
return list_grups
|
||||
|
||||
|
||||
def find_smb_groups(self, name:str, ou:str, base:str):
|
||||
group = self._smb.search_samba_ad(f"(&(objectCategory=group)(name={name})(distinguishedName=CN={name},{ou},{self.__get_str_base_ou(base)}))")
|
||||
for i in group:
|
||||
return dict(i)
|
||||
|
||||
|
||||
def create_group_for_samba(self, name:str, ou:str, data_group:dict, base:str )->bool:
|
||||
cmd = self._smb.add_group(name, ou)
|
||||
if cmd:
|
||||
self.__create_attrs(data_group, ou, base)
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def __create_attrs(self, data_group:dict, ou, base_ou:str)->int:
|
||||
logging.info("-> add attr <-")
|
||||
attr_list = []
|
||||
base_ou = self.__get_str_base_ou(base_ou)
|
||||
l = []
|
||||
for i in data_group.get("entries")[0].get("dn").split(","):
|
||||
if i.split("=")[0] != "DC":
|
||||
l.append(i)
|
||||
l.append(base_ou)
|
||||
dn = ",".join(l)
|
||||
attr_list.append("dn: {}".format(dn))
|
||||
attr_list.append("changetype: modify")
|
||||
data = data_group.get("entries")[0].get("attributes")
|
||||
if data.get("description"):
|
||||
attr_list.append("add:description")
|
||||
attr_list.append("description: {}".format(",".join(data.get("description"))))
|
||||
if data.get("mail"):
|
||||
attr_list.append("add:mail")
|
||||
attr_list.append("mail: {}".format(data.get("mail")))
|
||||
if data.get("info"):
|
||||
attr_list.append("add:info")
|
||||
attr_list.append("info: {}".format(data.get("info")))
|
||||
if data.get("groupType"):
|
||||
attr_list.append("replace:groupType")
|
||||
attr_list.append("groupType: {}".format(data.get("groupType")))
|
||||
cmd = ["ldbmodify", "-H", "/var/lib/samba/private/sam.ldb", "/tmp/group.ldif"]
|
||||
with open("/tmp/group.ldif", "w") as file:
|
||||
file.write("\n".join(attr_list))
|
||||
out = subprocess.call(cmd,restore_signals=True, shell=False)
|
||||
return out
|
||||
|
||||
|
||||
def find_user_by_groups_samba(self, name, ou, base_ou):
|
||||
str_base_ou = self.__get_str_base_ou(base_ou)
|
||||
return self._smb.search_samba_ad(f"(memberOf=CN={name},{ou},{str_base_ou})")
|
||||
|
||||
|
||||
def compare_entry_by_group(self, ms:list, name_group:str, samba_data, base):
|
||||
if len(samba_data) == 0:
|
||||
for items in ms:
|
||||
if "person" in items.get("attributes").get("objectClass"):
|
||||
if self.__is_user_samba(items.get("attributes").get("sAMAccountName")):
|
||||
self.__add_entry_for_group_samba(name_group, items.get("attributes").get("sAMAccountName"))
|
||||
if "group" in items.get("attributes").get("objectClass"):
|
||||
add_name = self.__is_group_samba(items.get("dn"), base)
|
||||
if add_name is not None:
|
||||
self.__add_entry_for_group_samba(name_group, add_name)
|
||||
else:
|
||||
path = i[0].replace('"', '') +"="+i[1]+","+ path
|
||||
str_add = "add ou -> {} <- status ....ok".format(path)
|
||||
print("***************************************")
|
||||
logging.info(str_add)
|
||||
print("***************************************")
|
||||
self._smb.add_ou(path)
|
||||
except Exception as ex:
|
||||
logging.warning(ex)
|
||||
smb_list_name = []
|
||||
ms_list_name = []
|
||||
for i in samba_data:
|
||||
smb_list_name.append(str(dict(i).get("sAMAccountName")))
|
||||
for ms_i in ms:
|
||||
if "person" in ms_i.get("attributes").get("objectClass"):
|
||||
if ms_i.get("attributes").get("sAMAccountName") not in smb_list_name and self.__is_user_samba(ms_i.get("attributes").get("sAMAccountName")):
|
||||
self.__add_entry_for_group_samba(name_group, ms_i.get("attributes").get("sAMAccountName"))
|
||||
logging.info("-> add in group <-")
|
||||
if "group" in ms_i.get("attributes").get("objectClass"):
|
||||
if ms_i.get("attributes").get("sAMAccountName") not in smb_list_name:
|
||||
add_name = self.__is_group_samba(ms_i.get("dn"), base)
|
||||
if add_name is not None:
|
||||
self.__add_entry_for_group_samba(name_group, add_name)
|
||||
logging.info("-> add in group <-")
|
||||
ms_list_name.append(ms_i.get("attributes").get("sAMAccountName"))
|
||||
self.__delet_entry(ms_list_name, smb_list_name, name_group)
|
||||
|
||||
|
||||
def open_csv_file(self, path)->list:
|
||||
out_list = []
|
||||
try:
|
||||
with open(path, encoding="utf-8") as f:
|
||||
reader = csv.reader(f, delimiter="\t" )
|
||||
next(reader)
|
||||
next(reader)
|
||||
for row in reader:
|
||||
out_list.append(row[0].split(";"))
|
||||
return out_list
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
print("при открытии файла произошла ошибка необходимо проверить кодировку файла, а также путь до файла")
|
||||
def __delet_entry(self, buf_ms:list, samba_buf:list, name_group:str):
|
||||
for i in samba_buf:
|
||||
if i not in buf_ms:
|
||||
cmd = ["samba-tool", "group", "removemembers", name_group, i]
|
||||
out = subprocess.call(cmd, restore_signals=True)
|
||||
|
||||
|
||||
def __is_user_samba(self, name)->bool:
|
||||
user = self._smb.search_samba_ad(f"(&(objectCategory=person)(objectClass=user)(sAMAccountName={name}))")
|
||||
if len(user) !=0:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def __is_group_samba(self, ou, base):
|
||||
path = []
|
||||
for i in ou.split(","):
|
||||
if i.split("=")[0] != "DC":
|
||||
path.append(i)
|
||||
p = ",".join(path)
|
||||
group = self._smb.search_samba_ad(f"(&(objectCategory=group)(distinguishedName={p},{self.__get_str_base_ou(base)}))")
|
||||
for i in group:
|
||||
if dict(i).get("sAMAccountName"): return str(dict(i).get("sAMAccountName"))
|
||||
return None
|
||||
|
||||
|
||||
def __add_entry_for_group_samba(self, name_group, name_user)->int:
|
||||
cmd = ["samba-tool", "group", "addmembers", name_group, name_user]
|
||||
out = subprocess.call(cmd,restore_signals=True)
|
||||
if out == 0:
|
||||
logging.info("Added members to group {} account {}".format(name_group, name_user))
|
||||
return out
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
|
||||
MS_AD_ADRESS = 'ldap://cp-vm-dc01.energo.ru'
|
||||
SEARCH_FREE_MS = "dc=energo,dc=ru"
|
||||
MS_USER = 'energo\\administrator'
|
||||
PASSWORD = ""
|
||||
PATH_CSV = "MigrBatch1.csv"
|
||||
PASSWORD = "P@sww0rd"
|
||||
PATH_SCV = "List_groups.csv"
|
||||
|
||||
SEARCH_FREE_SAMBA = "dc=lenenergo,dc=ru"
|
||||
TIME_RUN = "13:43"
|
||||
|
||||
logging.basicConfig(level=logging.DEBUG, format="%(asctime)s - %(levelname)s - %(message)s")
|
||||
|
||||
def run_script():
|
||||
logging.info("> Run script <")
|
||||
ad = AD_provaider(MS_AD_ADRESS, SEARCH_FREE_MS, MS_USER, PASSWORD)
|
||||
smb = Samba_provaider(SEARCH_FREE_SAMBA)
|
||||
manager = Manager(smb, ad)
|
||||
date_file = manager.open_csv_file(PATH_CSV)
|
||||
if date_file is not None:
|
||||
ou_add_list = [ i[5] for i in date_file]
|
||||
logging.info("run create ou")
|
||||
manager.creat_branch_ou(ou_add_list)# Создаст структуру OU
|
||||
logging.info("> END <")
|
||||
try:
|
||||
flag_out = True
|
||||
count = 0
|
||||
while flag_out:
|
||||
data = manager.open_file_list_groups(PATH_SCV)
|
||||
for items in data:
|
||||
group_data_ms = manager.find_group(items.get("SamAccountName"), items.get("OU"), SEARCH_FREE_MS)
|
||||
samba_groups = manager.find_smb_groups(items.get("SamAccountName"), items.get("OU"),SEARCH_FREE_SAMBA)
|
||||
if samba_groups is None:
|
||||
logging.info("-> Create group <-")
|
||||
manager.create_group_for_samba(items.get("SamAccountName"), items.get("OU"), group_data_ms, SEARCH_FREE_SAMBA)
|
||||
else:
|
||||
ms_group = manager.find_user_by_groups(items.get("SamAccountName"), items.get("OU"), SEARCH_FREE_MS)
|
||||
samba_group = manager.find_user_by_groups_samba(items.get("SamAccountName"), items.get("OU"), SEARCH_FREE_SAMBA)
|
||||
manager.compare_entry_by_group(ms_group.get("entries"), items.get("SamAccountName"), samba_group, SEARCH_FREE_SAMBA)
|
||||
logging.info("> End script <-")
|
||||
time.sleep(2)
|
||||
count += 1
|
||||
if count > 1: break
|
||||
except KeyboardInterrupt as kb:
|
||||
print("ctr+c")
|
||||
except Exception as ex:
|
||||
logging.error(ex)
|
||||
|
||||
|
||||
def time_run(hour:int, minuts:int):
|
||||
if isinstance(hour, int) and isinstance(minuts, int) is False:
|
||||
raise "Type error hour and minute is not int !!!!!"
|
||||
try:
|
||||
logging.info(f" -> The launch will be every day in {hour}:{minuts} <-")
|
||||
while True:
|
||||
time.sleep(1)
|
||||
z = time.localtime()
|
||||
if z.tm_hour == hour and z.tm_min == minuts and z.tm_sec == 0:
|
||||
logging.info(f"-> Run time {hour}:{minuts}")
|
||||
run_script()
|
||||
logging.info(f" -> The launch will be every day in {hour}:{minuts} <-")
|
||||
except KeyboardInterrupt:
|
||||
logging.warning("ctr+c")
|
||||
exit()
|
||||
|
||||
|
||||
time_data = TIME_RUN.split(":")
|
||||
time_run(int(time_data[0]), int(time_data[1]))
|
||||
|
|
|
@ -226,7 +226,7 @@ if __name__ == "__main__":
|
|||
MS_AD_ADRESS = 'ldap://cp-vm-dc01.energo.ru'
|
||||
SEARCH_FREE_MS = "dc=energo,dc=ru"
|
||||
MS_USER = 'energo\\administrator'
|
||||
PASSWORD = ""
|
||||
PASSWORD = "P@sww0rd"
|
||||
PATH_CSV = "MigrBatch1.csv"
|
||||
|
||||
SEARCH_FREE_SAMBA = "dc=lenenergo,dc=ru"
|
||||
|
|
Loading…
Reference in New Issue