diff --git a/pym/cl_datavars.py b/pym/cl_datavars.py index 68f2f80..8298bd0 100644 --- a/pym/cl_datavars.py +++ b/pym/cl_datavars.py @@ -30,7 +30,7 @@ tr.setLanguage(sys.modules[__name__]) class var: '''Объект "Переменная окружения"''' # название сервиса которому принадлежит переменная - #(Global, Builder, Client, Server итд) + #(Main, Builder, Client итд) service = None # значение переменной value = "" @@ -66,10 +66,10 @@ class var: #обновились то нужно) upd = False for depVarName in self.dependValues.keys(): - value = self.parentObj.__getattribute__(depVarName).Get() + value = getattr(self.parentObj, depVarName).Get() if self.dependValues[depVarName] != value: self.dependValues[depVarName] =\ - self.parentObj.__getattribute__(depVarName).value + getattr(self.parentObj, depVarName).value upd = True break return upd @@ -108,7 +108,7 @@ class DataVars(object): # Импортируемые модули - (раздел: модуль переменных, модуль заполнения #переменных) - __modlist={'Global':('cl_vars','cl_fill')} + __modlist={'Main':('cl_vars','cl_fill')} def __init__(self): # Для нахождения зависимостей переменных self.__levelNumber = 0 @@ -116,14 +116,14 @@ class DataVars(object): # Для хранения импортированных модулей и объектов #[(cекция,импортированный модуль переменных, объект заполнения),] self._importList = [] - self.importData("Global") + self.importData("Main") # Переменные которые нужно записать self.varsNeedWritten = [] def importData(self, section, modlist=[]): """Импортирует модули с переменными и модули с функциями заполнения - section секция раздела (Global, Server, Client итд) + section секция раздела (Main, Client итд) создает необходимые структуры данных """ if modlist: @@ -190,7 +190,7 @@ class DataVars(object): for section, moduleVar, fillobj in self._importList: if fillobj and hasattr(fillobj, nameMethod): flagFindMetod = True - method = fillobj.__getattribute__(nameMethod) + method = getattr(fillobj, nameMethod) break if flagFindMetod: return (dataVar,method) @@ -215,8 +215,8 @@ class DataVars(object): self.__LevelsVar.append((self.__levelNumber, nameVar)) self.__levelNumber += 1 #nameMethod = "get_" + nameVar - if self.__dict__.has_key(nameVar): - ret = self.__getattribute__(nameVar).Get() + if hasattr(self, nameVar): + ret = getattr(self, nameVar).Get() elif self.__findVarData(nameVar): dictVar, methodFill =self.__findVarData(nameVar) varobj = var(self) @@ -224,17 +224,17 @@ class DataVars(object): self.__setAttributesVar(varobj, nameVar, dictVar) if methodFill: varobj.Fill = methodFill - self.__setattr__(nameVar, varobj) - ret = self.__getattribute__(nameVar).Get() + setattr(self, nameVar, varobj) + ret = getattr(self, nameVar).Get() self.__levelNumber -= 1 if self.__levelNumber == 0 and\ - self.__getattribute__(nameVar).fillStart and\ + getattr(self, nameVar).fillStart and\ len(self.__LevelsVar)>1: links = self.__getLinks(self.__LevelsVar) for name in links.keys(): for nameLink in links[name].keys(): - val = self.__getattribute__(nameLink).Get() - self.__getattribute__(name).dependValues[nameLink] = val + val = getattr(self, nameLink).Get() + getattr(self, name).dependValues[nameLink] = val if self.__levelNumber == 0: self.__LevelsVar = [] return ret @@ -244,22 +244,22 @@ class DataVars(object): def __Set(self, nameVar, value, force=False): - nameMethod = "get_" +nameVar - if not self.__dict__.has_key(nameVar) and self.__findVarData(nameVar): + nameMethod = "get_" + nameVar + if not hasattr(self, nameVar) and self.__findVarData(nameVar): dictVar, methodFill =self.__findVarData(nameVar) varobj = var(self) # Устанавливаем аттрибуты self.__setAttributesVar(varobj, nameVar, dictVar) if methodFill: varobj.Fill = methodFill - self.__setattr__(nameVar, varobj) - if self.__dict__.has_key(nameVar): + setattr(self, nameVar, varobj) + if hasattr(self, nameVar): if not force and "r" in getattr(self, nameVar).mode: print _("Attempt to rewrite a variable for reading") +": %s"\ %nameVar return False - self.__getattribute__(nameVar).fillStart = False - return self.__getattribute__(nameVar).Set(value) + getattr(self, nameVar).fillStart = False + return getattr(self, nameVar).Set(value) def Set(self, nameVar, value, force=False): return self.__Set(nameVar, value, force) @@ -338,11 +338,8 @@ storage of variables templates")%location vname - имя переменной """ - if self.__dict__.has_key(vname): - if self.__dict__[vname].service == 'Global': - return 'calculate' - else: - return self.__dict__[vname].service.lower() + if hasattr(self, vname): + return getattr(self, vname).service.lower() def __writeVarValue(self, vname, val, location, header): '''Записать значение в calculate.ini @@ -351,7 +348,7 @@ storage of variables templates")%location vname имя переменной val значение переменной location расположение ini файла ('default', 'local', 'remote') - header раздел ini файла ('client', 'server', 'calculate') + header раздел ini файла ('client', 'server', 'main') Возвращаемые значение: True запись успешна @@ -415,7 +412,7 @@ storage of variables templates")%location val значение переменной force "принудительный режим" location расположение ini файла ('default', 'local', 'remote') - header раздел ini файла ('client', 'server', 'calculate') + header раздел ini файла ('client', 'server', 'main') ''' if self.__Set(vname, val, force)!= False: if not val.strip(): @@ -441,12 +438,37 @@ storage of variables templates")%location """активные секции в ini файле""" act_section = [] for service,t,t in self._importList: - if service == "Global": - act_section.append('calculate') - else: - act_section.append(service.lower()) + act_section.append(service.lower()) return act_section + def GetIniVar(self, section_dot_nameVar): + """Получить значение переменной из конфигурационного файла + + section_dot_nameVar - "имя_секции.имя_переменной_профиля" + """ + calculate_ini_files = self.Get('cl_env_path') + section, spl, name_var = section_dot_nameVar.rpartition(".") + if section and name_var: + pass + elif name_var: + section = "main" + else: + print _("error Datavars.GetIniVar: empty section") + return False + # Значение переменной в env файлах + valueVar = "" + for name_calculate_ini in calculate_ini_files: + # проверить сущестование ini файла + if os.path.exists(name_calculate_ini): + # получить объект настроенный на ini + config = iniParser(name_calculate_ini) + # получаем значение переменной из секции + value = config.getVar(section, name_var) + if value is False: + return False + valueVar = value + return valueVar.encode("UTF-8") + def flIniFile(self): '''Заместить значение переменных значениями из ини файлов diff --git a/pym/cl_fill.py b/pym/cl_fill.py index ea79a8a..75809f6 100644 --- a/pym/cl_fill.py +++ b/pym/cl_fill.py @@ -21,6 +21,8 @@ import filecmp import pwd, grp import cl_datavars import cl_overriding +from cl_ldap import ldapUser + class clLocale: lang = { @@ -209,7 +211,12 @@ def getdirlist(s_path): dir_list=fdir.common_dirs return dir_list -class fillVars(object, cl_datavars.glob_attr): +class fillVars(cl_datavars.glob_attr): + + # Объект данных из LDAP + _ldapUserObject = False + # Данные о пользователе из LDAP + _ldapUserData = {} def get_cl_env_path(self): '''Пути к env файлам''' @@ -443,15 +450,15 @@ class fillVars(object, cl_datavars.glob_attr): slpRootDev = rootDev.split("/dev/") if len(slpRootDev) == 2: rDev = slpRootDev[1] - devLines = self._runos("ls -la /dev/disk/by-id/", None, - {"LANG":"C"}) - if not devLines: - return "" - if type(devLines) == types.ListType: - for line in devLines: - if rDev in line and "usb-" in line: + devLines = os.listdir("/dev/disk/by-id") + for name in devLines: + path = os.path.join("/dev/disk/by-id", name) + if os.path.islink(path): + if rDev in os.readlink(path) and "usb-" in name: rootType = "usb-hdd" break + if not devLines: + return "" if rootType == "ram": rootType = "hdd" return rootType @@ -641,7 +648,7 @@ class fillVars(object, cl_datavars.glob_attr): except: return "" return groupName - + def get_ur_fullname(self): """Полное имя пользователя""" userName = self.Get('ur_login') @@ -651,4 +658,40 @@ class fillVars(object, cl_datavars.glob_attr): fullName = pwd.getpwnam(userName).pw_gecos except: return "" - return fullName \ No newline at end of file + return fullName + + def getLdapUserObject(self): + """Объект данных из LDAP""" + if not self._ldapUserObject: + self._ldapUserObject = ldapUser() + return self._ldapUserObject + + def getUserInfo(self): + """Получение информации о пользователе из LDAP""" + userName = self.Get('ur_login') + if userName: + if userName in self._ldapUserData: + return self._ldapUserData[userName] + else: + ldapObj = self.getLdapUserObject() + userInfo = ldapObj.getUserLdapInfo(userName) + if userInfo: + self._ldapUserData[userName] = userInfo + return userInfo + return {} + + def get_ur_jid(self): + """Jabber id пользователя""" + userInfo = self.getUserInfo() + userJID = "" + if userInfo: + userJID = userInfo["jid"] + return userJID + + def get_ur_mail(self): + """Почтовый адрес пользователя""" + userInfo = self.getUserInfo() + userMail = "" + if userInfo: + userMail = userInfo["mail"] + return userMail \ No newline at end of file diff --git a/pym/cl_ldap.py b/pym/cl_ldap.py index bea5fae..b8512a6 100644 --- a/pym/cl_ldap.py +++ b/pym/cl_ldap.py @@ -56,3 +56,116 @@ class ldapFun(_error): return False return result_set +class ldapUser(_error): + """Получение данных для пользователя из LDAP""" + # Данные из /etc/ldap.conf + _dictData = {} + # Объект LDAP + ldapObj = False + # Подключение к LDAP + conLdap = False + + def getServerDataUser(self, bindData=False): + """Получение данных из /etc/ldap.conf""" + fileName = "/etc/ldap.conf" + getStrList = lambda x: reduce(lambda x,y: [x,y.upper()],([x]*2)) + data = [("host",'host'), + ("usersDN",'nss_base_passwd'), + ("groupsDN",'nss_base_group')] + if bindData: + data += [("bindDn",'binddn'), ("bindPw",'bindpw')] + workData = map(lambda x: (x[0],getStrList(x[1]),len(x[1])), data) + namesData = map(lambda x: x[0], data) + dictData = {} + splList = (" ", "\t") + try: + for line in open(fileName): + for name, keys, lenKey in workData: + if not name in dictData.keys() and\ + filter(lambda x: line.startswith(x), keys) and\ + len(line)>lenKey: + spl = line[lenKey] + if spl in splList: + if not name in dictData: + dictData[name] = [] + if name == "usersDN": + dictData[name].append(line.rpartition(spl)[2].\ + partition('?')[0].strip()) + else: + dictData[name].append(line.rpartition(spl)[2].\ + strip()) + except: + self.setError(_("Can not open %s")%fileName) + return False + if set(dictData.keys()) == set(namesData): + return dictData + else: + return {} + + def getUserLdapInfo(self, userName): + """Выдаем информацию о пользователе из LDAP""" + if not "bindDn" in self._dictData: + # Получаем информацию из /etc/ldap.conf + retData = self.getServerDataUser(bindData=True) + if retData: + self._dictData = retData + else: + return {} + bindDn = self._dictData["bindDn"][0] + bindPw = self._dictData["bindPw"][0] + host = self._dictData["host"][0] + usersDN = self._dictData["usersDN"][0] + groupsDNs = self._dictData["groupsDN"] + # Соединяемся с LDAP + if not self.ldapConnect(bindDn, bindPw, host): + return False + searchUser = self.ldapObj.ldapSearch(usersDN, ldap.SCOPE_ONELEVEL, + "uid=%s" %userName, None) + if not searchUser: + return False + uid = False + gid = False + fullName = "" + mail = "" + jid = "" + group = "" + if 'uidNumber' in searchUser[0][0][1]: + uid = searchUser[0][0][1]['uidNumber'][0] + if 'gidNumber' in searchUser[0][0][1]: + gid = searchUser[0][0][1]['gidNumber'][0] + for groupDN in groupsDNs: + searchGroup = self.ldapObj.ldapSearch(groupDN, + ldap.SCOPE_ONELEVEL, + "gidNumber=%s" %gid, ['cn']) + if searchGroup: + group = searchGroup[0][0][1]['cn'][0] + break + if 'cn' in searchUser[0][0][1]: + fullName = searchUser[0][0][1]['cn'][0] + if 'mail' in searchUser[0][0][1]: + mail = searchUser[0][0][1]['mail'][0] + if 'registeredAddress' in searchUser[0][0][1]: + jid = searchUser[0][0][1]['registeredAddress'][0] + if 'homeDirectory' in searchUser[0][0][1]: + home = searchUser[0][0][1]['homeDirectory'][0] + if uid and gid: + return {"uid":uid, + "gid":gid, + "fullName":fullName, + "mail":mail, + "jid":jid, + "home":home, + "group":group} + else: + return {} + + def ldapConnect(self, bindDn, bindPw, host): + """Подключение к LDAP""" + if not self.ldapObj: + ldapObj = ldapFun(bindDn, bindPw, host) + if ldapObj.getError(): + return False + # Устанавливаем у объекта соединение и объект LDAP функций + self.ldapObj = ldapObj + self.conLdap = ldapObj.conLdap + return True \ No newline at end of file diff --git a/pym/cl_template.py b/pym/cl_template.py index 464e8d2..cb703c7 100644 --- a/pym/cl_template.py +++ b/pym/cl_template.py @@ -2246,6 +2246,7 @@ class templateFunction(_error, _shareTemplate, _shareTermsFunction): # Текст функции шаблона functText = "" + def __init__(self, objVar): # Если не определен словарь функций шаблона #print "dict", templateFunction.__dict__.items() @@ -2285,6 +2286,8 @@ class templateFunction(_error, _shareTemplate, _shareTermsFunction): self.fileConfigIni = os.path.join(self.pathConfigIni,"ini.env") # Словарь времен модификации env файлов self.timeConfigsIni = {} + # Словарь хранения переменых полученных функцией env() из env файлов + self.valuesVarEnv = {} def equalTerm(self, term, localVars): """Метод для вычисления выражения""" @@ -2835,6 +2838,32 @@ class templateFunction(_error, _shareTemplate, _shareTermsFunction): textTemplateTmp[resS.end():] return textTemplateTmp + def funcEnv(self, funArgv, resS, localVars, textTemplateTmp): + """Функция шаблона env(), выдает значение переменной из env файлов + """ + terms = funArgv.replace(" ","").split(",") + if len(terms) != 1: + self.printErrTemplate() + cl_overriding.exit(1) + nameVar = terms[0] + replace = '' + if nameVar in self.valuesVarEnv: + replace = self.valuesVarEnv[nameVar] + else: + # Получаем значение из env файлов + value = self.objVar.GetIniVar(nameVar) + if value is False: + self.printErrTemplate() + errMsg = self.getError() + if errMsg: + print errMsg + cl_overriding.exit(1) + self.valuesVarEnv[nameVar] = value + replace = value + textTemplateTmp = textTemplateTmp[:resS.start()] + replace +\ + textTemplateTmp[resS.end():] + return textTemplateTmp + def printErrTemplate(self): """Печать ошибки при обработке функций шаблона""" print _("error in template %s")%self.nameTemplate diff --git a/pym/cl_vars.py b/pym/cl_vars.py index fedc3a8..0809d6f 100644 --- a/pym/cl_vars.py +++ b/pym/cl_vars.py @@ -20,6 +20,8 @@ # type - тип переменной состоит из двух элементов(что это и для чего # это) # value - значение переменной +# official - флаг того, что данная переменная служебная и не отображается +# при печати списка значений переменных class Data: @@ -110,17 +112,28 @@ class Data: os_linux_ver = {} #Логин пользователя - ur_login = {'mode':"w"} + ur_login = {'mode':"r"} #Название группы пользователя - ur_group = {'mode':"w"} + ur_group = {'mode':"r", 'official':True} #Полное имя пользователя - ur_fullname = {'mode':"w"} - + ur_fullname = {'mode':"r", 'official':True} + # Действие программы # profile - генерация профиля пользователя # install / uninstall - установка и удаление программы # domain / undomain - ввод и вывод из домена - cl_pass_action = {'mode':"w"} + + # Jabber ID пользователя + ur_jid = {'mode':"r", 'official':True} + + # Почтовый адрес пользователя + ur_mail = {'mode':"r", 'official':True} + + # Переменные устанавливаемые сервером для клиента + # ip или имя домена (под управлением calculate-server) + cl_remote_host = {'mode':'w', 'official':True} + +