Доброго всем времени суток. Сегодня я расскажу вам о проблеме с которой, в силу своей работы, я столкнулся. Задача была крайне проста и, как казалось на первый взгляд, не должна занять много времени. Впрочем она и не заняла бы, если бы я не решил использовать для ее реализации сторонний софт. Но обо всем по порядку:
1. Задача была выгрузить из LDAPS значения соответствующие определенному запросу и внести их в базу mysql (База OTRS), возможно эту задачу, некий гуру OTRS мог бы решить и не прибегая к какому бы то ни было стороннему софту, но увы и ах, я не из их числа.
2. Для реализации данной задачи меня посетила мысль – «А не замастрячить ли это все на Python», но так как мне было лень писать, я решил найти альтернативу и альтернативой стал софт под название lsc. Софтинка в принципе не плохая, если бы не одно но. И но это — BASE64 в которой хранятся все кириличные поля. В общем и целом миграция то у меня мигрировала, но кирилица отображалась в виде «???» (вопросиков т. е.), долгие мытарства по преобразованию кодировок, ковырянию конфигов и кодов, короче — фиг.
3. Промаявшись с этой програмулиной (LSC) и потеряв множество времени и сил. Я вернулся к идее описать эту задачу на python.
А теперь мудрый совет: «Если вы можете реализовать что-то своими силами, без применения внешнего ПО — делайте».
Соответственно на этом предыстория заканчивается и начинается статья, суть которой в описании кода python, который я накидал за 2 часа и который прекрасно работает, смею сразу заметить, что код не претендует ни на премию самого быстрого не на премию самого красивого, но если кому пригодиться, то прошу.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 | import ldap import datetime import mysql.connector #Создаем подключение к mysql (OTRS) try: mysql_connect = mysql.connector.connect(user="otrs", password="otrs", host="10.10.10.107", database="otrs") mysql_cursor = mysql_connect.cursor() except mysql.connector.Error, e: print e #Создаем и открываем на дополнение файл для логов try: file = open('./ldap-to-mysql.log', 'a') except: print "Can`t create file, or open it" #Создаем подключение к LDAPS try: connect = ldap.initialize("ldaps://10.10.10.101") #Ограничение на таймаут connect.set_option(ldap.OPT_NETWORK_TIMEOUT, 10.0) #Запросить и принять сертификат ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_ALLOW) #Логинимся connect.simple_bind_s("cn=admin,dc=test,dc=kz","pass123") except ldap.LDAPError, e: file.write(e) #Задаем baseDN (в этом каталоге будет производиться поиск) dn="ou=customers,dc=scb,dc=kz" #Задаем возможность поиска в поддиректориях search = ldap.SCOPE_SUBTREE retrieveAttributes = None #Ну и сам поиск (cid не равен нулю и status равен ACTIVE) searchName="(&(cid=*)(status=ACTIVE))" try: result = connect.search(dn,search,searchName,retrieveAttributes) result_set = [] while 1: result_type, result_data = connect.result(result,0) if (result_data == []): break else: if result_type == ldap.RES_SEARCH_ENTRY: result_set.append(result_data) for i in range(len(result_set)): try: name = result_set[i][0][1]["o"][0] customer_id = result_set[i][0][1]["cid"][0] street = result_set[i][0][1]["registeredAddress"][0] country = "Kazakhstan" file.write("Name: %s\nCID: %s\nStreet: %s\nCountry: %s\n" %\ (name, customer_id, street, country)) # Вот тут мой косяк date можно было взять иначе date = (datetime.datetime.now().replace(second=0, microsecond=0)) try: # Сам инсерт в mysql query = "insert into customer_company (customer_id, name, street, country, create_time, change_time) values ('%s', '%s', '%s', '%s', '%s', '%s')" % (customer_id, name, street, country, date , date) mysql_cursor.execute(query) except mysql.connector.Error as err: if "Duplicate entry" in err.msg: file.write(err.msg) continue else: file.write(err.msg) except: file.write("Something was wrong!") except ldap.LDAPError, e: file.write(e) # Находим записи которые перестали быть ACTIVE и удаляем их searchName="(&(cid=*)(status=INACTIVE))" try: result = connect.search(dn,search,searchName,retrieveAttributes) result_set = [] while 1: result_type, result_data = connect.result(result,0) if (result_data == []): break else: if result_type == ldap.RES_SEARCH_ENTRY: result_set.append(result_data) for i in range(len(result_set)): try: customer_id = result_set[i][0][1]["cid"][0] try: query = "delete from customer_company where customer_id = '%s'" % (customer_id) mysql_cursor.execute(query) except mysql.connector.Error as err: if "Duplicate entry" in err.msg: file.write(err.msg) continue else: file.write(err.msg) except: file.write("Something was wrong!") except ldap.LDAPError, e: file.write(e) # Закрываем все коннекты. mysql_cursor.close() mysql_connect.close() connect.unbind_s() file.close() |
Для реализации данного скрипта вам потребуется установить python-ldap и mysql-connector-python
1 2 | pip install mysql-connector-python pip install python-ldap |
Во и все. Данныем мигрированны. Для выполнения данного скрипта с некоторой периодикой используйте crontab.
Надеюсь инфа будет вам полезна. Всяческие предложения по рефракторингу будут лично мне крайне интересны. Удачи.
Добавить комментарий