async def index( http_server: str, sort_qs: SortQS = Depends(SortQS), search: str = Query(None), pagination: PaginationQS = Depends(PaginationQS), zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("zone:list")), includes: List[str] = Query(None), ): includes = only(includes, ["http_records"], values=True) # Support ability to either submit http_server.name or http_server.id as http_server_id zone_http_server_id_label = zone_repo.label("http_server_id") try: http_server = int(http_server) label = zone_http_server_id_label except ValueError: label = zone_repo.label("http_server.name") pg, items = (zone_repo.search(search).loads(includes).filter_or( label == http_server, zone_http_server_id_label.is_(None)).sort( sort_qs).paginate(pagination).includes(includes).data()) return ZonesResponse(pagination=pg, zones=items)
async def activate( zone_id: int, zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("zone:update")), ): zone = zone_repo.get_or_fail(zone_id).update({"is_active": True}).data() return ZoneResponse(zone=zone)
async def update( zone_id: int, form: ZoneCreateForm, zone_repo: ZoneRepo = Depends(ZoneRepo()), dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()), http_server_repo: DnsServerRepo = Depends(HttpServerRepo()), token: TokenPayload = Depends(ScopedTo("zone:update")), includes: List[str] = Query(None), ): data = only(dict(form), ["ip", "domain"]) if "domain" in data: data["domain"] = data["domain"].lower() existing_domain = zone_repo.first(domain=data["domain"]).results() if existing_domain and existing_domain.id != zone_id: abort_for_input("domain", "A Zone with that domain already exists") zone_repo.clear() if form.dns_server_id is not None: if form.dns_server_id is 0: data["dns_server_id"] = None elif dns_server_repo.exists(id=form.dns_server_id): dns_server = dns_server_repo.results() data["dns_server"] = dns_server if form.http_server_id is not None: if form.http_server_id is 0: data["http_server_id"] = None elif http_server_repo.exists(id=form.http_server_id): http_server = http_server_repo.results() data["http_server"] = http_server zone = (zone_repo.loads(includes).get_or_fail(zone_id).update( data).includes(includes).data()) return ZoneResponse(zone=zone)
async def store( form: ZoneCreateForm, zone_repo: ZoneRepo = Depends(ZoneRepo()), dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()), http_server_repo: HttpServerRepo = Depends(HttpServerRepo()), token: TokenPayload = Depends(ScopedTo("zone:create")), ): data = only(dict(form), ["ip", "domain"]) data["domain"] = data["domain"].lower() # Make sure domain is unique if zone_repo.exists(domain=data["domain"]): abort_for_input("domain", "A Zone with that domain already exists") zone_repo.clear() if form.dns_server_id: if dns_server_repo.exists(id=form.dns_server_id): data["dns_server_id"] = dns_server_repo.results().id if form.http_server_id: if http_server_repo.exists(id=form.http_server_id): data["http_server_id"] = http_server_repo.results().id zone = zone_repo.create(data).data() return ZoneResponse(zone=zone)
async def store( form: DnsRequestCreateForm, dns_request_repo: DnsRequestRepo = Depends(DnsRequestRepo()), zone_repo: ZoneRepo = Depends(ZoneRepo()), dns_server_repo: DnsServerRepo = Depends(DnsServerRepo()), token: str = Depends(ScopedTo("dns-request:create")), ): dns_server_id = ( dns_server_repo.first_or_fail(name=form.dns_server_name.lower()).results().id ) zone = ( zone_repo.filter(literal(form.name.lower()).contains(zone_repo.label("domain"))) .first() .results() ) zone_id = zone.id if zone else None data = only( dict(form), ["name", "source_address", "source_port", "type", "protocol", "raw_request"], ) data["name"] = data["name"].lower() data["type"] = data["type"].upper() data["dns_server_id"] = dns_server_id data["zone_id"] = zone_id logger.info("[email protected] - Creating DNS Request") dns_request = dns_request_repo.create(data).data() return DnsRequestResponse(dns_request=dns_request)
async def destroy( zone_id: int, zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("zone:destroy")), ): messages = [{"text": "Deactivation Succesful", "type": "success"}] if not zone_repo.exists(zone_id): return BaseResponse(messages=messages) zone_repo.deactivate(zone_id) return BaseResponse(messages=messages)
async def show( zone_id: int, zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("zone:show")), includes: List[str] = Query(None), ): includes = only(includes, ["dns_server", "dns_records", "http_server"], values=True) zone = zone_repo.loads(includes).get_or_fail(zone_id).includes( includes).data() return ZoneResponse(zone=zone)
async def dig( zone_id: int, zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("dns-record:list")), ): zone = zone_repo.includes("dns_records").first_or_fail( id=zone_id).results() print(zone) print(zone.dns_records) # TODO: fix method rrs = RecordParser.from_zone(zone).get_rrs() dig = DNSRecord(rr=rrs).toZone() return DnsRecordsDigResponse(dig=dig)
async def index( sort_qs: SortQS = Depends(SortQS), pagination: PaginationQS = Depends(PaginationQS), zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("zone:list")), includes: List[str] = Query(None), ): # TODO: bypasses a bunch of scopes, find a way to restrict access via scopes includes = only(includes, ["dns_server", "dns_records", "http_server"], values=True) pg, items = (zone_repo.loads(includes).strict().sort(sort_qs).paginate( pagination).includes(includes).data()) return ZonesResponse(pagination=pg, zones=items)
async def store( zone_id: int, form: DnsRecordForZoneCreateForm, dns_record_repo: DnsRecordRepo = Depends(DnsRecordRepo()), zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("dns-record:create")), ): zone_repo.exists(id=zone_id, or_fail=True) data = only(dict(form), ["record", "sort"]) data["zone_id"] = zone_id item = dns_record_repo.create(data).data() return DnsRecordResponse(dns_record=item)
async def index( zone_id: int, sort_qs: SortQS = Depends(SortQS), pagination: PaginationQS = Depends(PaginationQS), dns_record_repo: DnsRecordRepo = Depends(DnsRecordRepo()), zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("dns-record:list")), includes: List[str] = Query(None), ): zone_repo.exists(id=zone_id, or_fail=True) includes = only(includes, ["zone"], values=True) pg, items = (dns_record_repo.loads("zone").sort(sort_qs).filter_by( zone_id=zone_id).paginate(pagination).includes(includes).data()) return DnsRecordsResponse(pagination=pg, dns_records=items)
async def update( zone_id: int, dns_record_id: int, form: DnsRecordForZoneCreateForm, dns_record_repo: DnsRecordRepo = Depends(DnsRecordRepo()), zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("dns-record:create")), ): # TODO: use abort_for_input instead of or_fail zone_repo.exists(id=zone_id, or_fail=True) data = only(form, ["record", "sort"]) item = dns_record_repo.first_or_fail(id=dns_record_id).update(data).data() return DnsRecordResponse(dns_record=item)
async def show( zone_id: int, dns_record_id: int, dns_record_repo: DnsRecordRepo = Depends(DnsRecordRepo()), zone_repo: ZoneRepo = Depends(ZoneRepo()), token: TokenPayload = Depends(ScopedTo("dns-record:show")), includes: List[str] = Query(None), ): zone_repo.exists(id=zone_id, or_fail=True) includes = only(includes, ["zone"], values=True) item = (dns_record_repo.loads("zone").filter_by( zone_id=zone_id).first_or_fail( id=dns_record_id).includes(includes).data()) return DnsRecordResponse(dns_record=item)
def seed_from_env(self): from boucanpy.core.user import UserRepo from boucanpy.core.zone import ZoneRepo from boucanpy.core.dns_server import DnsServerRepo from boucanpy.db.session import _scoped_session session = _scoped_session for i in range(9): i = str(i) user_data = {} email_key = f"SEED_USER_{i}_EMAIL" email = environ.get(email_key, None) password_key = f"SEED_USER_{i}_PASSWORD" password = environ.get(password_key, None) superuser_key = f"SEED_USER_{i}_SUPERUSER" is_superuser = int(environ.get(superuser_key, 0)) if email and password: email = email.lower() hashed_password = hash_password(password) repo = UserRepo(db=session) if not repo.exists(email=email): logger.info( f"seed_from_env@api_server.py - seeding user {email}") user = factory("UserFactory", session=session).create( email=email, hashed_password=hashed_password, is_superuser=is_superuser, ) else: logger.info( f"seed_from_env@api_server.py - Seeded user {email} already exists" ) for i in range(9): i = str(i) name_key = f"SEED_DNS_SERVER_{i}_NAME" name = environ.get(name_key, None) if name: repo = DnsServerRepo(db=session) if not repo.exists(name=name): logger.info( f"seed_from_env@api_server.py - Seeding domain {name}") domain = factory("DnsServerFactory", session=session).create(name=name) for i in range(9): i = str(i) ip_key = f"SEED_ZONE_{i}_IP" domain_key = f"SEED_ZONE_{i}_DOMAIN" dns_server_name_key = f"SEED_ZONE_{i}_DNS_SERVER_NAME" ip = environ.get(ip_key, None) domain = environ.get(domain_key, None) if domain: domain = domain.lower() dns_server_name = environ.get(dns_server_name_key, None) if ip and domain: if dns_server_name: dns_server_repo = DnsServerRepo(db=session) if dns_server_repo.exists(name=dns_server_name): dns_server = dns_server_repo.results() else: logger.info( f"seed_from_env@api_server.py - Seeding dns server as zone dependency: {name}" ) dns_server = factory( "DnsServerFactory", session=session).create(name=dns_server_name) factory("ZoneFactory", session=session).create(ip=ip, domain=domain, dns_server=dns_server) else: repo = ZoneRepo(db=session) if not repo.exists(ip=ip, domain=domain): logger.info( f"seed_from_env@api_server.py - Seeding zone without dns server: {ip}, {domain}" ) factory("GlobalZoneFactory", session=session).create(ip=ip, domain=domain)