109 lines
4.5 KiB
Python
109 lines
4.5 KiB
Python
from os import environ
|
||
import hvac
|
||
import hvac.exceptions
|
||
from oracledb import Error, create_pool, init_oracle_client
|
||
|
||
init_oracle_client()
|
||
|
||
class SimpleDB:
|
||
def __init__(self):
|
||
self._create_db_pool_from_vault()
|
||
self.pool
|
||
init_oracle_client()
|
||
|
||
def _handle_vault_exception(self, e: Exception, message: str):
|
||
"""
|
||
Обработка исключений Vault с возвратом понятного сообщения.
|
||
"""
|
||
print(message)
|
||
if isinstance(e, hvac.exceptions.InvalidPath):
|
||
raise hvac.exceptions.InvalidPath("Database configuration not found in Vault")
|
||
elif isinstance(e, hvac.exceptions.Forbidden):
|
||
raise hvac.exceptions.Forbidden("Permission denied to access Vault secrets")
|
||
elif isinstance(e, hvac.exceptions.Unauthorized):
|
||
raise hvac.exceptions.Unauthorized("Invalid Vault token")
|
||
elif isinstance(e, hvac.exceptions.VaultError):
|
||
raise hvac.exceptions.VaultError(f"Vault secret retrieval failed: {e}")
|
||
elif isinstance(e, hvac.exceptions.InvalidRequest):
|
||
raise hvac.exceptions.InvalidRequest(f"Missing database parameter in Vault response: {e}")
|
||
elif isinstance(e, hvac.exceptions.VaultDown):
|
||
raise hvac.exceptions.VaultDown(f"Database server not available: {e}")
|
||
else:
|
||
raise Exception (f'Unexpected error reading from Vault: {e}')
|
||
|
||
#TODO: rename +
|
||
def _create_db_pool_from_vault(self):
|
||
"""
|
||
Подключение к Vault и получение параметров для подключеник к БД
|
||
"""
|
||
try:
|
||
# Подключение к Vault
|
||
client = hvac.Client(
|
||
url='https://vlt.dataekb.ru:8222',
|
||
token=environ.get('VAULT_TOKEN'),
|
||
)
|
||
except Exception as e:
|
||
self._handle_vault_exception(e, "Ошибка при создание покдлючения c Vault")
|
||
try:
|
||
# Чтение секретов из Vault
|
||
secret_read_response = client.secrets.kv.v2.read_secret_version(
|
||
path='oracledb',
|
||
mount_point='kv'
|
||
)
|
||
except Exception as e:
|
||
self._handle_vault_exception(e, "Ошибка чтение скретов из Vault")
|
||
|
||
try:
|
||
# Создаем пул соединений
|
||
self.pool = create_pool(
|
||
user=secret_read_response['data']['data']['user'],
|
||
password=secret_read_response['data']['data']['password'],
|
||
dsn=secret_read_response['data']['data']['cs'],
|
||
min=2,
|
||
max=10,
|
||
increment=1
|
||
)
|
||
except Exception as e:
|
||
self._handle_vault_exception(e, "Ошибка при создание пула для подключение к Oracle")
|
||
|
||
def data_transfer_in_database(self, list_data: list):
|
||
"""
|
||
Передача данных в базу
|
||
Процедура на вставку:
|
||
|
||
P_RK_GOVERNMENT_REPORTS_INSERS
|
||
(
|
||
ID IN NUMBER,
|
||
ORGAN IN VARCHAR2,
|
||
NAMES IN VARCHAR2,
|
||
DATE_FROM in date,
|
||
DATE_TO in date,
|
||
VERS IN VARCHAR2)
|
||
"""
|
||
if not self.pool:
|
||
raise ValueError(self.pool, "Database pool not initialized")
|
||
if not list_data:
|
||
raise ValueError(list_data, "No data to process")
|
||
|
||
try:
|
||
with self.pool.acquire() as connection:
|
||
with connection.cursor() as cursor:
|
||
for list_argument_bd in list_data:
|
||
id, organ, names, date_from, date_to, ver = list_argument_bd
|
||
parametrs_list = [id, organ, names, date_to, date_from, ver]
|
||
print("Отправляемых аргрументов: ", *parametrs_list)
|
||
print("Типов данных: ", list(map(type, parametrs_list)))
|
||
cursor.callproc('P_RK_GOVERNMENT_REPORTS_INSERS', [
|
||
id,
|
||
organ,
|
||
names,
|
||
date_from,
|
||
date_to,
|
||
ver,
|
||
])
|
||
|
||
except Error as e:
|
||
raise Error(f'Ошибка при отправке данных в БД: {e}')
|
||
except Exception as e:
|
||
raise Error(f'Неожиданная ошибка: {e}')
|