фикс ссх дб 3
This commit is contained in:
parent
dc677888bb
commit
f6743076b6
2 changed files with 41 additions and 18 deletions
|
|
@ -545,6 +545,32 @@ async def _check_if_slave_multi(
|
||||||
return False, "", ""
|
return False, "", ""
|
||||||
|
|
||||||
|
|
||||||
|
async def _open_tunnel(tunnel_host: str, tunnel_port: int, ssh_options: list, target_host: str, target_port: int):
|
||||||
|
"""Try each ssh_option in order; return open asyncssh connection on first success or raise."""
|
||||||
|
last_exc: Exception = Exception("No SSH options provided")
|
||||||
|
for opt in ssh_options:
|
||||||
|
try:
|
||||||
|
connect_kwargs: dict = dict(
|
||||||
|
host=tunnel_host, port=tunnel_port, username=opt.username,
|
||||||
|
known_hosts=None, connect_timeout=10,
|
||||||
|
)
|
||||||
|
if opt.type == "key":
|
||||||
|
connect_kwargs["client_keys"] = [opt.key_path]
|
||||||
|
connect_kwargs["passphrase"] = None
|
||||||
|
logger.info("[ssh_discovery] Tunnel attempt for %s — key: user=%s key_path=%s", tunnel_host, opt.username, opt.key_path)
|
||||||
|
else:
|
||||||
|
connect_kwargs["password"] = opt.password
|
||||||
|
masked = (opt.password[:1] + "***" + opt.password[-1:]) if len(opt.password) > 2 else "***"
|
||||||
|
logger.info("[ssh_discovery] Tunnel attempt for %s — password: user=%s password=%s", tunnel_host, opt.username, masked)
|
||||||
|
conn = await asyncssh.connect(**connect_kwargs)
|
||||||
|
logger.info("[ssh_discovery] Tunnel auth succeeded for %s with %s(%s)", tunnel_host, opt.type, opt.username)
|
||||||
|
return conn
|
||||||
|
except Exception as exc:
|
||||||
|
last_exc = exc
|
||||||
|
logger.info("[ssh_discovery] Tunnel auth failed for %s with %s(%s): %s", tunnel_host, opt.type, opt.username, exc)
|
||||||
|
raise last_exc
|
||||||
|
|
||||||
|
|
||||||
async def _get_rack_hosts_direct(
|
async def _get_rack_hosts_direct(
|
||||||
host: str,
|
host: str,
|
||||||
port: int,
|
port: int,
|
||||||
|
|
@ -555,19 +581,13 @@ async def _get_rack_hosts_direct(
|
||||||
via_tunnel: bool = False,
|
via_tunnel: bool = False,
|
||||||
tunnel_host: str | None = None,
|
tunnel_host: str | None = None,
|
||||||
tunnel_ssh_port: int = 22,
|
tunnel_ssh_port: int = 22,
|
||||||
tunnel_ssh_user: str | None = None,
|
ssh_options: list | None = None,
|
||||||
tunnel_ssh_password: str | None = None,
|
|
||||||
) -> list[tuple[str, str, str, str | None]]:
|
) -> list[tuple[str, str, str, str | None]]:
|
||||||
"""Return list of (external_id, host_ip, rack_name, rack_type) from the racks table."""
|
"""Return list of (external_id, host_ip, rack_name, rack_type) from the racks table."""
|
||||||
if via_tunnel and tunnel_host and tunnel_ssh_user and tunnel_ssh_password:
|
if via_tunnel and tunnel_host and ssh_options:
|
||||||
async with asyncssh.connect(
|
conn = await _open_tunnel(tunnel_host, tunnel_ssh_port, ssh_options, host, port)
|
||||||
tunnel_host,
|
async with conn:
|
||||||
port=tunnel_ssh_port,
|
listener = await conn.forward_local_port("127.0.0.1", 0, host, port)
|
||||||
username=tunnel_ssh_user,
|
|
||||||
password=tunnel_ssh_password,
|
|
||||||
known_hosts=None,
|
|
||||||
) as tunnel:
|
|
||||||
listener = await tunnel.forward_local_port("127.0.0.1", 0, host, port)
|
|
||||||
local_port = listener.get_port()
|
local_port = listener.get_port()
|
||||||
dsn = (
|
dsn = (
|
||||||
f"host=127.0.0.1 port={local_port} dbname={dbname} "
|
f"host=127.0.0.1 port={local_port} dbname={dbname} "
|
||||||
|
|
@ -729,6 +749,7 @@ async def discover_via_ssh(
|
||||||
source="auto_ssh",
|
source="auto_ssh",
|
||||||
location="server_room",
|
location="server_room",
|
||||||
status="unknown",
|
status="unknown",
|
||||||
|
device_meta={"is_caps_db": True},
|
||||||
)
|
)
|
||||||
db.add(db_device_obj)
|
db.add(db_device_obj)
|
||||||
await db.flush()
|
await db.flush()
|
||||||
|
|
@ -764,8 +785,7 @@ async def discover_via_ssh(
|
||||||
via_tunnel=use_tunnel,
|
via_tunnel=use_tunnel,
|
||||||
tunnel_host=obj.server_ip,
|
tunnel_host=obj.server_ip,
|
||||||
tunnel_ssh_port=ssh_port,
|
tunnel_ssh_port=ssh_port,
|
||||||
tunnel_ssh_user=obj.ssh_user,
|
ssh_options=ssh_options,
|
||||||
tunnel_ssh_password=ssh_password,
|
|
||||||
)
|
)
|
||||||
# Connection succeeded — mark DB device online
|
# Connection succeeded — mark DB device online
|
||||||
if db_device_obj is not None:
|
if db_device_obj is not None:
|
||||||
|
|
|
||||||
|
|
@ -219,11 +219,14 @@ export function DeviceEditModal({ open, device, objId, onClose, onSaved }: Props
|
||||||
/>
|
/>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
|
||||||
|
{device?.device_meta?.is_caps_db && (
|
||||||
|
<>
|
||||||
<Divider orientation="left" plain>Подключение к БД</Divider>
|
<Divider orientation="left" plain>Подключение к БД</Divider>
|
||||||
|
|
||||||
<Form.Item name="db_via_tunnel" valuePropName="checked">
|
<Form.Item name="db_via_tunnel" valuePropName="checked">
|
||||||
<Checkbox>Подключаться к БД через SSH-туннель (через main_server объекта)</Checkbox>
|
<Checkbox>Подключаться к БД через SSH-туннель (через main_server объекта)</Checkbox>
|
||||||
</Form.Item>
|
</Form.Item>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
</Form>
|
</Form>
|
||||||
</Modal>
|
</Modal>
|
||||||
)
|
)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue