1# Copyright (C) 2018-2019 Garmin Ltd. 2# 3# SPDX-License-Identifier: GPL-2.0-only 4# 5 6import asyncio 7from contextlib import closing 8import itertools 9import json 10from collections import namedtuple 11from urllib.parse import urlparse 12from bb.asyncrpc.client import parse_address, ADDR_TYPE_UNIX, ADDR_TYPE_WS 13 14User = namedtuple("User", ("username", "permissions")) 15 16def create_server( 17 addr, 18 dbname, 19 *, 20 sync=True, 21 upstream=None, 22 read_only=False, 23 db_username=None, 24 db_password=None, 25 anon_perms=None, 26 admin_username=None, 27 admin_password=None, 28): 29 def sqlite_engine(): 30 from .sqlite import DatabaseEngine 31 32 return DatabaseEngine(dbname, sync) 33 34 def sqlalchemy_engine(): 35 from .sqlalchemy import DatabaseEngine 36 37 return DatabaseEngine(dbname, db_username, db_password) 38 39 from . import server 40 41 if "://" in dbname: 42 db_engine = sqlalchemy_engine() 43 else: 44 db_engine = sqlite_engine() 45 46 if anon_perms is None: 47 anon_perms = server.DEFAULT_ANON_PERMS 48 49 s = server.Server( 50 db_engine, 51 upstream=upstream, 52 read_only=read_only, 53 anon_perms=anon_perms, 54 admin_username=admin_username, 55 admin_password=admin_password, 56 ) 57 58 (typ, a) = parse_address(addr) 59 if typ == ADDR_TYPE_UNIX: 60 s.start_unix_server(*a) 61 elif typ == ADDR_TYPE_WS: 62 url = urlparse(a[0]) 63 s.start_websocket_server(url.hostname, url.port) 64 else: 65 s.start_tcp_server(*a) 66 67 return s 68 69 70def create_client(addr, username=None, password=None): 71 from . import client 72 73 c = client.Client(username, password) 74 75 try: 76 (typ, a) = parse_address(addr) 77 if typ == ADDR_TYPE_UNIX: 78 c.connect_unix(*a) 79 elif typ == ADDR_TYPE_WS: 80 c.connect_websocket(*a) 81 else: 82 c.connect_tcp(*a) 83 return c 84 except Exception as e: 85 c.close() 86 raise e 87 88 89async def create_async_client(addr, username=None, password=None): 90 from . import client 91 92 c = client.AsyncClient(username, password) 93 94 try: 95 (typ, a) = parse_address(addr) 96 if typ == ADDR_TYPE_UNIX: 97 await c.connect_unix(*a) 98 elif typ == ADDR_TYPE_WS: 99 await c.connect_websocket(*a) 100 else: 101 await c.connect_tcp(*a) 102 103 return c 104 except Exception as e: 105 await c.close() 106 raise e 107