суббота, 11 июня 2011 г.

Прячем пароль при вызове внешних утилит.

Всем привет.

Идея этой заметки появилась после вот такой беседы:
...мне нужно внутри пакета выполнить sql файл. Через OS command можно, но получается, что явно пароль указывается. Вроде как не хорошо. Может ещё вариант есть?
   ...я могу написать sqlplus user/pass@Database @file.sql
но хочется логин пароль и имя базы не прописывать явно

Поэтому я решил и сам подумать и вам рассказать о том, какие возможности предоставляет ODI для конфигурирования работы внешних утилит. Я рассмотрю только аспект работы с именем пользователя и его паролем. Когда это может быть нужно? Например, при загрузке данных в область стейджа, данные могут загружаться из файла через специальные утилиты СУБД которые осуществляют так называемый bulk load, т.е. быструю загрузку практически без каких либо проверок или преобразований в данных.

Итак, какие есть способы спрятать пароль при вызове внешних утилит?

Таблица с метаданными.

Специально создаем в БД некую таблицу, с простой структурой имя параметра - значение параметра. Сохраняем в этой таблице пароль, а доступ к таблице даем только тому пользователю, под которым работает ОДИ. Далее этот пароль читается в переменную, а затем указывается в шаблоне построения текста команды.

Выглядит потом в тексте процедуры или модуля знаний этот кусочек примерно так:

cmd_txt = 'sqlplus @ETL.DB_User_Name/@ETL.DB_User_Pass' + '@' + '@ETL.DB_Name'


Конечно, перед вызовом такого кода данные переменные необходимо обновить в пакете, чтобы они получили правильные значения.

Используем метаданные ODI.

Я имею ввиду использование метода подстановки odiRef.getInfo().
Этот метод часто используется в модулях знаний, так что, я думаю, он не будет для вас совсем новым. Итак, я взял из документа Руководство разработчика модулей знаний все возможные значения единственного параметра этого метода и попробовал его выполнить в простой процедуре.


Вот результаты, я оставил только не пустые значения:

/* DEST_CATALOG results is: db_test*/
/* DEST_SCHEMA results is: dbo*/
/* DEST_WORK_CATALOG results is: tempdb*/
/* DEST_WORK_SCHEMA results is: dbo*/
/* SRC_ENCODED_PASS results is: <@=snpRef.getInfo("SRC_ENCODED_PASS") @>*/
/* DEST_CON_NAME results is: SQL*/
/* DEST_DSERV_NAME results is: SENCHUK-ODI*/
/* DEST_CONNECT_TYPE results is: D*/
/* DEST_IND_JNDI results is: 0*/
/* DEST_JAVA_DRIVER results is: com.microsoft.sqlserver.jdbc.SQLServerDriver*/
/* DEST_JAVA_URL results is: jdbc:sqlserver://localhost:1433; selectMethod=cursor; Integratedsecurity=false*/
/* DEST_USER_NAME results is: odi_dev*/
/* DEST_ENCODED_PASS results is: <@=snpRef.getInfo("DEST_ENCODED_PASS") @>*/
/* DEST_FETCH_ARRAY results is: 30*/
/* DEST_BATCH_UPDATE results is: 30*/
/* DEST_REM_OBJ_PATTERN results is: %DSERVER.%CATALOG.%SCHEMA.%OBJECT*/
/* DEST_LOC_OBJ_PATTERN results is: %CATALOG.%SCHEMA.%OBJECT*/
/* SUBSCRIBER_TABLE results is: SNP_SUBSCRIBERS*/
/* CDC_SET_TABLE results is: tempdb.dbo.SNP_CDC_SET*/
/* CDC_TABLE_TABLE results is: tempdb.dbo.SNP_CDC_SET_TABLE*/
/* CDC_SUBS_TABLE results is: tempdb.dbo.SNP_CDC_SUBS*/
/* CDC_OBJECTS_TABLE results is: tempdb.dbo.SNP_CDC_OBJECTS*/
/* DEST_DEF_CATALOG results is: db_snpm*/
/* DEST_DEF_SCHEMA results is: dbo*/
/* DEST_DEFW_CATALOG results is: tempdb*/
/* DEST_DEFW_SCHEMA results is: dbo*/
/* DEST_LSCHEMA_NAME results is: TARGET*/


Как видно, для всех параметров, кроме двух паролей, метод getInfo вернул реальные значения соответствующие целевой БД. Вместо значений пароля подставлены вызовы функций в обрамлении конструкций <@ и @>

Для того, чтобы проверить что происходит с паролем, попробуем сохранить результат в файл.
Код проверки:

#Подготовим строку для скрипта с логином
cmd_txt = 'SRC_ENCODED_PASS is: <%=odiRef.getInfo("SRC_ENCODED_PASS")%>'

f = open('c:\\temp\\utl.script', 'w')
f.write(cmd_txt)
f.close()


результат присутствует в файле:


Все хорошо, но вот только наши утилиты должны использовать незашифрованный пароль при соединениях с СУБД. Не может быть, чтобы нельзя было получить просто пароль. И, хотя документация не говорит ничего об использовании DEST_PASS как параметра метода getInfo, но так же было и для метода getSession с его недокументированными параметрами.

Поиски, как это часто бывает, привели к одному из стандартных модулей знаний. Первый шаг LKM File to MSSQL (BULK) имеет нужные нам параметры:


Так что используя этот подход получим нужные нам значения в виде текстового файла:


Хочу также обратить ваше внимание на то, что разница между модулем знаний и процедурой, в разрезе применения функции getInfo, есть. И разница заключается в том, что при использовании в процедуре функция будет возвращать имя пользователя или пароль для выбранной в этом шаге процедуры схемы:


А если мы попытаемся выводить пароль не источника, а целевого сервера данных, мы получим пустое значение, так как используется технология Jython и схема для этой технологии не может быть задана.

Но вот при использовании в модуле знаний целевая схема это всегда схема, в которой находится целевая таблица. Так что имя пользователя и пароль для сервера данных к которому относится целевая таблица вернется командой getInfo правильно. По крайней мере такой вывод напрашивается если посмотреть стандартный модуль знаний, в котором нашлось использование параметра для незашифрованного пароля:


Возможно, правильный ответ кроется в понимании того, откуда берется эта информация. Как пишут, данные берутся из таблицы SNP_CONNECT мастер репозитория. Надо будет еще подумать на тему того, как организовывается физическое взаимодействие в плане установления соединения при выполнении модулей знаний, и в почему различаются результаты для процедуры и модуля.

Использование настраиваемых полей (Using Flexfields).
Настраиваемые поля, как пишет нам документация, это поля, задаваемые пользователем, которые расширяют перечень существующих параметров объектов ODI.

Теоретически, можно использовать эти поля для хранения такой информации как имя пользователя и пароль, а потом доставать их при помощи тех же методов подстановки.

Если будет время, попытаюсь отдельно разобраться с этой возможностью и опубликовать результаты.

Комментариев нет:

Отправить комментарий