From 9edd1db13576b8dbfeb0fe1e09eb1da613f743a5 Mon Sep 17 00:00:00 2001 From: Ilya Verbitskiy Date: Fri, 14 Jun 2024 22:52:01 +0200 Subject: [PATCH] make virtuerl top-level project --- .dockerignore | 4 - .flake8 | 3 - .gitignore | 32 +- Dockerfile | 42 - README.md | 78 +- {virtuerl/config => config}/sys.config | 0 examples/docker-compose.yml | 21 - {virtuerl/hack => hack}/repack | 0 minivirt/__init__.py | 0 minivirt/controller.py | 193 --- minivirt/controller_pb2.py | 33 - minivirt/controller_pb2_grpc.py | 1260 ----------------- minivirt/daemon.py | 894 ------------ minivirt/daemon_pb2.py | 32 - minivirt/daemon_pb2_grpc.py | 862 ----------- minivirt/dns_controller.py | 104 -- minivirt/dns_pb2.py | 37 - minivirt/dns_pb2_grpc.py | 166 --- minivirt/domain_pb2.py | 60 - minivirt/domain_pb2_grpc.py | 331 ----- minivirt/host.py | 126 -- minivirt/host_pb2.py | 43 - minivirt/host_pb2_grpc.py | 232 --- minivirt/image.py | 91 -- minivirt/main.py | 297 ---- minivirt/migrations.py | 116 -- minivirt/models.py | 132 -- minivirt/port_forwarding.py | 301 ---- minivirt/port_forwarding_pb2.py | 37 - minivirt/port_forwarding_pb2_grpc.py | 166 --- minivirt/route.py | 133 -- minivirt/route_pb2.py | 49 - minivirt/route_pb2_grpc.py | 331 ----- minivirt/utils.py | 39 - minivirt/version.py | 1 - minivirt/volume_pb2.py | 49 - minivirt/volume_pb2_grpc.py | 331 ----- protos/minivirt/controller.proto | 60 - protos/minivirt/daemon.proto | 44 - protos/minivirt/dns.proto | 34 - protos/minivirt/domain.proto | 113 -- protos/minivirt/host.proto | 46 - protos/minivirt/port_forwarding.proto | 38 - protos/minivirt/route.proto | 67 - protos/minivirt/volume.proto | 73 - pyproject.toml | 18 - virtuerl/rebar.config => rebar.config | 0 virtuerl/rebar.lock => rebar.lock | 0 requirements-dev.txt | 5 - requirements.txt | 14 - setup.py | 31 - snap/hooks/configure | 19 - snap/hooks/install | 3 - snap/local/bin/bird-wrapper | 3 - snap/local/bin/birdc-wrapper | 3 - snap/local/bin/restvirt-controller | 3 - snap/local/bin/restvirt-daemon | 3 - snap/local/bin/restvirt-deregister | 3 - snap/local/bin/restvirt-register | 3 - snap/local/bin/unbound-wrapper | 3 - snap/local/etc/bird/minivirt.conf | 229 --- snap/local/etc/unbound/minivirt.conf | 20 - snap/snapcraft.yaml | 83 -- {virtuerl/src => src}/virtuerl.app.src | 0 {virtuerl/src => src}/virtuerl_api.erl | 0 {virtuerl/src => src}/virtuerl_app.erl | 0 {virtuerl/src => src}/virtuerl_ghac.erl | 0 {virtuerl/src => src}/virtuerl_img.erl | 0 {virtuerl/src => src}/virtuerl_ipam.erl | 0 {virtuerl/src => src}/virtuerl_mgt.erl | 0 {virtuerl/src => src}/virtuerl_net.erl | 0 {virtuerl/src => src}/virtuerl_pubsub.erl | 0 {virtuerl/src => src}/virtuerl_qemu.erl | 0 {virtuerl/src => src}/virtuerl_qmp.erl | 0 {virtuerl/src => src}/virtuerl_sup.erl | 0 {virtuerl/src => src}/virtuerl_ui.erl | 0 {virtuerl/src => src}/virtuerl_util.erl | 0 {virtuerl/src => src}/virtuerl_vnc.erl | 0 {virtuerl/src => src}/virtuerl_vnc_proxy.erl | 0 {virtuerl/test => test}/ipam.erl | 0 {virtuerl/test => test}/scheduler.erl | 0 {virtuerl/test => test}/virtuerl_SUITE.erl | 0 tests/integration/test_integration.py | 211 --- tests/unit/__init__.py | 0 tests/unit/conftest.py | 231 --- tests/unit/test_dns.py | 151 -- tests/unit/test_domain.py | 110 -- tests/unit/test_host.py | 52 - tests/unit/test_image.py | 35 - tests/unit/test_port_forwarding.py | 141 -- tests/unit/test_route.py | 153 -- virtuerl/.gitignore | 25 - virtuerl/.idea/.gitignore | 5 - virtuerl/.idea/codeStyles/Project.xml | 7 - virtuerl/.idea/codeStyles/codeStyleConfig.xml | 5 - virtuerl/.idea/modules.xml | 21 - virtuerl/.idea/vcs.xml | 6 - virtuerl/LICENSE.md | 186 --- virtuerl/README.md | 57 - virtuerl/Vagrantfile | 77 - virtuerl/bird.conf | 171 --- virtuerl/erlang_ls.config | 9 - 102 files changed, 71 insertions(+), 9126 deletions(-) delete mode 100644 .dockerignore delete mode 100644 .flake8 delete mode 100644 Dockerfile rename {virtuerl/config => config}/sys.config (100%) delete mode 100644 examples/docker-compose.yml rename {virtuerl/hack => hack}/repack (100%) delete mode 100644 minivirt/__init__.py delete mode 100644 minivirt/controller.py delete mode 100644 minivirt/controller_pb2.py delete mode 100644 minivirt/controller_pb2_grpc.py delete mode 100644 minivirt/daemon.py delete mode 100644 minivirt/daemon_pb2.py delete mode 100644 minivirt/daemon_pb2_grpc.py delete mode 100644 minivirt/dns_controller.py delete mode 100644 minivirt/dns_pb2.py delete mode 100644 minivirt/dns_pb2_grpc.py delete mode 100644 minivirt/domain_pb2.py delete mode 100644 minivirt/domain_pb2_grpc.py delete mode 100644 minivirt/host.py delete mode 100644 minivirt/host_pb2.py delete mode 100644 minivirt/host_pb2_grpc.py delete mode 100644 minivirt/image.py delete mode 100644 minivirt/main.py delete mode 100644 minivirt/migrations.py delete mode 100644 minivirt/models.py delete mode 100644 minivirt/port_forwarding.py delete mode 100644 minivirt/port_forwarding_pb2.py delete mode 100644 minivirt/port_forwarding_pb2_grpc.py delete mode 100644 minivirt/route.py delete mode 100644 minivirt/route_pb2.py delete mode 100644 minivirt/route_pb2_grpc.py delete mode 100644 minivirt/utils.py delete mode 100644 minivirt/version.py delete mode 100644 minivirt/volume_pb2.py delete mode 100644 minivirt/volume_pb2_grpc.py delete mode 100644 protos/minivirt/controller.proto delete mode 100644 protos/minivirt/daemon.proto delete mode 100644 protos/minivirt/dns.proto delete mode 100644 protos/minivirt/domain.proto delete mode 100644 protos/minivirt/host.proto delete mode 100644 protos/minivirt/port_forwarding.proto delete mode 100644 protos/minivirt/route.proto delete mode 100644 protos/minivirt/volume.proto delete mode 100644 pyproject.toml rename virtuerl/rebar.config => rebar.config (100%) rename virtuerl/rebar.lock => rebar.lock (100%) delete mode 100644 requirements-dev.txt delete mode 100644 requirements.txt delete mode 100644 setup.py delete mode 100755 snap/hooks/configure delete mode 100644 snap/hooks/install delete mode 100755 snap/local/bin/bird-wrapper delete mode 100755 snap/local/bin/birdc-wrapper delete mode 100755 snap/local/bin/restvirt-controller delete mode 100755 snap/local/bin/restvirt-daemon delete mode 100755 snap/local/bin/restvirt-deregister delete mode 100755 snap/local/bin/restvirt-register delete mode 100755 snap/local/bin/unbound-wrapper delete mode 100644 snap/local/etc/bird/minivirt.conf delete mode 100644 snap/local/etc/unbound/minivirt.conf delete mode 100644 snap/snapcraft.yaml rename {virtuerl/src => src}/virtuerl.app.src (100%) rename {virtuerl/src => src}/virtuerl_api.erl (100%) rename {virtuerl/src => src}/virtuerl_app.erl (100%) rename {virtuerl/src => src}/virtuerl_ghac.erl (100%) rename {virtuerl/src => src}/virtuerl_img.erl (100%) rename {virtuerl/src => src}/virtuerl_ipam.erl (100%) rename {virtuerl/src => src}/virtuerl_mgt.erl (100%) rename {virtuerl/src => src}/virtuerl_net.erl (100%) rename {virtuerl/src => src}/virtuerl_pubsub.erl (100%) rename {virtuerl/src => src}/virtuerl_qemu.erl (100%) rename {virtuerl/src => src}/virtuerl_qmp.erl (100%) rename {virtuerl/src => src}/virtuerl_sup.erl (100%) rename {virtuerl/src => src}/virtuerl_ui.erl (100%) rename {virtuerl/src => src}/virtuerl_util.erl (100%) rename {virtuerl/src => src}/virtuerl_vnc.erl (100%) rename {virtuerl/src => src}/virtuerl_vnc_proxy.erl (100%) rename {virtuerl/test => test}/ipam.erl (100%) rename {virtuerl/test => test}/scheduler.erl (100%) rename {virtuerl/test => test}/virtuerl_SUITE.erl (100%) delete mode 100644 tests/integration/test_integration.py delete mode 100644 tests/unit/__init__.py delete mode 100644 tests/unit/conftest.py delete mode 100644 tests/unit/test_dns.py delete mode 100644 tests/unit/test_domain.py delete mode 100644 tests/unit/test_host.py delete mode 100644 tests/unit/test_image.py delete mode 100644 tests/unit/test_port_forwarding.py delete mode 100644 tests/unit/test_route.py delete mode 100644 virtuerl/.gitignore delete mode 100644 virtuerl/.idea/.gitignore delete mode 100644 virtuerl/.idea/codeStyles/Project.xml delete mode 100644 virtuerl/.idea/codeStyles/codeStyleConfig.xml delete mode 100644 virtuerl/.idea/modules.xml delete mode 100644 virtuerl/.idea/vcs.xml delete mode 100644 virtuerl/LICENSE.md delete mode 100644 virtuerl/README.md delete mode 100644 virtuerl/Vagrantfile delete mode 100644 virtuerl/bird.conf delete mode 100644 virtuerl/erlang_ls.config diff --git a/.dockerignore b/.dockerignore deleted file mode 100644 index 4757721..0000000 --- a/.dockerignore +++ /dev/null @@ -1,4 +0,0 @@ -venv/ -.pytest_cache/ -.idea/ -Dockerfile diff --git a/.flake8 b/.flake8 deleted file mode 100644 index 79f04cc..0000000 --- a/.flake8 +++ /dev/null @@ -1,3 +0,0 @@ -[flake8] -ignore = E501,W503 -exclude = migrations,venv diff --git a/.gitignore b/.gitignore index 5638fa5..78647f9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,25 @@ -#.idea/ -venv/ -.venv/ -__pycache__/ -*.snap -*.egg-info -*.sqlite3 +*.iml +.DS_Store +.vagrant/ +khepri*/ + +.rebar3 +_build +_checkouts +_vendor +.eunit +*.o +*.beam +*.plt +*.swp +*.swo +.erlang.cookie +ebin +log +erl_crash.dump +.rebar +logs +#.idea +#*.iml +rebar3.crashdump +*~ diff --git a/Dockerfile b/Dockerfile deleted file mode 100644 index 0c1ae78..0000000 --- a/Dockerfile +++ /dev/null @@ -1,42 +0,0 @@ -FROM python:3.9.7-slim-bullseye AS base -ENV PATH="/root/.local/bin:$PATH" -WORKDIR /app - - -FROM base AS base_build -RUN apt-get update && apt-get install -y --no-install-recommends \ - gcc \ - libc-dev \ - pkg-config \ - libvirt-dev \ - git \ - && rm -rf /var/lib/apt/lists/* -COPY requirements.txt . -RUN pip install --user -r requirements.txt - - -FROM base_build as test_build -COPY requirements-dev.txt . -RUN pip install --user -r requirements-dev.txt - - -FROM base as base_run -RUN apt-get update && apt-get install -y --no-install-recommends \ - libvirt0 \ - iptables \ - libnftables1 \ - && rm -rf /var/lib/apt/lists/* - - -FROM base_run as test -COPY --from=test_build /root/.local /root/.local -COPY . . -ENTRYPOINT ["/usr/bin/env", "python3", "-m", "pytest"] -CMD ["tests"] - - -FROM base_run as default -LABEL org.opencontainers.image.source=https://github.com/verbit/restvirt -COPY --from=base_build /root/.local /root/.local -COPY . . -ENTRYPOINT ["/usr/bin/env", "python3", "main.py"] diff --git a/README.md b/README.md index c9f4625..8f86b0e 100644 --- a/README.md +++ b/README.md @@ -1,43 +1,57 @@ -# RESTvirt +virtuerl +===== -Manage libvirt through a REST API. +An OTP application -# Installation - -```shell -apt install --no-install-recommends dnsmasq-base libvirt-daemon-system qemu-kvm qemu-utils -snap install minivirt -sudo snap connect minivirt:network-control -sudo snap connect minivirt:firewall-control -sudo snap connect minivirt:libvirt +# Required packages +```sh +sudo apt install ovmf swtpm ``` -## Getting Started - -```shell -git clone git@github.com:verbit/restvirt.git -cd restvirt - -apt install python3-dev libvirt-dev -pip install -r requirements.txt +# Windows Guests + +## Disable boot prompt +```sh +sudo mount -o loop Win11_23H2_EnglishInternational_x64v2.iso /mnt/win + +genisoimage \ + --allow-limited-size \ + -no-emul-boot \ + -b "boot/etfsboot.com" \ + -boot-load-seg 0 \ + -boot-load-size 8 \ + -eltorito-alt-boot \ + -no-emul-boot \ + -e "efi/microsoft/boot/efisys_noprompt.bin" \ + -boot-load-size 1 \ + -iso-level 4 \ + -udf \ + -o "win.iso" \ + /mnt/win/ +``` -mkdir /etc/restvirt +# Running -# start controller -python main.py controller +On the server -#start daemon -apt install libvirt-daemon-system -python main.py daemon +Make sure IP forwarding is enabled (`/etc/sysctl.conf`) ``` - -## Code Generation -```shell -python -m grpc_tools.protoc --python_out=. --grpc_python_out=. -Iprotos/ protos/minivirt/*.proto +# Uncomment the next line to enable packet forwarding for IPv4 +net.ipv4.ip_forward=1 +# Uncomment the next line to enable packet forwarding for IPv6 +net.ipv6.conf.all.forwarding=1 ``` +Run `sysctl -w` to commit changes. -## Known Issues +```sh +sudo -s ./erts-13.1.5/bin/erl -mode embedded -boot releases/0.7.0+build.61.ref8fc0b7e/start -config releases/0.7.0+build.61.ref8fc0b7e/sys.config -proto_dist inet6_tcp -name verbit@verbit.in-berlin.de -setcookie abcdef +``` -* AppArmor - * https://ubuntu.com/server/docs/virtualization-libvirt - * https://bugs.launchpad.net/ubuntu/+source/libvirt/+bug/1677398 +Locally +```sh +rebar3 compile +erl -name moi -proto_dist inet6_tcp -setcookie abcdef -pa _build/default/lib/*/ebin -hidden +(moi@t460s.lan)1> net_adm:ping('virtuerl@a.in6.dev'). +pong +(moi@t460s.lan)2> virtuerl_ui:start('virtuerl@a.in6.dev'). +``` diff --git a/virtuerl/config/sys.config b/config/sys.config similarity index 100% rename from virtuerl/config/sys.config rename to config/sys.config diff --git a/examples/docker-compose.yml b/examples/docker-compose.yml deleted file mode 100644 index 22a1621..0000000 --- a/examples/docker-compose.yml +++ /dev/null @@ -1,21 +0,0 @@ -version: "3.3" -services: - web: - image: ghcr.io/verbit/restvirt:latest - command: - - -b - - :8093 - - --server-cert - - /etc/restvirt/pki/server.crt - - --server-key - - /etc/restvirt/pki/server.key - - --client-ca-cert - - /etc/restvirt/pki/ca.crt - cap_add: - - NET_ADMIN - - NET_RAW - network_mode: host - volumes: - - "/etc/restvirt:/etc/restvirt" - - "/data/restvirt:/data/restvirt" - - "/var/run/libvirt:/var/run/libvirt" diff --git a/virtuerl/hack/repack b/hack/repack similarity index 100% rename from virtuerl/hack/repack rename to hack/repack diff --git a/minivirt/__init__.py b/minivirt/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/minivirt/controller.py b/minivirt/controller.py deleted file mode 100644 index 1aacd5a..0000000 --- a/minivirt/controller.py +++ /dev/null @@ -1,193 +0,0 @@ -import grpc -from google.protobuf import empty_pb2 -from grpc import StatusCode - -from minivirt import ( - controller_pb2_grpc, - daemon_pb2, - daemon_pb2_grpc, - dns_pb2, - dns_pb2_grpc, - route_pb2, - route_pb2_grpc, -) -from minivirt.host import HostController -from minivirt.models import DNSRecord -from minivirt.route import GenericRouteController, GenericRouteTableController, SyncEventHandler - - -class ControllerSyncHandler(SyncEventHandler): - def __init__(self, host_controller): - self.host_controller = host_controller - - def handle_sync(self, session): - channels = self.host_controller.channels() - for channel in channels: - client = daemon_pb2_grpc.DaemonServiceStub(channel) - client.SyncRoutes(daemon_pb2.SyncRoutesRequest()) - - -class Controller( - controller_pb2_grpc.ControllerServiceServicer, - dns_pb2_grpc.DNSServicer, - route_pb2_grpc.RouteServiceServicer, -): - def __init__(self, session_factory, host_controller: HostController, dns_controller): - self.session_factory = session_factory - self.host_controller = host_controller - self.dns_controller = dns_controller - sync_handler = ControllerSyncHandler(host_controller) - self.route_table_controller = GenericRouteTableController(session_factory, sync_handler) - self.route_controller = GenericRouteController(session_factory, sync_handler) - self.channel_cache = {} - - def _get_daemon_client(self, hostname=None): - if not hostname: - hostname = "default" - return daemon_pb2_grpc.DaemonServiceStub(self.host_controller.channel(hostname)) - - def GetDNSRecord(self, request, context): - record = self.dns_controller.record(request.name, request.type) - if record is None: - context.set_code(StatusCode.NOT_FOUND) - return empty_pb2.Empty() - return dns_pb2.DNSRecord( - name=record.name, - type=record.type, - ttl=record.ttl, - records=record.records, - ) - - def ListDNSRecords(self, request, context): - return dns_pb2.ListDNSRecordsResponse( - dns_records=[ - dns_pb2.DNSRecord( - name=record.name, - type=record.type, - ttl=record.ttl, - records=record.records, - ) - for record in self.dns_controller.records() - ] - ) - - def PutDNSRecord(self, request, context): - record = request.dns_record - self.dns_controller.set( - DNSRecord( - name=record.name, - type=record.type, - ttl=record.ttl, - records=record.records, - ) - ) - return record - - def DeleteDNSRecord(self, request, context): - self.dns_controller.remove(request.name, request.type) - return empty_pb2.Empty() - - def GetRouteTable(self, request, context): - table = self.route_table_controller.route_table(request.id) - if table is None: - context.set_code(StatusCode.NOT_FOUND) - return empty_pb2.Empty() - - return route_pb2.RouteTable( - id=table.id, - name=table.name, - ) - - def ListRouteTables(self, request, context): - tables = self.route_table_controller.route_tables() - - return route_pb2.ListRouteTablesResponse( - route_tables=[ - route_pb2.RouteTable( - id=table.id, - name=table.name, - ) - for table in tables - ] - ) - - def CreateRouteTable(self, request, context): - table = self.route_table_controller.create_route_table(request.route_table) - return table - - def DeleteRouteTable(self, request, context): - self.route_table_controller.remove_route_table(request.id) - return empty_pb2.Empty() - - def GetRoute(self, request, context): - route = self.route_controller.route(request.route_table_id, request.destination) - return route_pb2.Route( - route_table_id=route.route_table_id, - destination=route.destination, - gateways=route.gateways, - ) - - def ListRoutes(self, request, context): - routes = self.route_controller.routes(request.route_table_id) - - return route_pb2.ListRoutesResponse( - routes=[ - route_pb2.Route( - route_table_id=route.route_table_id, - destination=route.destination, - gateways=route.gateways, - ) - for route in routes - ] - ) - - def PutRoute(self, request, context): - route = self.route_controller.put_route(request.route) - return route - - def DeleteRoute(self, request, context): - self.route_controller.remove_route(request.route_table_id, request.destination) - return empty_pb2.Empty() - - def SyncRoutes(self, request, context): - self.route_table_controller.sync() - self.route_controller.sync() - return empty_pb2.Empty() - - def Sync(self, request, context): - # TODO: implement or remove - return super().Sync(request, context) - - -def monkeypatch_controller(): - cls = Controller - super_methods = { - getattr(base, a) for base in cls.__bases__ for a in dir(base) if not a.startswith("__") - } - sub_methods = {getattr(cls, a) for a in dir(cls) if not a.startswith("__")} - - for method in super_methods & sub_methods: - method_name = method.__name__ - - def create_target_method(method_name): - def target(self, request, context): - client = self._get_daemon_client(request.host) - try: - to_call = getattr(client, method_name) - if isinstance(to_call, grpc.UnaryUnaryMultiCallable): - return to_call(request) - elif isinstance(to_call, grpc.UnaryStreamMultiCallable): - return (chunk for chunk in to_call(request)) - else: - assert False # TODO - except grpc.RpcError as e: - context.set_code(e.code()) - context.set_details(e.details()) - return empty_pb2.Empty() - - return target - - setattr(cls, method_name, create_target_method(method_name)) - - -monkeypatch_controller() diff --git a/minivirt/controller_pb2.py b/minivirt/controller_pb2.py deleted file mode 100644 index 83d0cfa..0000000 --- a/minivirt/controller_pb2.py +++ /dev/null @@ -1,33 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/controller.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import daemon_pb2 as minivirt_dot_daemon__pb2 -from minivirt import domain_pb2 as minivirt_dot_domain__pb2 -from minivirt import volume_pb2 as minivirt_dot_volume__pb2 -from minivirt import port_forwarding_pb2 as minivirt_dot_port__forwarding__pb2 -from minivirt import dns_pb2 as minivirt_dot_dns__pb2 -from minivirt import route_pb2 as minivirt_dot_route__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x19minivirt/controller.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x15minivirt/daemon.proto\x1a\x15minivirt/domain.proto\x1a\x15minivirt/volume.proto\x1a\x1eminivirt/port_forwarding.proto\x1a\x12minivirt/dns.proto\x1a\x14minivirt/route.proto2\xce\x11\n\x11\x43ontrollerService\x12\x32\n\x0cGetDNSRecord\x12\x14.DNSRecordIdentifier\x1a\n.DNSRecord\"\x00\x12\x43\n\x0eListDNSRecords\x12\x16.ListDNSRecordsRequest\x1a\x17.ListDNSRecordsResponse\"\x00\x12\x32\n\x0cPutDNSRecord\x12\x14.PutDNSRecordRequest\x1a\n.DNSRecord\"\x00\x12\x41\n\x0f\x44\x65leteDNSRecord\x12\x14.DNSRecordIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12,\n\nGetNetwork\x12\x12.GetNetworkRequest\x1a\x08.Network\"\x00\x12=\n\x0cListNetworks\x12\x14.ListNetworksRequest\x1a\x15.ListNetworksResponse\"\x00\x12\x32\n\rCreateNetwork\x12\x15.CreateNetworkRequest\x1a\x08.Network\"\x00\x12@\n\rDeleteNetwork\x12\x15.DeleteNetworkRequest\x1a\x16.google.protobuf.Empty\"\x00\x12<\n\x0bStartDomain\x12\x13.StartDomainRequest\x1a\x16.google.protobuf.Empty\"\x00\x12:\n\nStopDomain\x12\x12.StopDomainRequest\x1a\x16.google.protobuf.Empty\"\x00\x12)\n\tGetDomain\x12\x11.GetDomainRequest\x1a\x07.Domain\"\x00\x12:\n\x0bListDomains\x12\x13.ListDomainsRequest\x1a\x14.ListDomainsResponse\"\x00\x12/\n\x0c\x43reateDomain\x12\x14.CreateDomainRequest\x1a\x07.Domain\"\x00\x12>\n\x0c\x44\x65leteDomain\x12\x14.DeleteDomainRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x37\n\rDownloadImage\x12\x15.DownloadImageRequest\x1a\x0b.ImageChunk\"\x00\x30\x01\x12)\n\tGetVolume\x12\x11.GetVolumeRequest\x1a\x07.Volume\"\x00\x12:\n\x0bListVolumes\x12\x13.ListVolumesRequest\x1a\x14.ListVolumesResponse\"\x00\x12/\n\x0c\x43reateVolume\x12\x14.CreateVolumeRequest\x1a\x07.Volume\"\x00\x12/\n\x0cUpdateVolume\x12\x14.UpdateVolumeRequest\x1a\x07.Volume\"\x00\x12>\n\x0c\x44\x65leteVolume\x12\x14.DeleteVolumeRequest\x1a\x16.google.protobuf.Empty\"\x00\x12X\n\x15ListVolumeAttachments\x12\x1d.ListVolumeAttachmentsRequest\x1a\x1e.ListVolumeAttachmentsResponse\"\x00\x12G\n\x13GetVolumeAttachment\x12\x1b.VolumeAttachmentIdentifier\x1a\x11.VolumeAttachment\"\x00\x12@\n\x0c\x41ttachVolume\x12\x1b.VolumeAttachmentIdentifier\x1a\x11.VolumeAttachment\"\x00\x12\x45\n\x0c\x44\x65tachVolume\x12\x1b.VolumeAttachmentIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\x11GetPortForwarding\x12\x19.PortForwardingIdentifier\x1a\x0f.PortForwarding\"\x00\x12R\n\x13ListPortForwardings\x12\x1b.ListPortForwardingsRequest\x1a\x1c.ListPortForwardingsResponse\"\x00\x12\x41\n\x11PutPortForwarding\x12\x19.PutPortForwardingRequest\x1a\x0f.PortForwarding\"\x00\x12K\n\x14\x44\x65letePortForwarding\x12\x19.PortForwardingIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12\x35\n\rGetRouteTable\x12\x15.RouteTableIdentifier\x1a\x0b.RouteTable\"\x00\x12\x46\n\x0fListRouteTables\x12\x17.ListRouteTablesRequest\x1a\x18.ListRouteTablesResponse\"\x00\x12;\n\x10\x43reateRouteTable\x12\x18.CreateRouteTableRequest\x1a\x0b.RouteTable\"\x00\x12\x43\n\x10\x44\x65leteRouteTable\x12\x15.RouteTableIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12&\n\x08GetRoute\x12\x10.RouteIdentifier\x1a\x06.Route\"\x00\x12\x37\n\nListRoutes\x12\x12.ListRoutesRequest\x1a\x13.ListRoutesResponse\"\x00\x12&\n\x08PutRoute\x12\x10.PutRouteRequest\x1a\x06.Route\"\x00\x12\x39\n\x0b\x44\x65leteRoute\x12\x10.RouteIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12:\n\nSyncRoutes\x12\x12.SyncRoutesRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.controller_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _CONTROLLERSERVICE._serialized_start=202 - _CONTROLLERSERVICE._serialized_end=2456 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/controller_pb2_grpc.py b/minivirt/controller_pb2_grpc.py deleted file mode 100644 index a4fab8c..0000000 --- a/minivirt/controller_pb2_grpc.py +++ /dev/null @@ -1,1260 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import daemon_pb2 as minivirt_dot_daemon__pb2 -from minivirt import dns_pb2 as minivirt_dot_dns__pb2 -from minivirt import domain_pb2 as minivirt_dot_domain__pb2 -from minivirt import port_forwarding_pb2 as minivirt_dot_port__forwarding__pb2 -from minivirt import route_pb2 as minivirt_dot_route__pb2 -from minivirt import volume_pb2 as minivirt_dot_volume__pb2 - - -class ControllerServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetDNSRecord = channel.unary_unary( - '/ControllerService/GetDNSRecord', - request_serializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - response_deserializer=minivirt_dot_dns__pb2.DNSRecord.FromString, - ) - self.ListDNSRecords = channel.unary_unary( - '/ControllerService/ListDNSRecords', - request_serializer=minivirt_dot_dns__pb2.ListDNSRecordsRequest.SerializeToString, - response_deserializer=minivirt_dot_dns__pb2.ListDNSRecordsResponse.FromString, - ) - self.PutDNSRecord = channel.unary_unary( - '/ControllerService/PutDNSRecord', - request_serializer=minivirt_dot_dns__pb2.PutDNSRecordRequest.SerializeToString, - response_deserializer=minivirt_dot_dns__pb2.DNSRecord.FromString, - ) - self.DeleteDNSRecord = channel.unary_unary( - '/ControllerService/DeleteDNSRecord', - request_serializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetNetwork = channel.unary_unary( - '/ControllerService/GetNetwork', - request_serializer=minivirt_dot_domain__pb2.GetNetworkRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Network.FromString, - ) - self.ListNetworks = channel.unary_unary( - '/ControllerService/ListNetworks', - request_serializer=minivirt_dot_domain__pb2.ListNetworksRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ListNetworksResponse.FromString, - ) - self.CreateNetwork = channel.unary_unary( - '/ControllerService/CreateNetwork', - request_serializer=minivirt_dot_domain__pb2.CreateNetworkRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Network.FromString, - ) - self.DeleteNetwork = channel.unary_unary( - '/ControllerService/DeleteNetwork', - request_serializer=minivirt_dot_domain__pb2.DeleteNetworkRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.StartDomain = channel.unary_unary( - '/ControllerService/StartDomain', - request_serializer=minivirt_dot_domain__pb2.StartDomainRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.StopDomain = channel.unary_unary( - '/ControllerService/StopDomain', - request_serializer=minivirt_dot_domain__pb2.StopDomainRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetDomain = channel.unary_unary( - '/ControllerService/GetDomain', - request_serializer=minivirt_dot_domain__pb2.GetDomainRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Domain.FromString, - ) - self.ListDomains = channel.unary_unary( - '/ControllerService/ListDomains', - request_serializer=minivirt_dot_domain__pb2.ListDomainsRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ListDomainsResponse.FromString, - ) - self.CreateDomain = channel.unary_unary( - '/ControllerService/CreateDomain', - request_serializer=minivirt_dot_domain__pb2.CreateDomainRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Domain.FromString, - ) - self.DeleteDomain = channel.unary_unary( - '/ControllerService/DeleteDomain', - request_serializer=minivirt_dot_domain__pb2.DeleteDomainRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.DownloadImage = channel.unary_stream( - '/ControllerService/DownloadImage', - request_serializer=minivirt_dot_domain__pb2.DownloadImageRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ImageChunk.FromString, - ) - self.GetVolume = channel.unary_unary( - '/ControllerService/GetVolume', - request_serializer=minivirt_dot_volume__pb2.GetVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.ListVolumes = channel.unary_unary( - '/ControllerService/ListVolumes', - request_serializer=minivirt_dot_volume__pb2.ListVolumesRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.ListVolumesResponse.FromString, - ) - self.CreateVolume = channel.unary_unary( - '/ControllerService/CreateVolume', - request_serializer=minivirt_dot_volume__pb2.CreateVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.UpdateVolume = channel.unary_unary( - '/ControllerService/UpdateVolume', - request_serializer=minivirt_dot_volume__pb2.UpdateVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.DeleteVolume = channel.unary_unary( - '/ControllerService/DeleteVolume', - request_serializer=minivirt_dot_volume__pb2.DeleteVolumeRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.ListVolumeAttachments = channel.unary_unary( - '/ControllerService/ListVolumeAttachments', - request_serializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.FromString, - ) - self.GetVolumeAttachment = channel.unary_unary( - '/ControllerService/GetVolumeAttachment', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.VolumeAttachment.FromString, - ) - self.AttachVolume = channel.unary_unary( - '/ControllerService/AttachVolume', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.VolumeAttachment.FromString, - ) - self.DetachVolume = channel.unary_unary( - '/ControllerService/DetachVolume', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetPortForwarding = channel.unary_unary( - '/ControllerService/GetPortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - ) - self.ListPortForwardings = channel.unary_unary( - '/ControllerService/ListPortForwardings', - request_serializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.FromString, - ) - self.PutPortForwarding = channel.unary_unary( - '/ControllerService/PutPortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - ) - self.DeletePortForwarding = channel.unary_unary( - '/ControllerService/DeletePortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetRouteTable = channel.unary_unary( - '/ControllerService/GetRouteTable', - request_serializer=minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.RouteTable.FromString, - ) - self.ListRouteTables = channel.unary_unary( - '/ControllerService/ListRouteTables', - request_serializer=minivirt_dot_route__pb2.ListRouteTablesRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.ListRouteTablesResponse.FromString, - ) - self.CreateRouteTable = channel.unary_unary( - '/ControllerService/CreateRouteTable', - request_serializer=minivirt_dot_route__pb2.CreateRouteTableRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.RouteTable.FromString, - ) - self.DeleteRouteTable = channel.unary_unary( - '/ControllerService/DeleteRouteTable', - request_serializer=minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetRoute = channel.unary_unary( - '/ControllerService/GetRoute', - request_serializer=minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.Route.FromString, - ) - self.ListRoutes = channel.unary_unary( - '/ControllerService/ListRoutes', - request_serializer=minivirt_dot_route__pb2.ListRoutesRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.ListRoutesResponse.FromString, - ) - self.PutRoute = channel.unary_unary( - '/ControllerService/PutRoute', - request_serializer=minivirt_dot_route__pb2.PutRouteRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.Route.FromString, - ) - self.DeleteRoute = channel.unary_unary( - '/ControllerService/DeleteRoute', - request_serializer=minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.SyncRoutes = channel.unary_unary( - '/ControllerService/SyncRoutes', - request_serializer=minivirt_dot_daemon__pb2.SyncRoutesRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - - -class ControllerServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def GetDNSRecord(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListDNSRecords(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutDNSRecord(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteDNSRecord(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListNetworks(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def StartDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def StopDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListDomains(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DownloadImage(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListVolumes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListVolumeAttachments(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetVolumeAttachment(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def AttachVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DetachVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetPortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListPortForwardings(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutPortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeletePortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetRouteTable(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListRouteTables(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateRouteTable(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteRouteTable(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetRoute(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListRoutes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutRoute(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteRoute(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SyncRoutes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_ControllerServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetDNSRecord': grpc.unary_unary_rpc_method_handler( - servicer.GetDNSRecord, - request_deserializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.FromString, - response_serializer=minivirt_dot_dns__pb2.DNSRecord.SerializeToString, - ), - 'ListDNSRecords': grpc.unary_unary_rpc_method_handler( - servicer.ListDNSRecords, - request_deserializer=minivirt_dot_dns__pb2.ListDNSRecordsRequest.FromString, - response_serializer=minivirt_dot_dns__pb2.ListDNSRecordsResponse.SerializeToString, - ), - 'PutDNSRecord': grpc.unary_unary_rpc_method_handler( - servicer.PutDNSRecord, - request_deserializer=minivirt_dot_dns__pb2.PutDNSRecordRequest.FromString, - response_serializer=minivirt_dot_dns__pb2.DNSRecord.SerializeToString, - ), - 'DeleteDNSRecord': grpc.unary_unary_rpc_method_handler( - servicer.DeleteDNSRecord, - request_deserializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetNetwork': grpc.unary_unary_rpc_method_handler( - servicer.GetNetwork, - request_deserializer=minivirt_dot_domain__pb2.GetNetworkRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Network.SerializeToString, - ), - 'ListNetworks': grpc.unary_unary_rpc_method_handler( - servicer.ListNetworks, - request_deserializer=minivirt_dot_domain__pb2.ListNetworksRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ListNetworksResponse.SerializeToString, - ), - 'CreateNetwork': grpc.unary_unary_rpc_method_handler( - servicer.CreateNetwork, - request_deserializer=minivirt_dot_domain__pb2.CreateNetworkRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Network.SerializeToString, - ), - 'DeleteNetwork': grpc.unary_unary_rpc_method_handler( - servicer.DeleteNetwork, - request_deserializer=minivirt_dot_domain__pb2.DeleteNetworkRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'StartDomain': grpc.unary_unary_rpc_method_handler( - servicer.StartDomain, - request_deserializer=minivirt_dot_domain__pb2.StartDomainRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'StopDomain': grpc.unary_unary_rpc_method_handler( - servicer.StopDomain, - request_deserializer=minivirt_dot_domain__pb2.StopDomainRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetDomain': grpc.unary_unary_rpc_method_handler( - servicer.GetDomain, - request_deserializer=minivirt_dot_domain__pb2.GetDomainRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Domain.SerializeToString, - ), - 'ListDomains': grpc.unary_unary_rpc_method_handler( - servicer.ListDomains, - request_deserializer=minivirt_dot_domain__pb2.ListDomainsRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ListDomainsResponse.SerializeToString, - ), - 'CreateDomain': grpc.unary_unary_rpc_method_handler( - servicer.CreateDomain, - request_deserializer=minivirt_dot_domain__pb2.CreateDomainRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Domain.SerializeToString, - ), - 'DeleteDomain': grpc.unary_unary_rpc_method_handler( - servicer.DeleteDomain, - request_deserializer=minivirt_dot_domain__pb2.DeleteDomainRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'DownloadImage': grpc.unary_stream_rpc_method_handler( - servicer.DownloadImage, - request_deserializer=minivirt_dot_domain__pb2.DownloadImageRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ImageChunk.SerializeToString, - ), - 'GetVolume': grpc.unary_unary_rpc_method_handler( - servicer.GetVolume, - request_deserializer=minivirt_dot_volume__pb2.GetVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'ListVolumes': grpc.unary_unary_rpc_method_handler( - servicer.ListVolumes, - request_deserializer=minivirt_dot_volume__pb2.ListVolumesRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.ListVolumesResponse.SerializeToString, - ), - 'CreateVolume': grpc.unary_unary_rpc_method_handler( - servicer.CreateVolume, - request_deserializer=minivirt_dot_volume__pb2.CreateVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'UpdateVolume': grpc.unary_unary_rpc_method_handler( - servicer.UpdateVolume, - request_deserializer=minivirt_dot_volume__pb2.UpdateVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'DeleteVolume': grpc.unary_unary_rpc_method_handler( - servicer.DeleteVolume, - request_deserializer=minivirt_dot_volume__pb2.DeleteVolumeRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'ListVolumeAttachments': grpc.unary_unary_rpc_method_handler( - servicer.ListVolumeAttachments, - request_deserializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.SerializeToString, - ), - 'GetVolumeAttachment': grpc.unary_unary_rpc_method_handler( - servicer.GetVolumeAttachment, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=minivirt_dot_volume__pb2.VolumeAttachment.SerializeToString, - ), - 'AttachVolume': grpc.unary_unary_rpc_method_handler( - servicer.AttachVolume, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=minivirt_dot_volume__pb2.VolumeAttachment.SerializeToString, - ), - 'DetachVolume': grpc.unary_unary_rpc_method_handler( - servicer.DetachVolume, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetPortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.GetPortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.PortForwarding.SerializeToString, - ), - 'ListPortForwardings': grpc.unary_unary_rpc_method_handler( - servicer.ListPortForwardings, - request_deserializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.SerializeToString, - ), - 'PutPortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.PutPortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.PortForwarding.SerializeToString, - ), - 'DeletePortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.DeletePortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetRouteTable': grpc.unary_unary_rpc_method_handler( - servicer.GetRouteTable, - request_deserializer=minivirt_dot_route__pb2.RouteTableIdentifier.FromString, - response_serializer=minivirt_dot_route__pb2.RouteTable.SerializeToString, - ), - 'ListRouteTables': grpc.unary_unary_rpc_method_handler( - servicer.ListRouteTables, - request_deserializer=minivirt_dot_route__pb2.ListRouteTablesRequest.FromString, - response_serializer=minivirt_dot_route__pb2.ListRouteTablesResponse.SerializeToString, - ), - 'CreateRouteTable': grpc.unary_unary_rpc_method_handler( - servicer.CreateRouteTable, - request_deserializer=minivirt_dot_route__pb2.CreateRouteTableRequest.FromString, - response_serializer=minivirt_dot_route__pb2.RouteTable.SerializeToString, - ), - 'DeleteRouteTable': grpc.unary_unary_rpc_method_handler( - servicer.DeleteRouteTable, - request_deserializer=minivirt_dot_route__pb2.RouteTableIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetRoute': grpc.unary_unary_rpc_method_handler( - servicer.GetRoute, - request_deserializer=minivirt_dot_route__pb2.RouteIdentifier.FromString, - response_serializer=minivirt_dot_route__pb2.Route.SerializeToString, - ), - 'ListRoutes': grpc.unary_unary_rpc_method_handler( - servicer.ListRoutes, - request_deserializer=minivirt_dot_route__pb2.ListRoutesRequest.FromString, - response_serializer=minivirt_dot_route__pb2.ListRoutesResponse.SerializeToString, - ), - 'PutRoute': grpc.unary_unary_rpc_method_handler( - servicer.PutRoute, - request_deserializer=minivirt_dot_route__pb2.PutRouteRequest.FromString, - response_serializer=minivirt_dot_route__pb2.Route.SerializeToString, - ), - 'DeleteRoute': grpc.unary_unary_rpc_method_handler( - servicer.DeleteRoute, - request_deserializer=minivirt_dot_route__pb2.RouteIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'SyncRoutes': grpc.unary_unary_rpc_method_handler( - servicer.SyncRoutes, - request_deserializer=minivirt_dot_daemon__pb2.SyncRoutesRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'ControllerService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class ControllerService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetDNSRecord(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetDNSRecord', - minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - minivirt_dot_dns__pb2.DNSRecord.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListDNSRecords(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListDNSRecords', - minivirt_dot_dns__pb2.ListDNSRecordsRequest.SerializeToString, - minivirt_dot_dns__pb2.ListDNSRecordsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutDNSRecord(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/PutDNSRecord', - minivirt_dot_dns__pb2.PutDNSRecordRequest.SerializeToString, - minivirt_dot_dns__pb2.DNSRecord.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteDNSRecord(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DeleteDNSRecord', - minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetNetwork', - minivirt_dot_domain__pb2.GetNetworkRequest.SerializeToString, - minivirt_dot_domain__pb2.Network.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListNetworks(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListNetworks', - minivirt_dot_domain__pb2.ListNetworksRequest.SerializeToString, - minivirt_dot_domain__pb2.ListNetworksResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/CreateNetwork', - minivirt_dot_domain__pb2.CreateNetworkRequest.SerializeToString, - minivirt_dot_domain__pb2.Network.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DeleteNetwork', - minivirt_dot_domain__pb2.DeleteNetworkRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def StartDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/StartDomain', - minivirt_dot_domain__pb2.StartDomainRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def StopDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/StopDomain', - minivirt_dot_domain__pb2.StopDomainRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetDomain', - minivirt_dot_domain__pb2.GetDomainRequest.SerializeToString, - minivirt_dot_domain__pb2.Domain.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListDomains(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListDomains', - minivirt_dot_domain__pb2.ListDomainsRequest.SerializeToString, - minivirt_dot_domain__pb2.ListDomainsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/CreateDomain', - minivirt_dot_domain__pb2.CreateDomainRequest.SerializeToString, - minivirt_dot_domain__pb2.Domain.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DeleteDomain', - minivirt_dot_domain__pb2.DeleteDomainRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DownloadImage(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_stream(request, target, '/ControllerService/DownloadImage', - minivirt_dot_domain__pb2.DownloadImageRequest.SerializeToString, - minivirt_dot_domain__pb2.ImageChunk.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetVolume', - minivirt_dot_volume__pb2.GetVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListVolumes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListVolumes', - minivirt_dot_volume__pb2.ListVolumesRequest.SerializeToString, - minivirt_dot_volume__pb2.ListVolumesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/CreateVolume', - minivirt_dot_volume__pb2.CreateVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def UpdateVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/UpdateVolume', - minivirt_dot_volume__pb2.UpdateVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DeleteVolume', - minivirt_dot_volume__pb2.DeleteVolumeRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListVolumeAttachments(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListVolumeAttachments', - minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.SerializeToString, - minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetVolumeAttachment(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetVolumeAttachment', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - minivirt_dot_volume__pb2.VolumeAttachment.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def AttachVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/AttachVolume', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - minivirt_dot_volume__pb2.VolumeAttachment.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DetachVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DetachVolume', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetPortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetPortForwarding', - minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListPortForwardings(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListPortForwardings', - minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.SerializeToString, - minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutPortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/PutPortForwarding', - minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.SerializeToString, - minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeletePortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DeletePortForwarding', - minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetRouteTable(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetRouteTable', - minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - minivirt_dot_route__pb2.RouteTable.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListRouteTables(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListRouteTables', - minivirt_dot_route__pb2.ListRouteTablesRequest.SerializeToString, - minivirt_dot_route__pb2.ListRouteTablesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateRouteTable(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/CreateRouteTable', - minivirt_dot_route__pb2.CreateRouteTableRequest.SerializeToString, - minivirt_dot_route__pb2.RouteTable.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteRouteTable(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DeleteRouteTable', - minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetRoute(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/GetRoute', - minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - minivirt_dot_route__pb2.Route.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListRoutes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/ListRoutes', - minivirt_dot_route__pb2.ListRoutesRequest.SerializeToString, - minivirt_dot_route__pb2.ListRoutesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutRoute(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/PutRoute', - minivirt_dot_route__pb2.PutRouteRequest.SerializeToString, - minivirt_dot_route__pb2.Route.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteRoute(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/DeleteRoute', - minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SyncRoutes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/ControllerService/SyncRoutes', - minivirt_dot_daemon__pb2.SyncRoutesRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/minivirt/daemon.py b/minivirt/daemon.py deleted file mode 100644 index 696fcc1..0000000 --- a/minivirt/daemon.py +++ /dev/null @@ -1,894 +0,0 @@ -import ipaddress -import os -import re -import string -import threading -import uuid -from datetime import datetime, timezone - -import libvirt -import requests -import xmltodict -from google.protobuf import empty_pb2, timestamp_pb2 -from grpc import StatusCode -from pyroute2 import IPRoute -from pyroute2.netlink.rtnl import rtypes -from requests.exceptions import ConnectionError, HTTPError -from sqlalchemy import delete, select - -from minivirt import ( - controller_pb2_grpc, - daemon_pb2_grpc, - domain_pb2, - port_forwarding_pb2, - route_pb2, - volume_pb2, -) -from minivirt.image import create_cloud_config_image -from minivirt.models import Domain, PortForwarding - - -def libvirt_state_to_string(state): - if state == libvirt.VIR_DOMAIN_NOSTATE: - return "NOSTATE" - elif state == libvirt.VIR_DOMAIN_RUNNING: - return "RUNNING" - elif state == libvirt.VIR_DOMAIN_BLOCKED: - return "BLOCKED" - elif state == libvirt.VIR_DOMAIN_PAUSED: - return "PAUSED" - elif state == libvirt.VIR_DOMAIN_SHUTDOWN: - return "SHUTDOWN" - elif state == libvirt.VIR_DOMAIN_CRASHED: - return "CRASHED" - elif state == libvirt.VIR_DOMAIN_PMSUSPENDED: - return "PMSUSPENDED" - elif state == libvirt.VIR_DOMAIN_SHUTOFF: - return "SHUTOFF" - return "UNKNOWN" - - -def domain_to_dict(domain): - domain_dict = xmltodict.parse(domain.XMLDesc(libvirt.VIR_DOMAIN_XML_INACTIVE)) - d = domain_dict["domain"] - res = { - "uuid": d["uuid"], - "name": d["name"], - "vcpu": int(d["vcpu"]["#text"]), - "memory": int(d["memory"]["#text"]) // 1024, - "nested_virtualization": d["cpu"]["@mode"] == "host-model", - } - try: - res["network"] = d["devices"]["interface"]["source"]["@network"] - except: - pass - try: # FIXME: once all have create metadata, remove this try/catch - dt = datetime.fromisoformat(d["metadata"]["restvirt:metadata"]["created"]) - res["created_at"] = timestamp_pb2.Timestamp( - seconds=int(dt.timestamp()) - ) # we don't need sub-second precision - except Exception as e: - print(e) - return res - - -def _volume_to_dict(vol): - _, cap, _ = vol.info() - name = vol.name() - return { - "id": name, - "name": name, - "size": cap, - } - - -def _get_attachments(domain): - domain_dict = xmltodict.parse(domain.XMLDesc()) - disks = domain_dict["domain"]["devices"]["disk"] - volume_ids = [ - d["alias"]["@name"][3:] - for d in disks - if d["@device"] == "disk" and d["alias"]["@name"].startswith("ua-") - ] - attachments = [ - { - "volume_id": vid, - "disk_address": _disk_address(domain_dict, vid), - } - for vid in volume_ids - ] - - return attachments - - -def _get_all_attachments(domains, vol): - vol_id = vol.name() - attachments = [(domain, _get_attachments(domain)) for domain in domains] - attachments = [(d, da) for d, das in attachments for da in das] - filtered_domains = [(d, da) for (d, da) in attachments if da["volume_id"] == vol_id] - filtered_domains = [ - {"domain_id": d.UUIDString(), "disk_address": da["disk_address"]} - for d, da in filtered_domains - ] - return filtered_domains - - -def _disk_address(domain_dict, volume_id): - disks = domain_dict["domain"]["devices"]["disk"] - - da = [d["address"] for d in disks if d["alias"]["@name"] == f"ua-{volume_id}"][0] - daddr = [int(da[f"@{k}"], 16) for k in ["domain", "bus", "slot", "function"]] - return f"{da['@type']}-{daddr[0]:04x}:{daddr[1]:02x}:{daddr[2]:02x}.{daddr[3]:x}" - - -def disk_address(domain, volume_id): - domain_dict = xmltodict.parse(domain.XMLDesc()) - return _disk_address(domain_dict, volume_id) - - -class IPRouteTableSynchronizer: - id_range_min, id_range_max = 30069, 30169 - - def __init__(self): - self.lock = threading.Lock() - - def handle_sync(self, client: controller_pb2_grpc.ControllerServiceStub): - with self.lock, IPRoute() as ip: - tables = client.ListRouteTables(route_pb2.ListRouteTablesRequest()).route_tables - table_ids = {t.id for t in tables} - - def filt(r): - prio = r.get_attr("FRA_PRIORITY") - return prio is not None and self.id_range_min <= prio <= self.id_range_max - - rules = filter(filt, ip.get_rules()) - rules = {r.get_attr("FRA_PRIORITY"): r for r in rules} - - # step 1: delete tables not in conf - for prio in rules: - if prio not in table_ids: - ip.rule("del", priority=prio) - - # step 2: update tables - # TODO: this is broken - for table in tables: - if table.id not in rules or rules[table.id]["table"] != table.id: - try: - ip.rule("del", priority=table.id) - except: - pass - ip.rule( - "add", - priority=table.id, - table=table.id, - ) - - -# TODO: RouteTableController -# try: -# # FIXME: make "virbr0" configurable -# ip.rule( -# "add", table=TABLE_ID, priority=30069, iifname="virbr0" -# ) # FIXME: check if rule identical -# except NetlinkError as e: -# if e.code != 17: # 17 = rule already exists -# raise e - - -class IPRouteSynchronizer: - id_range_min, id_range_max = 30069, 30169 - - def __init__(self): - self.lock = threading.Lock() - - def get_ip_routes(self, ip): - filtered_routes = {} - for r in ip.get_routes(): - table_id = r.get_attr("RTA_TABLE") - if not self.id_range_min <= table_id < self.id_range_max: - continue - if r["family"] != 2 or r["type"] != rtypes["RTN_UNICAST"]: - continue - dst = r.get_attr("RTA_DST") - if dst is None: - continue - dstnet = f"{dst}/{r['dst_len']}" - addr = ipaddress.ip_network(dstnet) - - gateway = r.get_attr("RTA_GATEWAY") - if gateway is not None: - gateways = [gateway] - else: - routes = r.get_attr("RTA_MULTIPATH") - gateways = [r.get_attr("RTA_GATEWAY") for r in routes] - filtered_routes[addr] = (table_id, {ipaddress.ip_address(gw) for gw in gateways}) - - return filtered_routes - - def remove_ip_route(self, ip, table_id, dst): - ip.route("del", table=table_id, dst=str(dst)) - - def put_ip_route(self, ip, table_id, dst, gws): - try: - ip.route("del", table=table_id, dst=str(dst)) - except: - pass - ip.route( - "add", - table=table_id, - dst=str(dst), - multipath=[{"gateway": str(gw)} for gw in gws], - ) - - def handle_sync(self, client: controller_pb2_grpc.ControllerServiceStub): - with self.lock, IPRoute() as ip: - tables = client.ListRouteTables(route_pb2.ListRouteTablesRequest()).route_tables - routes = [ - client.ListRoutes(route_pb2.ListRoutesRequest(route_table_id=table.id)).routes - for table in tables - ] - routes = [r for rs in routes for r in rs] - routes = { - ipaddress.IPv4Network(route.destination): ( - route.route_table_id, - {ipaddress.IPv4Address(gw) for gw in route.gateways}, - ) - for route in routes - } - - filtered_routes = self.get_ip_routes(ip) - - # step 1: delete routes not in conf - for dst, (tid, gws) in filtered_routes.items(): - if dst not in routes: - self.remove_ip_route(ip, tid, dst) - - # step 2: update routes - for dst, (tid, gws) in routes.items(): - if dst not in filtered_routes or filtered_routes[dst][1] != gws: - self.put_ip_route(ip, tid, dst, gws) - - -def create_storage_pool(conn, name, pool_dir, location=None): - if location is None: - location = name - - try: - conn.storagePoolLookupByName(name) - except libvirt.libvirtError as e: - if e.get_error_code() == libvirt.VIR_ERR_NO_STORAGE_POOL: - pool = conn.storagePoolDefineXML( - f""" - {name} - - {os.path.join(pool_dir, location)} - - """ - ) - pool.build() - pool.create() - else: - raise e - - -def get_root_volume(conn, domain_name): - try: - pool = conn.storagePoolLookupByName("volumes") - vol = pool.storageVolLookupByName(f"{domain_name}-root.qcow2") - except: - # FIXME: can be removed once not in use - pool = conn.storagePoolLookupByName("restvirtimages") - vol = pool.storageVolLookupByName(f"{domain_name}-root.qcow2") - return vol - - -def _network_prefix(net_elem): - # FIXME: remove/simplify me, once all network use prefix - if "@netmask" in net_elem: - return ipaddress.ip_network("0.0.0.0/" + net_elem["@netmask"]).prefixlen - return net_elem["@prefix"] - - -def _network_to_pb(net): - net_dict = xmltodict.parse(net.XMLDesc(), force_list=("ip",))["network"] - cidr6 = "" - if len(net_dict["ip"]) > 1: - cidr6 = str( - ipaddress.ip_network( - f'{net_dict["ip"][1]["@address"]}/{_network_prefix(net_dict["ip"][1])}', - strict=False, - ) - ) - return domain_pb2.Network( - uuid=net_dict["uuid"], - name=net_dict["name"], - cidr=str( - ipaddress.ip_network( - f'{net_dict["ip"][0]["@address"]}/{_network_prefix(net_dict["ip"][0])}', - strict=False, - ) - ), - cidr6=cidr6, - ) - - -class DaemonService(daemon_pb2_grpc.DaemonServiceServicer): - def __init__( - self, session_factory, port_fwd_sync_handler, controller_channel, pool_dir="/data/restvirt" - ): - self.session_factory = session_factory - self.port_fwd_sync_handler = port_fwd_sync_handler - self.controller = controller_pb2_grpc.ControllerServiceStub(controller_channel) - - self.tables_synchronizer = IPRouteTableSynchronizer() - self.routes_synchronizer = IPRouteSynchronizer() - - self.conn = libvirt.open("qemu:///system?socket=/var/run/libvirt/libvirt-sock") - - self.lock = threading.Lock() - - create_storage_pool(self.conn, "restvirtimages", pool_dir, "images") - create_storage_pool(self.conn, "volumes", pool_dir) - - def GetNetwork(self, request, context): - net = self.conn.networkLookupByUUIDString(request.uuid) - return _network_to_pb(net) - - def ListNetworks(self, request, context): - return domain_pb2.ListNetworksResponse( - networks=[_network_to_pb(net) for net in (self.conn.listAllNetworks())] - ) - - def CreateNetwork(self, request, context): - network = request.network - - try: - net_json = {} - if network.cidr: - net_json["cidr4"] = network.cidr - if network.cidr6: - net_json["cidr6"] = network.cidr6 - res = requests.post( - "http://localhost:8081/networks", - json={"network": net_json}, - ) - res.raise_for_status() - virtuerl_net = res.json() - net_id = virtuerl_net["id"] - except HTTPError as e: - raise e - - return domain_pb2.Network( - uuid=net_id, - name="name", - cidr=network.cidr, - cidr6=network.cidr6, - ) - - def DeleteNetwork(self, request, context): - try: - net = self.conn.networkLookupByUUIDString(request.uuid) - try: - net.destroy() - except: - pass - net.undefine() - except: - pass - - requests.delete(f"http://localhost:8081/networks/{request.uuid}") - - return empty_pb2.Empty() - - def StartDomain(self, request, context): - domain = self.conn.lookupByUUIDString(request.uuid) - domain.create() - return empty_pb2.Empty() - - def StopDomain(self, request, context): - domain = self.conn.lookupByUUIDString(request.uuid) - if request.force: - domain.destroy() - else: - domain.shutdown() - return empty_pb2.Empty() - - def _get_domain(self, uuid): - domain_lv = self.conn.lookupByUUIDString(uuid) - domain_dict = domain_to_dict(domain_lv) - try: - net = self.conn.networkLookupByName(domain_dict["network"]) - domain_dict["network"] = net.UUIDString() - except: - res = requests.get(f"http://localhost:8081/domains/{uuid}") - resj = res.json() - domain_dict["network"] = resj["network_id"] - state, _ = domain_lv.state() - domain_dict["state"] = libvirt_state_to_string(state) - - with self.session_factory() as session: - domain = ( - session.execute( - select(Domain).filter( - Domain.id == uuid, - ) - ) - .scalars() - .one_or_none() - ) - domain_dict["os_type"] = domain.os_type - domain_dict["private_ip"] = domain.private_ip - domain_dict["ipv6_address"] = domain.ipv6_address - domain_dict["user_data"] = domain.user_data - - return domain_dict - - def GetDomain(self, request, context): - return domain_pb2.Domain(**self._get_domain(request.uuid)) - - def ListDomains(self, request, context): - domains = self.conn.listAllDomains() - ds = [domain_pb2.Domain(**domain_to_dict(d)) for d in domains] - return domain_pb2.ListDomainsResponse(domains=ds) - - def CreateDomain(self, request, context): - domreq = request.domain - - req_net = {"domain": {"network_id": domreq.network}} - private_ip = domreq.private_ip - if private_ip: - req_net["domain"]["ipv4_addr"] = private_ip - ipv6_address = domreq.ipv6_address - if ipv6_address: - req_net["domain"]["ipv6_addr"] = ipv6_address - - mac = None - try: - res = requests.post("http://localhost:8081/domains", json=req_net) - res.raise_for_status() - virtuerl_dom = res.json() - dom_id = virtuerl_dom["id"] - tap_name = virtuerl_dom["tap_name"] - ip_addr = virtuerl_dom["ipv4_addr"] - mac = virtuerl_dom["mac_addr"] - mac = ":".join(re.findall("..", mac.lower())) - if ipv6_address: - ip6_addr = virtuerl_dom["ipv6_addr"] - except HTTPError as e: - raise e - - gateway6 = None - net6 = None - - try: - lvnet = self.conn.networkLookupByUUIDString(domreq.network) - - net_dict = xmltodict.parse(lvnet.XMLDesc(), force_list=("ip",)) - net_def = net_dict["network"]["ip"][0] - gateway = ipaddress.ip_address(net_def["@address"]) - net = ipaddress.ip_network(f"{gateway}/{_network_prefix(net_def)}", strict=False) - - if len(net_dict["network"]["ip"]) > 1: - net6_def = net_dict["network"]["ip"][1] - gateway6 = ipaddress.ip_address(net6_def["@address"]) - net6 = ipaddress.ip_network(f'{gateway6}/{net6_def["@prefix"]}', strict=False) - - is_virtuerl_net = False - except libvirt.libvirtError as e: - if e.get_error_code() != libvirt.VIR_ERR_NO_NETWORK: - raise e - private_ip = ip_addr - - vres = requests.get(f"http://localhost:8081/networks/{domreq.network}") - vres.raise_for_status() - vresj = vres.json() - cidrs = [ipaddress.ip_network(cidr, strict=False) for cidr in vresj["cidrs"]] - cidr4 = [cidr for cidr in cidrs if isinstance(cidr, ipaddress.IPv4Network)] - cidr6 = [cidr for cidr in cidrs if isinstance(cidr, ipaddress.IPv6Network)] - net = cidr4[0] - gateway = net[1] - if ipv6_address: - net6 = cidr6[0] - gateway6 = net6[1] - - is_virtuerl_net = True - - dom_uuid = dom_id - os_type = domreq.os_type - if os_type is None: - os_type = "linux" - user_data = domreq.user_data - if user_data is None: - user_data = "" - with self.lock: - with self.session_factory() as session: - domains = session.execute(select(Domain)).scalars().all() - - ips = set([dom.private_ip for dom in domains]) - if not private_ip: - available = {str(h) for h in net.hosts()} - available -= {str(net.network_address), str(net.broadcast_address)} - available -= ips - private_ip = available.pop() - else: - assert private_ip not in ips - - domain = Domain( - id=str(dom_uuid), - os_type=os_type, - private_ip=private_ip, - ipv6_address=ipv6_address, - user_data=user_data, - ) - session.add(domain) - session.commit() - - ip = ipaddress.ip_address(private_ip) - ip6 = ipaddress.ip_address(ipv6_address) if ipv6_address else None - if mac is None: - mac = "{:02x}:{:02x}:{:02x}:{:02x}:{:02x}:{:02x}".format( - 0x52, 0x54, 0x00, ip.packed[-3], ip.packed[-2], ip.packed[-1] - ) - - if is_virtuerl_net: - netxml = f""" - - - - -""" - else: - netxml = f""" - - - - -""" - - img_pool = self.conn.storagePoolLookupByName("restvirtimages") - if not domreq.base_image: - base_img_name = "debian-12-generic-amd64-20240102-1614.qcow2" - try: - base_img = img_pool.storageVolLookupByName(base_img_name) - except: - from urllib.request import urlopen - - res = urlopen( - f"https://cloud.debian.org/images/cloud/bookworm/20240102-1614/debian-12-generic-amd64-20240102-1614.qcow2" - ) - size = int(res.getheader("Content-length")) - base_img = img_pool.createXML( - f""" - {base_img_name} - {size} - - - -""" - ) - stream = self.conn.newStream() - base_img.upload(stream, 0, size) - while True: - chunk = res.read(64 * 1024) - if not chunk: - break - stream.send(chunk) - stream.finish() - else: - base_img = img_pool.storageVolLookupByName(domreq.base_image) - - vol_pool = self.conn.storagePoolLookupByName("volumes") - vol = vol_pool.createXML( - f""" - {domreq.name}-root.qcow2 - {20} - - {base_img.path()} - - - - - -""" - ) - root_image_path = vol.path() - - ccfg_raw = create_cloud_config_image( - domain_id=dom_uuid, - user_data=user_data, - mac=mac, - network=net, - network6=net6, - address=ip, - address6=ip6, - gateway=net[1], - gateway6=gateway6, - name=domreq.name, - ) - stream = self.conn.newStream() - ccfg_vol = img_pool.createXML( - f""" - {domreq.name}-cloud-init.img - {len(ccfg_raw)} - - - -""" - ) - ccfg_vol.upload(stream, 0, len(ccfg_raw)) - stream.send(ccfg_raw) - stream.finish() - - creation_timestamp = datetime.now(timezone.utc) - dom = self.conn.defineXML( - f""" - {dom_uuid} - - - {creation_timestamp.isoformat()} - - - - - - {"" if domreq.nested_virtualization else ""} - {domreq.name} - {domreq.vcpu} - {domreq.memory} - - hvm - - - - - - - - - - - - - {netxml} - - -""" - ) - - dom.setAutostart(True) - dom.create() - - return domain_pb2.Domain(**self._get_domain(dom.UUIDString())) - - def DeleteDomain(self, request, context): - with self.session_factory() as session: - session.execute(delete(Domain).where(Domain.id == request.uuid)) - session.commit() - - dom = self.conn.lookupByUUIDString(str(request.uuid)) - name = dom.name() - try: - dom.destroy() - except libvirt.libvirtError as e: - if "Requested operation is not valid: domain is not running" in str(e): - pass - else: - raise e - dom.undefine() - - pool = self.conn.storagePoolLookupByName("restvirtimages") - vol = get_root_volume(self.conn, name) - vol.delete() - vol = pool.storageVolLookupByName(f"{name}-cloud-init.img") - vol.delete() - - requests.delete(f"http://localhost:8081/domains/{str(request.uuid)}") - - return empty_pb2.Empty() - - def DownloadImage(self, request, context): - dom = self.conn.lookupByUUIDString(request.domain_id) - name = dom.name() - vol = get_root_volume(self.conn, name) - stream = self.conn.newStream() - vol.download(stream, 0, 0) - while True: - bytes = stream.recv(64 * 1024) - if not bytes: - break - yield domain_pb2.ImageChunk(bytes=bytes) - stream.finish() - - def GetVolume(self, request, context): - pool = self.conn.storagePoolLookupByName("volumes") - vol = pool.storageVolLookupByName(request.uuid) - return volume_pb2.Volume(**_volume_to_dict(vol)) - - def ListVolumes(self, request, context): - pool = self.conn.storagePoolLookupByName("volumes") - vols = pool.listAllVolumes() - vol_dicts = [_volume_to_dict(vol) for vol in vols] - return volume_pb2.ListVolumesResponse(volumes=[volume_pb2.Volume(**d) for d in vol_dicts]) - - def CreateVolume(self, request, context): - pool = self.conn.storagePoolLookupByName("volumes") - vol = pool.createXML( - f""" - {request.volume.name} - {request.volume.size} - - - -""" - ) - return volume_pb2.Volume( - id=vol.name(), - name=request.volume.name, - size=request.volume.size, - ) - - def UpdateVolume(self, request, context): - pool = self.conn.storagePoolLookupByName("volumes") - vol = pool.storageVolLookupByName(request.volume.id) - _, current_capacity, _ = vol.info() - desired_capacity = request.volume.size - if desired_capacity < current_capacity: - raise Exception("shrinking volumes is not supported") - vol.resize(desired_capacity) - return volume_pb2.Volume(**_volume_to_dict(vol)) - - def DeleteVolume(self, request, context): - pool = self.conn.storagePoolLookupByName("volumes") - vol = pool.storageVolLookupByName(request.uuid) - if _get_all_attachments(self.conn.listAllDomains(), vol): - raise Exception("volume is attached z") - vol.delete() - return empty_pb2.Empty() - - def ListVolumeAttachments(self, request, context): - domain = self.conn.lookupByUUIDString(request.domain_id) - return volume_pb2.ListVolumeAttachmentsResponse( - attachments=[ - volume_pb2.VolumeAttachment(domain_id=request.domain_id, **a) - for a in _get_attachments(domain) - ] - ) - - def GetVolumeAttachment(self, request, context): - domain = self.conn.lookupByUUIDString(request.domain_id) - pool = self.conn.storagePoolLookupByName("volumes") - vol = pool.storageVolLookupByName(request.volume_id) - - return volume_pb2.VolumeAttachment( - domain_id=domain.UUIDString(), - volume_id=vol.name(), - disk_address=disk_address(domain, request.volume_id), - ) - - def AttachVolume(self, request, context): - domain = self.conn.lookupByUUIDString(request.domain_id) - pool = self.conn.storagePoolLookupByName("volumes") - vol = pool.storageVolLookupByName(request.volume_id) - - domain_dict = xmltodict.parse(domain.XMLDesc()) - disks = domain_dict["domain"]["devices"]["disk"] - - volumes_ids = [ - d["alias"]["@name"][3:] - for d in disks - if d["@device"] == "disk" and d["alias"]["@name"].startswith("ua-") - ] - - if request.volume_id in volumes_ids: - return volume_pb2.VolumeAttachment( - domain_id=request.domain_id, - volume_id=request.volume_id, - disk_address=disk_address(domain, request.volume_id), - ) - - disk_shortnames = [d["target"]["@dev"][-1:] for d in disks] - disk_letter = sorted(set(string.ascii_lowercase).difference(disk_shortnames))[0] - domain.attachDeviceFlags( - f""" - - - - - - """, - libvirt.VIR_DOMAIN_AFFECT_LIVE | libvirt.VIR_DOMAIN_AFFECT_CONFIG, - ) - - return volume_pb2.VolumeAttachment( - domain_id=request.domain_id, - volume_id=request.volume_id, - disk_address=disk_address(domain, request.volume_id), - ) - - def DetachVolume(self, request, context): - domain = self.conn.lookupByUUIDString(request.domain_id) - alias = f"ua-{request.volume_id}" - try: - domain.detachDeviceAlias( - alias, - libvirt.VIR_DOMAIN_AFFECT_LIVE | libvirt.VIR_DOMAIN_AFFECT_CONFIG, - ) - except libvirt.libvirtError as e: - if f"no device found with alias {alias}" not in e.get_error_message(): - raise e - return empty_pb2.Empty() - - def GetPortForwarding(self, request, context): - with self.session_factory() as session: - forwarding = ( - session.execute( - select(PortForwarding).filter( - PortForwarding.protocol == request.protocol, - PortForwarding.source_port == request.source_port, - ) - ) - .scalars() - .one_or_none() - ) - if forwarding is None: - context.set_code(StatusCode.NOT_FOUND) - return empty_pb2.Empty() - return port_forwarding_pb2.PortForwarding( - protocol=forwarding.protocol, - source_port=forwarding.source_port, - target_ip=forwarding.target_ip, - target_port=forwarding.target_port, - ) - - def ListPortForwardings(self, request, context): - with self.session_factory() as session: - fwds = session.execute(select(PortForwarding)).scalars().all() - return port_forwarding_pb2.ListPortForwardingsResponse( - port_forwardings=[ - port_forwarding_pb2.PortForwarding( - protocol=fwd.protocol, - source_port=fwd.source_port, - target_ip=fwd.target_ip, - target_port=fwd.target_port, - ) - for fwd in fwds - ] - ) - - def PutPortForwarding(self, request, context): - f = request.port_forwarding - route = PortForwarding( - protocol=f.protocol, - source_port=f.source_port, - target_ip=f.target_ip, - target_port=f.target_port, - ) - - with self.session_factory() as session: - session.merge(route) - session.commit() - self.port_fwd_sync_handler.handle_sync(session, self.conn) - - return f - - def DeletePortForwarding(self, request, context): - with self.session_factory() as session: - session.execute( - delete(PortForwarding).where( - PortForwarding.protocol == request.protocol, - PortForwarding.source_port == request.source_port, - ) - ) - session.commit() - self.port_fwd_sync_handler.handle_sync(session, self.conn) - - return empty_pb2.Empty() - - def sync(self): - with self.session_factory() as session: - self.port_fwd_sync_handler.handle_sync(session, self.conn) - - def SyncRoutes(self, request, context): - self.tables_synchronizer.handle_sync(self.controller) - self.routes_synchronizer.handle_sync(self.controller) - return empty_pb2.Empty() diff --git a/minivirt/daemon_pb2.py b/minivirt/daemon_pb2.py deleted file mode 100644 index 0ce5595..0000000 --- a/minivirt/daemon_pb2.py +++ /dev/null @@ -1,32 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/daemon.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import domain_pb2 as minivirt_dot_domain__pb2 -from minivirt import volume_pb2 as minivirt_dot_volume__pb2 -from minivirt import port_forwarding_pb2 as minivirt_dot_port__forwarding__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15minivirt/daemon.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x15minivirt/domain.proto\x1a\x15minivirt/volume.proto\x1a\x1eminivirt/port_forwarding.proto\"\x13\n\x11SyncRoutesRequest2\x95\x0c\n\rDaemonService\x12,\n\nGetNetwork\x12\x12.GetNetworkRequest\x1a\x08.Network\"\x00\x12=\n\x0cListNetworks\x12\x14.ListNetworksRequest\x1a\x15.ListNetworksResponse\"\x00\x12\x32\n\rCreateNetwork\x12\x15.CreateNetworkRequest\x1a\x08.Network\"\x00\x12@\n\rDeleteNetwork\x12\x15.DeleteNetworkRequest\x1a\x16.google.protobuf.Empty\"\x00\x12<\n\x0bStartDomain\x12\x13.StartDomainRequest\x1a\x16.google.protobuf.Empty\"\x00\x12:\n\nStopDomain\x12\x12.StopDomainRequest\x1a\x16.google.protobuf.Empty\"\x00\x12)\n\tGetDomain\x12\x11.GetDomainRequest\x1a\x07.Domain\"\x00\x12:\n\x0bListDomains\x12\x13.ListDomainsRequest\x1a\x14.ListDomainsResponse\"\x00\x12/\n\x0c\x43reateDomain\x12\x14.CreateDomainRequest\x1a\x07.Domain\"\x00\x12>\n\x0c\x44\x65leteDomain\x12\x14.DeleteDomainRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x37\n\rDownloadImage\x12\x15.DownloadImageRequest\x1a\x0b.ImageChunk\"\x00\x30\x01\x12)\n\tGetVolume\x12\x11.GetVolumeRequest\x1a\x07.Volume\"\x00\x12:\n\x0bListVolumes\x12\x13.ListVolumesRequest\x1a\x14.ListVolumesResponse\"\x00\x12/\n\x0c\x43reateVolume\x12\x14.CreateVolumeRequest\x1a\x07.Volume\"\x00\x12/\n\x0cUpdateVolume\x12\x14.UpdateVolumeRequest\x1a\x07.Volume\"\x00\x12>\n\x0c\x44\x65leteVolume\x12\x14.DeleteVolumeRequest\x1a\x16.google.protobuf.Empty\"\x00\x12X\n\x15ListVolumeAttachments\x12\x1d.ListVolumeAttachmentsRequest\x1a\x1e.ListVolumeAttachmentsResponse\"\x00\x12G\n\x13GetVolumeAttachment\x12\x1b.VolumeAttachmentIdentifier\x1a\x11.VolumeAttachment\"\x00\x12@\n\x0c\x41ttachVolume\x12\x1b.VolumeAttachmentIdentifier\x1a\x11.VolumeAttachment\"\x00\x12\x45\n\x0c\x44\x65tachVolume\x12\x1b.VolumeAttachmentIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12\x41\n\x11GetPortForwarding\x12\x19.PortForwardingIdentifier\x1a\x0f.PortForwarding\"\x00\x12R\n\x13ListPortForwardings\x12\x1b.ListPortForwardingsRequest\x1a\x1c.ListPortForwardingsResponse\"\x00\x12\x41\n\x11PutPortForwarding\x12\x19.PutPortForwardingRequest\x1a\x0f.PortForwarding\"\x00\x12K\n\x14\x44\x65letePortForwarding\x12\x19.PortForwardingIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12:\n\nSyncRoutes\x12\x12.SyncRoutesRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.daemon_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _SYNCROUTESREQUEST._serialized_start=132 - _SYNCROUTESREQUEST._serialized_end=151 - _DAEMONSERVICE._serialized_start=154 - _DAEMONSERVICE._serialized_end=1711 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/daemon_pb2_grpc.py b/minivirt/daemon_pb2_grpc.py deleted file mode 100644 index d202fd5..0000000 --- a/minivirt/daemon_pb2_grpc.py +++ /dev/null @@ -1,862 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import daemon_pb2 as minivirt_dot_daemon__pb2 -from minivirt import domain_pb2 as minivirt_dot_domain__pb2 -from minivirt import port_forwarding_pb2 as minivirt_dot_port__forwarding__pb2 -from minivirt import volume_pb2 as minivirt_dot_volume__pb2 - - -class DaemonServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetNetwork = channel.unary_unary( - '/DaemonService/GetNetwork', - request_serializer=minivirt_dot_domain__pb2.GetNetworkRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Network.FromString, - ) - self.ListNetworks = channel.unary_unary( - '/DaemonService/ListNetworks', - request_serializer=minivirt_dot_domain__pb2.ListNetworksRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ListNetworksResponse.FromString, - ) - self.CreateNetwork = channel.unary_unary( - '/DaemonService/CreateNetwork', - request_serializer=minivirt_dot_domain__pb2.CreateNetworkRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Network.FromString, - ) - self.DeleteNetwork = channel.unary_unary( - '/DaemonService/DeleteNetwork', - request_serializer=minivirt_dot_domain__pb2.DeleteNetworkRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.StartDomain = channel.unary_unary( - '/DaemonService/StartDomain', - request_serializer=minivirt_dot_domain__pb2.StartDomainRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.StopDomain = channel.unary_unary( - '/DaemonService/StopDomain', - request_serializer=minivirt_dot_domain__pb2.StopDomainRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetDomain = channel.unary_unary( - '/DaemonService/GetDomain', - request_serializer=minivirt_dot_domain__pb2.GetDomainRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Domain.FromString, - ) - self.ListDomains = channel.unary_unary( - '/DaemonService/ListDomains', - request_serializer=minivirt_dot_domain__pb2.ListDomainsRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ListDomainsResponse.FromString, - ) - self.CreateDomain = channel.unary_unary( - '/DaemonService/CreateDomain', - request_serializer=minivirt_dot_domain__pb2.CreateDomainRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Domain.FromString, - ) - self.DeleteDomain = channel.unary_unary( - '/DaemonService/DeleteDomain', - request_serializer=minivirt_dot_domain__pb2.DeleteDomainRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.DownloadImage = channel.unary_stream( - '/DaemonService/DownloadImage', - request_serializer=minivirt_dot_domain__pb2.DownloadImageRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ImageChunk.FromString, - ) - self.GetVolume = channel.unary_unary( - '/DaemonService/GetVolume', - request_serializer=minivirt_dot_volume__pb2.GetVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.ListVolumes = channel.unary_unary( - '/DaemonService/ListVolumes', - request_serializer=minivirt_dot_volume__pb2.ListVolumesRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.ListVolumesResponse.FromString, - ) - self.CreateVolume = channel.unary_unary( - '/DaemonService/CreateVolume', - request_serializer=minivirt_dot_volume__pb2.CreateVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.UpdateVolume = channel.unary_unary( - '/DaemonService/UpdateVolume', - request_serializer=minivirt_dot_volume__pb2.UpdateVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.DeleteVolume = channel.unary_unary( - '/DaemonService/DeleteVolume', - request_serializer=minivirt_dot_volume__pb2.DeleteVolumeRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.ListVolumeAttachments = channel.unary_unary( - '/DaemonService/ListVolumeAttachments', - request_serializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.FromString, - ) - self.GetVolumeAttachment = channel.unary_unary( - '/DaemonService/GetVolumeAttachment', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.VolumeAttachment.FromString, - ) - self.AttachVolume = channel.unary_unary( - '/DaemonService/AttachVolume', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.VolumeAttachment.FromString, - ) - self.DetachVolume = channel.unary_unary( - '/DaemonService/DetachVolume', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetPortForwarding = channel.unary_unary( - '/DaemonService/GetPortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - ) - self.ListPortForwardings = channel.unary_unary( - '/DaemonService/ListPortForwardings', - request_serializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.FromString, - ) - self.PutPortForwarding = channel.unary_unary( - '/DaemonService/PutPortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - ) - self.DeletePortForwarding = channel.unary_unary( - '/DaemonService/DeletePortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.SyncRoutes = channel.unary_unary( - '/DaemonService/SyncRoutes', - request_serializer=minivirt_dot_daemon__pb2.SyncRoutesRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - - -class DaemonServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def GetNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListNetworks(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def StartDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def StopDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListDomains(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DownloadImage(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListVolumes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListVolumeAttachments(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetVolumeAttachment(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def AttachVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DetachVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetPortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListPortForwardings(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutPortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeletePortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def SyncRoutes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_DaemonServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetNetwork': grpc.unary_unary_rpc_method_handler( - servicer.GetNetwork, - request_deserializer=minivirt_dot_domain__pb2.GetNetworkRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Network.SerializeToString, - ), - 'ListNetworks': grpc.unary_unary_rpc_method_handler( - servicer.ListNetworks, - request_deserializer=minivirt_dot_domain__pb2.ListNetworksRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ListNetworksResponse.SerializeToString, - ), - 'CreateNetwork': grpc.unary_unary_rpc_method_handler( - servicer.CreateNetwork, - request_deserializer=minivirt_dot_domain__pb2.CreateNetworkRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Network.SerializeToString, - ), - 'DeleteNetwork': grpc.unary_unary_rpc_method_handler( - servicer.DeleteNetwork, - request_deserializer=minivirt_dot_domain__pb2.DeleteNetworkRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'StartDomain': grpc.unary_unary_rpc_method_handler( - servicer.StartDomain, - request_deserializer=minivirt_dot_domain__pb2.StartDomainRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'StopDomain': grpc.unary_unary_rpc_method_handler( - servicer.StopDomain, - request_deserializer=minivirt_dot_domain__pb2.StopDomainRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetDomain': grpc.unary_unary_rpc_method_handler( - servicer.GetDomain, - request_deserializer=minivirt_dot_domain__pb2.GetDomainRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Domain.SerializeToString, - ), - 'ListDomains': grpc.unary_unary_rpc_method_handler( - servicer.ListDomains, - request_deserializer=minivirt_dot_domain__pb2.ListDomainsRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ListDomainsResponse.SerializeToString, - ), - 'CreateDomain': grpc.unary_unary_rpc_method_handler( - servicer.CreateDomain, - request_deserializer=minivirt_dot_domain__pb2.CreateDomainRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Domain.SerializeToString, - ), - 'DeleteDomain': grpc.unary_unary_rpc_method_handler( - servicer.DeleteDomain, - request_deserializer=minivirt_dot_domain__pb2.DeleteDomainRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'DownloadImage': grpc.unary_stream_rpc_method_handler( - servicer.DownloadImage, - request_deserializer=minivirt_dot_domain__pb2.DownloadImageRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ImageChunk.SerializeToString, - ), - 'GetVolume': grpc.unary_unary_rpc_method_handler( - servicer.GetVolume, - request_deserializer=minivirt_dot_volume__pb2.GetVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'ListVolumes': grpc.unary_unary_rpc_method_handler( - servicer.ListVolumes, - request_deserializer=minivirt_dot_volume__pb2.ListVolumesRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.ListVolumesResponse.SerializeToString, - ), - 'CreateVolume': grpc.unary_unary_rpc_method_handler( - servicer.CreateVolume, - request_deserializer=minivirt_dot_volume__pb2.CreateVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'UpdateVolume': grpc.unary_unary_rpc_method_handler( - servicer.UpdateVolume, - request_deserializer=minivirt_dot_volume__pb2.UpdateVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'DeleteVolume': grpc.unary_unary_rpc_method_handler( - servicer.DeleteVolume, - request_deserializer=minivirt_dot_volume__pb2.DeleteVolumeRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'ListVolumeAttachments': grpc.unary_unary_rpc_method_handler( - servicer.ListVolumeAttachments, - request_deserializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.SerializeToString, - ), - 'GetVolumeAttachment': grpc.unary_unary_rpc_method_handler( - servicer.GetVolumeAttachment, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=minivirt_dot_volume__pb2.VolumeAttachment.SerializeToString, - ), - 'AttachVolume': grpc.unary_unary_rpc_method_handler( - servicer.AttachVolume, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=minivirt_dot_volume__pb2.VolumeAttachment.SerializeToString, - ), - 'DetachVolume': grpc.unary_unary_rpc_method_handler( - servicer.DetachVolume, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetPortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.GetPortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.PortForwarding.SerializeToString, - ), - 'ListPortForwardings': grpc.unary_unary_rpc_method_handler( - servicer.ListPortForwardings, - request_deserializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.SerializeToString, - ), - 'PutPortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.PutPortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.PortForwarding.SerializeToString, - ), - 'DeletePortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.DeletePortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'SyncRoutes': grpc.unary_unary_rpc_method_handler( - servicer.SyncRoutes, - request_deserializer=minivirt_dot_daemon__pb2.SyncRoutesRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'DaemonService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class DaemonService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/GetNetwork', - minivirt_dot_domain__pb2.GetNetworkRequest.SerializeToString, - minivirt_dot_domain__pb2.Network.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListNetworks(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/ListNetworks', - minivirt_dot_domain__pb2.ListNetworksRequest.SerializeToString, - minivirt_dot_domain__pb2.ListNetworksResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/CreateNetwork', - minivirt_dot_domain__pb2.CreateNetworkRequest.SerializeToString, - minivirt_dot_domain__pb2.Network.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/DeleteNetwork', - minivirt_dot_domain__pb2.DeleteNetworkRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def StartDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/StartDomain', - minivirt_dot_domain__pb2.StartDomainRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def StopDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/StopDomain', - minivirt_dot_domain__pb2.StopDomainRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/GetDomain', - minivirt_dot_domain__pb2.GetDomainRequest.SerializeToString, - minivirt_dot_domain__pb2.Domain.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListDomains(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/ListDomains', - minivirt_dot_domain__pb2.ListDomainsRequest.SerializeToString, - minivirt_dot_domain__pb2.ListDomainsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/CreateDomain', - minivirt_dot_domain__pb2.CreateDomainRequest.SerializeToString, - minivirt_dot_domain__pb2.Domain.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/DeleteDomain', - minivirt_dot_domain__pb2.DeleteDomainRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DownloadImage(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_stream(request, target, '/DaemonService/DownloadImage', - minivirt_dot_domain__pb2.DownloadImageRequest.SerializeToString, - minivirt_dot_domain__pb2.ImageChunk.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/GetVolume', - minivirt_dot_volume__pb2.GetVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListVolumes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/ListVolumes', - minivirt_dot_volume__pb2.ListVolumesRequest.SerializeToString, - minivirt_dot_volume__pb2.ListVolumesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/CreateVolume', - minivirt_dot_volume__pb2.CreateVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def UpdateVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/UpdateVolume', - minivirt_dot_volume__pb2.UpdateVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/DeleteVolume', - minivirt_dot_volume__pb2.DeleteVolumeRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListVolumeAttachments(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/ListVolumeAttachments', - minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.SerializeToString, - minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetVolumeAttachment(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/GetVolumeAttachment', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - minivirt_dot_volume__pb2.VolumeAttachment.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def AttachVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/AttachVolume', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - minivirt_dot_volume__pb2.VolumeAttachment.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DetachVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/DetachVolume', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetPortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/GetPortForwarding', - minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListPortForwardings(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/ListPortForwardings', - minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.SerializeToString, - minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutPortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/PutPortForwarding', - minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.SerializeToString, - minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeletePortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/DeletePortForwarding', - minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def SyncRoutes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DaemonService/SyncRoutes', - minivirt_dot_daemon__pb2.SyncRoutesRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/minivirt/dns_controller.py b/minivirt/dns_controller.py deleted file mode 100644 index 119ef39..0000000 --- a/minivirt/dns_controller.py +++ /dev/null @@ -1,104 +0,0 @@ -from dns import resolver -from dnslib import QTYPE, RCODE, RR, copy -from dnslib.server import DNSServer -from sqlalchemy import delete, select - -from minivirt.models import DNSRecord - - -class DNSController: - def __init__(self, session_factory): - self.session_factory = session_factory - self.server = None - - r = resolver.Resolver() - self.upstream = r.nameservers[0] - - def records(self): - with self.session_factory() as session: - return session.execute(select(DNSRecord)).scalars().all() - - def record(self, name, type): - with self.session_factory() as session: - return ( - session.execute( - select(DNSRecord).filter( - DNSRecord.name == name, - DNSRecord.type == type, - ) - ) - .scalars() - .one_or_none() - ) - - def load_zone_list(self): - zone_file = "\n".join( - [f"{f.name} {f.ttl} {f.type} {' '.join(f.records)}" for f in self.records()] - ) - return [(rr.rname, QTYPE[rr.rtype], rr) for rr in RR.fromZone(zone_file)] - - def set(self, record: DNSRecord): - with self.session_factory() as session: - session.merge(record) - session.commit() - - def remove(self, name, type): - with self.session_factory() as session: - session.execute( - delete(DNSRecord).where( - DNSRecord.name == name, - DNSRecord.type == type, - ) - ) - session.commit() - - def resolve(self, request, handler): - zone = self.load_zone_list() - - reply = None - qname = request.q.qname - qtype = QTYPE[request.q.qtype] - for name, rtype, rr in zone: - # Check if label & type match - if qname.matchGlob(name): - reply = request.reply() - if qtype == rtype or qtype == "ANY" or rtype == "CNAME": - # Since we have a glob match fix reply label - a = copy.copy(rr) - a.rname = qname - reply.add_answer(a) - # Check for A/AAAA records associated with reply and - # add in additional section - if rtype in ["CNAME", "NS", "MX", "PTR"]: - for a_name, a_rtype, a_rr in zone: - if a_name == rr.rdata.label and a_rtype in ["A", "AAAA"]: - reply.add_answer(a_rr) - - if reply is None: - # check for zone delegation - for name, rtype, rr in zone: - if rtype == "NS" and qname.matchSuffix(name): - if reply is None: - reply = request.reply() - reply.add_auth(copy.copy(rr)) - - if reply is None: - # try: - # reply = dnslib.DNSRecord.parse(request.send(self.upstream, 53, timeout=3)) - # except socket.timeout: - # reply.header.rcode = RCODE.SERVFAIL - reply = request.reply() - reply.header.rcode = RCODE.NXDOMAIN - reply.header.ra = False # we don't support recursion - return reply - - def start(self, port=53): - self.server = DNSServer(self, port=port) - self.server.start_thread() - return self.server.server.server_address[1] - - def stop(self): - if self.server is not None: - self.server.stop() - self.server.server.server_close() - self.server = None diff --git a/minivirt/dns_pb2.py b/minivirt/dns_pb2.py deleted file mode 100644 index ed12e7f..0000000 --- a/minivirt/dns_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/dns.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x12minivirt/dns.proto\x1a\x1bgoogle/protobuf/empty.proto\"1\n\x13\x44NSRecordIdentifier\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\"E\n\tDNSRecord\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0c\n\x04type\x18\x02 \x01(\t\x12\x0b\n\x03ttl\x18\x03 \x01(\x04\x12\x0f\n\x07records\x18\x04 \x03(\t\"\x17\n\x15ListDNSRecordsRequest\"9\n\x16ListDNSRecordsResponse\x12\x1f\n\x0b\x64ns_records\x18\x01 \x03(\x0b\x32\n.DNSRecord\"5\n\x13PutDNSRecordRequest\x12\x1e\n\ndns_record\x18\x01 \x01(\x0b\x32\n.DNSRecord2\xf5\x01\n\x03\x44NS\x12\x32\n\x0cGetDNSRecord\x12\x14.DNSRecordIdentifier\x1a\n.DNSRecord\"\x00\x12\x43\n\x0eListDNSRecords\x12\x16.ListDNSRecordsRequest\x1a\x17.ListDNSRecordsResponse\"\x00\x12\x32\n\x0cPutDNSRecord\x12\x14.PutDNSRecordRequest\x1a\n.DNSRecord\"\x00\x12\x41\n\x0f\x44\x65leteDNSRecord\x12\x14.DNSRecordIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.dns_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _DNSRECORDIDENTIFIER._serialized_start=51 - _DNSRECORDIDENTIFIER._serialized_end=100 - _DNSRECORD._serialized_start=102 - _DNSRECORD._serialized_end=171 - _LISTDNSRECORDSREQUEST._serialized_start=173 - _LISTDNSRECORDSREQUEST._serialized_end=196 - _LISTDNSRECORDSRESPONSE._serialized_start=198 - _LISTDNSRECORDSRESPONSE._serialized_end=255 - _PUTDNSRECORDREQUEST._serialized_start=257 - _PUTDNSRECORDREQUEST._serialized_end=310 - _DNS._serialized_start=313 - _DNS._serialized_end=558 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/dns_pb2_grpc.py b/minivirt/dns_pb2_grpc.py deleted file mode 100644 index 727efe5..0000000 --- a/minivirt/dns_pb2_grpc.py +++ /dev/null @@ -1,166 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import dns_pb2 as minivirt_dot_dns__pb2 - - -class DNSStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetDNSRecord = channel.unary_unary( - '/DNS/GetDNSRecord', - request_serializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - response_deserializer=minivirt_dot_dns__pb2.DNSRecord.FromString, - ) - self.ListDNSRecords = channel.unary_unary( - '/DNS/ListDNSRecords', - request_serializer=minivirt_dot_dns__pb2.ListDNSRecordsRequest.SerializeToString, - response_deserializer=minivirt_dot_dns__pb2.ListDNSRecordsResponse.FromString, - ) - self.PutDNSRecord = channel.unary_unary( - '/DNS/PutDNSRecord', - request_serializer=minivirt_dot_dns__pb2.PutDNSRecordRequest.SerializeToString, - response_deserializer=minivirt_dot_dns__pb2.DNSRecord.FromString, - ) - self.DeleteDNSRecord = channel.unary_unary( - '/DNS/DeleteDNSRecord', - request_serializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - - -class DNSServicer(object): - """Missing associated documentation comment in .proto file.""" - - def GetDNSRecord(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListDNSRecords(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutDNSRecord(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteDNSRecord(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_DNSServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetDNSRecord': grpc.unary_unary_rpc_method_handler( - servicer.GetDNSRecord, - request_deserializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.FromString, - response_serializer=minivirt_dot_dns__pb2.DNSRecord.SerializeToString, - ), - 'ListDNSRecords': grpc.unary_unary_rpc_method_handler( - servicer.ListDNSRecords, - request_deserializer=minivirt_dot_dns__pb2.ListDNSRecordsRequest.FromString, - response_serializer=minivirt_dot_dns__pb2.ListDNSRecordsResponse.SerializeToString, - ), - 'PutDNSRecord': grpc.unary_unary_rpc_method_handler( - servicer.PutDNSRecord, - request_deserializer=minivirt_dot_dns__pb2.PutDNSRecordRequest.FromString, - response_serializer=minivirt_dot_dns__pb2.DNSRecord.SerializeToString, - ), - 'DeleteDNSRecord': grpc.unary_unary_rpc_method_handler( - servicer.DeleteDNSRecord, - request_deserializer=minivirt_dot_dns__pb2.DNSRecordIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'DNS', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class DNS(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetDNSRecord(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DNS/GetDNSRecord', - minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - minivirt_dot_dns__pb2.DNSRecord.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListDNSRecords(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DNS/ListDNSRecords', - minivirt_dot_dns__pb2.ListDNSRecordsRequest.SerializeToString, - minivirt_dot_dns__pb2.ListDNSRecordsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutDNSRecord(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DNS/PutDNSRecord', - minivirt_dot_dns__pb2.PutDNSRecordRequest.SerializeToString, - minivirt_dot_dns__pb2.DNSRecord.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteDNSRecord(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DNS/DeleteDNSRecord', - minivirt_dot_dns__pb2.DNSRecordIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/minivirt/domain_pb2.py b/minivirt/domain_pb2.py deleted file mode 100644 index 8f041ec..0000000 --- a/minivirt/domain_pb2.py +++ /dev/null @@ -1,60 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/domain.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15minivirt/domain.proto\x1a\x1bgoogle/protobuf/empty.proto\x1a\x1fgoogle/protobuf/timestamp.proto\"0\n\x12StartDomainRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04uuid\x18\x02 \x01(\t\">\n\x11StopDomainRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x0c\n\x04uuid\x18\x02 \x01(\t\x12\r\n\x05\x66orce\x18\x03 \x01(\x08\".\n\x10GetDomainRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\"\xaf\x02\n\x06\x44omain\x12\n\n\x02id\x18\x01 \x01(\x04\x12\x0c\n\x04uuid\x18\x02 \x01(\t\x12\x0c\n\x04name\x18\x03 \x01(\t\x12\x0c\n\x04vcpu\x18\x04 \x01(\r\x12\x0e\n\x06memory\x18\x05 \x01(\x04\x12\x0f\n\x07network\x18\x06 \x01(\t\x12\x0e\n\x06\x62ridge\x18\x07 \x01(\t\x12\r\n\x05state\x18\x08 \x01(\t\x12\x12\n\nprivate_ip\x18\t \x01(\t\x12\x14\n\x0cipv6_address\x18\x0f \x01(\t\x12\x11\n\tuser_data\x18\n \x01(\t\x12\x1d\n\x15nested_virtualization\x18\x0b \x01(\x08\x12\x12\n\nbase_image\x18\x0c \x01(\t\x12.\n\ncreated_at\x18\r \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0f\n\x07os_type\x18\x0e \x01(\t\"\"\n\x12ListDomainsRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\"/\n\x13ListDomainsResponse\x12\x18\n\x07\x64omains\x18\x01 \x03(\x0b\x32\x07.Domain\"<\n\x13\x43reateDomainRequest\x12\x17\n\x06\x64omain\x18\x01 \x01(\x0b\x32\x07.Domain\x12\x0c\n\x04host\x18\x02 \x01(\t\"1\n\x13\x44\x65leteDomainRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\"7\n\x14\x44ownloadImageRequest\x12\x11\n\tdomain_id\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\"\x1b\n\nImageChunk\x12\r\n\x05\x62ytes\x18\x01 \x01(\x0c\"/\n\x11GetNetworkRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\"B\n\x07Network\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04\x63idr\x18\x03 \x01(\t\x12\r\n\x05\x63idr6\x18\x04 \x01(\t\"#\n\x13ListNetworksRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\"2\n\x14ListNetworksResponse\x12\x1a\n\x08networks\x18\x01 \x03(\x0b\x32\x08.Network\"?\n\x14\x43reateNetworkRequest\x12\x19\n\x07network\x18\x01 \x01(\x0b\x32\x08.Network\x12\x0c\n\x04host\x18\x02 \x01(\t\"2\n\x14\x44\x65leteNetworkRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t2\x83\x04\n\rDomainService\x12)\n\tGetDomain\x12\x11.GetDomainRequest\x1a\x07.Domain\"\x00\x12:\n\x0bListDomains\x12\x13.ListDomainsRequest\x1a\x14.ListDomainsResponse\"\x00\x12/\n\x0c\x43reateDomain\x12\x14.CreateDomainRequest\x1a\x07.Domain\"\x00\x12>\n\x0c\x44\x65leteDomain\x12\x14.DeleteDomainRequest\x1a\x16.google.protobuf.Empty\"\x00\x12\x37\n\rDownloadImage\x12\x15.DownloadImageRequest\x1a\x0b.ImageChunk\"\x00\x30\x01\x12,\n\nGetNetwork\x12\x12.GetNetworkRequest\x1a\x08.Network\"\x00\x12=\n\x0cListNetworks\x12\x14.ListNetworksRequest\x1a\x15.ListNetworksResponse\"\x00\x12\x32\n\rCreateNetwork\x12\x15.CreateNetworkRequest\x1a\x08.Network\"\x00\x12@\n\rDeleteNetwork\x12\x15.DeleteNetworkRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.domain_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _STARTDOMAINREQUEST._serialized_start=87 - _STARTDOMAINREQUEST._serialized_end=135 - _STOPDOMAINREQUEST._serialized_start=137 - _STOPDOMAINREQUEST._serialized_end=199 - _GETDOMAINREQUEST._serialized_start=201 - _GETDOMAINREQUEST._serialized_end=247 - _DOMAIN._serialized_start=250 - _DOMAIN._serialized_end=553 - _LISTDOMAINSREQUEST._serialized_start=555 - _LISTDOMAINSREQUEST._serialized_end=589 - _LISTDOMAINSRESPONSE._serialized_start=591 - _LISTDOMAINSRESPONSE._serialized_end=638 - _CREATEDOMAINREQUEST._serialized_start=640 - _CREATEDOMAINREQUEST._serialized_end=700 - _DELETEDOMAINREQUEST._serialized_start=702 - _DELETEDOMAINREQUEST._serialized_end=751 - _DOWNLOADIMAGEREQUEST._serialized_start=753 - _DOWNLOADIMAGEREQUEST._serialized_end=808 - _IMAGECHUNK._serialized_start=810 - _IMAGECHUNK._serialized_end=837 - _GETNETWORKREQUEST._serialized_start=839 - _GETNETWORKREQUEST._serialized_end=886 - _NETWORK._serialized_start=888 - _NETWORK._serialized_end=954 - _LISTNETWORKSREQUEST._serialized_start=956 - _LISTNETWORKSREQUEST._serialized_end=991 - _LISTNETWORKSRESPONSE._serialized_start=993 - _LISTNETWORKSRESPONSE._serialized_end=1043 - _CREATENETWORKREQUEST._serialized_start=1045 - _CREATENETWORKREQUEST._serialized_end=1108 - _DELETENETWORKREQUEST._serialized_start=1110 - _DELETENETWORKREQUEST._serialized_end=1160 - _DOMAINSERVICE._serialized_start=1163 - _DOMAINSERVICE._serialized_end=1678 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/domain_pb2_grpc.py b/minivirt/domain_pb2_grpc.py deleted file mode 100644 index 04e622a..0000000 --- a/minivirt/domain_pb2_grpc.py +++ /dev/null @@ -1,331 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import domain_pb2 as minivirt_dot_domain__pb2 - - -class DomainServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetDomain = channel.unary_unary( - '/DomainService/GetDomain', - request_serializer=minivirt_dot_domain__pb2.GetDomainRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Domain.FromString, - ) - self.ListDomains = channel.unary_unary( - '/DomainService/ListDomains', - request_serializer=minivirt_dot_domain__pb2.ListDomainsRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ListDomainsResponse.FromString, - ) - self.CreateDomain = channel.unary_unary( - '/DomainService/CreateDomain', - request_serializer=minivirt_dot_domain__pb2.CreateDomainRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Domain.FromString, - ) - self.DeleteDomain = channel.unary_unary( - '/DomainService/DeleteDomain', - request_serializer=minivirt_dot_domain__pb2.DeleteDomainRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.DownloadImage = channel.unary_stream( - '/DomainService/DownloadImage', - request_serializer=minivirt_dot_domain__pb2.DownloadImageRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ImageChunk.FromString, - ) - self.GetNetwork = channel.unary_unary( - '/DomainService/GetNetwork', - request_serializer=minivirt_dot_domain__pb2.GetNetworkRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Network.FromString, - ) - self.ListNetworks = channel.unary_unary( - '/DomainService/ListNetworks', - request_serializer=minivirt_dot_domain__pb2.ListNetworksRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.ListNetworksResponse.FromString, - ) - self.CreateNetwork = channel.unary_unary( - '/DomainService/CreateNetwork', - request_serializer=minivirt_dot_domain__pb2.CreateNetworkRequest.SerializeToString, - response_deserializer=minivirt_dot_domain__pb2.Network.FromString, - ) - self.DeleteNetwork = channel.unary_unary( - '/DomainService/DeleteNetwork', - request_serializer=minivirt_dot_domain__pb2.DeleteNetworkRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - - -class DomainServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def GetDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListDomains(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteDomain(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DownloadImage(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListNetworks(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteNetwork(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_DomainServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetDomain': grpc.unary_unary_rpc_method_handler( - servicer.GetDomain, - request_deserializer=minivirt_dot_domain__pb2.GetDomainRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Domain.SerializeToString, - ), - 'ListDomains': grpc.unary_unary_rpc_method_handler( - servicer.ListDomains, - request_deserializer=minivirt_dot_domain__pb2.ListDomainsRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ListDomainsResponse.SerializeToString, - ), - 'CreateDomain': grpc.unary_unary_rpc_method_handler( - servicer.CreateDomain, - request_deserializer=minivirt_dot_domain__pb2.CreateDomainRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Domain.SerializeToString, - ), - 'DeleteDomain': grpc.unary_unary_rpc_method_handler( - servicer.DeleteDomain, - request_deserializer=minivirt_dot_domain__pb2.DeleteDomainRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'DownloadImage': grpc.unary_stream_rpc_method_handler( - servicer.DownloadImage, - request_deserializer=minivirt_dot_domain__pb2.DownloadImageRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ImageChunk.SerializeToString, - ), - 'GetNetwork': grpc.unary_unary_rpc_method_handler( - servicer.GetNetwork, - request_deserializer=minivirt_dot_domain__pb2.GetNetworkRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Network.SerializeToString, - ), - 'ListNetworks': grpc.unary_unary_rpc_method_handler( - servicer.ListNetworks, - request_deserializer=minivirt_dot_domain__pb2.ListNetworksRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.ListNetworksResponse.SerializeToString, - ), - 'CreateNetwork': grpc.unary_unary_rpc_method_handler( - servicer.CreateNetwork, - request_deserializer=minivirt_dot_domain__pb2.CreateNetworkRequest.FromString, - response_serializer=minivirt_dot_domain__pb2.Network.SerializeToString, - ), - 'DeleteNetwork': grpc.unary_unary_rpc_method_handler( - servicer.DeleteNetwork, - request_deserializer=minivirt_dot_domain__pb2.DeleteNetworkRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'DomainService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class DomainService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/GetDomain', - minivirt_dot_domain__pb2.GetDomainRequest.SerializeToString, - minivirt_dot_domain__pb2.Domain.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListDomains(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/ListDomains', - minivirt_dot_domain__pb2.ListDomainsRequest.SerializeToString, - minivirt_dot_domain__pb2.ListDomainsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/CreateDomain', - minivirt_dot_domain__pb2.CreateDomainRequest.SerializeToString, - minivirt_dot_domain__pb2.Domain.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteDomain(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/DeleteDomain', - minivirt_dot_domain__pb2.DeleteDomainRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DownloadImage(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_stream(request, target, '/DomainService/DownloadImage', - minivirt_dot_domain__pb2.DownloadImageRequest.SerializeToString, - minivirt_dot_domain__pb2.ImageChunk.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/GetNetwork', - minivirt_dot_domain__pb2.GetNetworkRequest.SerializeToString, - minivirt_dot_domain__pb2.Network.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListNetworks(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/ListNetworks', - minivirt_dot_domain__pb2.ListNetworksRequest.SerializeToString, - minivirt_dot_domain__pb2.ListNetworksResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/CreateNetwork', - minivirt_dot_domain__pb2.CreateNetworkRequest.SerializeToString, - minivirt_dot_domain__pb2.Network.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteNetwork(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/DomainService/DeleteNetwork', - minivirt_dot_domain__pb2.DeleteNetworkRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/minivirt/host.py b/minivirt/host.py deleted file mode 100644 index c5a317c..0000000 --- a/minivirt/host.py +++ /dev/null @@ -1,126 +0,0 @@ -import threading -import uuid -from datetime import datetime, timedelta - -import grpc -from google.protobuf import empty_pb2 -from grpc import StatusCode -from sqlalchemy import select - -from minivirt import host_pb2, host_pb2_grpc -from minivirt.models import BootstrapToken, Host - - -class HostController: - def __init__(self, session_factory, creds=None): - self.session_factory = session_factory - self.creds = creds - self.lock = threading.Lock() - self.cache = {} - - for host in self.hosts(): - self.cache[host.name] = self._create_channel(host.address) - - def _create_channel(self, address): - if self.creds is not None: - return grpc.secure_channel(address, self.creds) - return grpc.insecure_channel(address) - - def hosts(self): - with self.session_factory() as session: - return session.execute(select(Host)).scalars().all() - - def host(self, name): - with self.session_factory.begin() as session: - return session.get(Host, name) - - def channel(self, hostname): - with self.lock: - return self.cache.get(hostname) - - def channels(self): - with self.lock: - return list(self.cache.values()) - - def register(self, token, hostname, address): - with self.session_factory.begin() as session: - token = session.get(BootstrapToken, token) - if token is None or token.expires_at <= datetime.utcnow(): - raise Exception("BootstrapToken invalid") - session.add(Host(name=hostname, address=address)) - with self.lock: - self.cache[hostname] = self._create_channel(address) - return empty_pb2.Empty() - - def deregister(self, hostname): - with self.session_factory.begin() as session: - host = session.get(Host, hostname) - if host is None: - raise Exception("Host not found") - session.delete(host) - with self.lock: - del self.cache[hostname] - - -class HostService(host_pb2_grpc.HostServiceServicer): - def __init__(self, host_controller: HostController, session_factory): - self.session_factory = session_factory - self.host_controller = host_controller - - def CreateBootstrapToken(self, request, context): - with self.session_factory.begin() as session: - if not request.expires_at: - expires_at = datetime.utcnow() + timedelta(minutes=10) - else: - expires_at = datetime.fromisoformat(request.expires_at) - token = BootstrapToken( - token=str(uuid.uuid4()), - expires_at=expires_at, - ) - session.add(token) - return host_pb2.CreateBootstrapTokenResponse(token=token.token) - - def GetHost(self, request, context): - host = self.host_controller.host(request.name) - if host is None: - context.set_code(StatusCode.NOT_FOUND) - context.set_details("Host not found") - return - return host_pb2.Host(name=host.name, address=host.address) - - def ListHosts(self, request, context): - hosts = self.host_controller.hosts() - hosts = [host_pb2.Host(name=h.name, address=h.address) for h in hosts] - return host_pb2.ListHostsResponse(hosts=hosts) - - def Register(self, request, context): - try: - self.host_controller.register(request.token, request.host.name, request.host.address) - return empty_pb2.Empty() - except Exception as e: - if "BootstrapToken invalid" in str(e): - context.set_code(StatusCode.INVALID_ARGUMENT) - context.set_details("BootstrapToken invalid") - return - raise e - - def Deregister(self, request, context): - try: - self.host_controller.deregister(request.name) - return empty_pb2.Empty() - except Exception as e: - if "Host not found" in str(e): - context.set_code(StatusCode.NOT_FOUND) - context.set_details("Host not found") - return - raise e - - def Heartbeat(self, request, context): - with self.session_factory.begin() as session: - host = session.get(Host, request.host.name) - if host is None: - context.set_code(StatusCode.NOT_FOUND) - context.set_details("Host not found") - return - host.last_heartbeat = datetime.utcnow() - return host_pb2.HeartbeatResponse() diff --git a/minivirt/host_pb2.py b/minivirt/host_pb2.py deleted file mode 100644 index 22c7fd5..0000000 --- a/minivirt/host_pb2.py +++ /dev/null @@ -1,43 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/host.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x13minivirt/host.proto\x1a\x1bgoogle/protobuf/empty.proto\"1\n\x1b\x43reateBootstrapTokenRequest\x12\x12\n\nexpires_at\x18\x01 \x01(\t\"-\n\x1c\x43reateBootstrapTokenResponse\x12\r\n\x05token\x18\x01 \x01(\t\"%\n\x04Host\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x0f\n\x07\x61\x64\x64ress\x18\x02 \x01(\t\"\x12\n\x10ListHostsRequest\")\n\x11ListHostsResponse\x12\x14\n\x05hosts\x18\x01 \x03(\x0b\x32\x05.Host\"9\n\x13RegisterHostRequest\x12\x13\n\x04host\x18\x01 \x01(\x0b\x32\x05.Host\x12\r\n\x05token\x18\x02 \x01(\t\"\'\n\x10HeartbeatRequest\x12\x13\n\x04host\x18\x01 \x01(\x0b\x32\x05.Host\"\x13\n\x11HeartbeatResponse2\xc5\x02\n\x0bHostService\x12U\n\x14\x43reateBootstrapToken\x12\x1c.CreateBootstrapTokenRequest\x1a\x1d.CreateBootstrapTokenResponse\"\x00\x12\x19\n\x07GetHost\x12\x05.Host\x1a\x05.Host\"\x00\x12\x34\n\tListHosts\x12\x11.ListHostsRequest\x1a\x12.ListHostsResponse\"\x00\x12)\n\x08Register\x12\x14.RegisterHostRequest\x1a\x05.Host\"\x00\x12-\n\nDeregister\x12\x05.Host\x1a\x16.google.protobuf.Empty\"\x00\x12\x34\n\tHeartbeat\x12\x11.HeartbeatRequest\x1a\x12.HeartbeatResponse\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.host_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _CREATEBOOTSTRAPTOKENREQUEST._serialized_start=52 - _CREATEBOOTSTRAPTOKENREQUEST._serialized_end=101 - _CREATEBOOTSTRAPTOKENRESPONSE._serialized_start=103 - _CREATEBOOTSTRAPTOKENRESPONSE._serialized_end=148 - _HOST._serialized_start=150 - _HOST._serialized_end=187 - _LISTHOSTSREQUEST._serialized_start=189 - _LISTHOSTSREQUEST._serialized_end=207 - _LISTHOSTSRESPONSE._serialized_start=209 - _LISTHOSTSRESPONSE._serialized_end=250 - _REGISTERHOSTREQUEST._serialized_start=252 - _REGISTERHOSTREQUEST._serialized_end=309 - _HEARTBEATREQUEST._serialized_start=311 - _HEARTBEATREQUEST._serialized_end=350 - _HEARTBEATRESPONSE._serialized_start=352 - _HEARTBEATRESPONSE._serialized_end=371 - _HOSTSERVICE._serialized_start=374 - _HOSTSERVICE._serialized_end=699 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/host_pb2_grpc.py b/minivirt/host_pb2_grpc.py deleted file mode 100644 index ec74a36..0000000 --- a/minivirt/host_pb2_grpc.py +++ /dev/null @@ -1,232 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import host_pb2 as minivirt_dot_host__pb2 - - -class HostServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.CreateBootstrapToken = channel.unary_unary( - '/HostService/CreateBootstrapToken', - request_serializer=minivirt_dot_host__pb2.CreateBootstrapTokenRequest.SerializeToString, - response_deserializer=minivirt_dot_host__pb2.CreateBootstrapTokenResponse.FromString, - ) - self.GetHost = channel.unary_unary( - '/HostService/GetHost', - request_serializer=minivirt_dot_host__pb2.Host.SerializeToString, - response_deserializer=minivirt_dot_host__pb2.Host.FromString, - ) - self.ListHosts = channel.unary_unary( - '/HostService/ListHosts', - request_serializer=minivirt_dot_host__pb2.ListHostsRequest.SerializeToString, - response_deserializer=minivirt_dot_host__pb2.ListHostsResponse.FromString, - ) - self.Register = channel.unary_unary( - '/HostService/Register', - request_serializer=minivirt_dot_host__pb2.RegisterHostRequest.SerializeToString, - response_deserializer=minivirt_dot_host__pb2.Host.FromString, - ) - self.Deregister = channel.unary_unary( - '/HostService/Deregister', - request_serializer=minivirt_dot_host__pb2.Host.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.Heartbeat = channel.unary_unary( - '/HostService/Heartbeat', - request_serializer=minivirt_dot_host__pb2.HeartbeatRequest.SerializeToString, - response_deserializer=minivirt_dot_host__pb2.HeartbeatResponse.FromString, - ) - - -class HostServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def CreateBootstrapToken(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetHost(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListHosts(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Register(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Deregister(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Heartbeat(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_HostServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'CreateBootstrapToken': grpc.unary_unary_rpc_method_handler( - servicer.CreateBootstrapToken, - request_deserializer=minivirt_dot_host__pb2.CreateBootstrapTokenRequest.FromString, - response_serializer=minivirt_dot_host__pb2.CreateBootstrapTokenResponse.SerializeToString, - ), - 'GetHost': grpc.unary_unary_rpc_method_handler( - servicer.GetHost, - request_deserializer=minivirt_dot_host__pb2.Host.FromString, - response_serializer=minivirt_dot_host__pb2.Host.SerializeToString, - ), - 'ListHosts': grpc.unary_unary_rpc_method_handler( - servicer.ListHosts, - request_deserializer=minivirt_dot_host__pb2.ListHostsRequest.FromString, - response_serializer=minivirt_dot_host__pb2.ListHostsResponse.SerializeToString, - ), - 'Register': grpc.unary_unary_rpc_method_handler( - servicer.Register, - request_deserializer=minivirt_dot_host__pb2.RegisterHostRequest.FromString, - response_serializer=minivirt_dot_host__pb2.Host.SerializeToString, - ), - 'Deregister': grpc.unary_unary_rpc_method_handler( - servicer.Deregister, - request_deserializer=minivirt_dot_host__pb2.Host.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'Heartbeat': grpc.unary_unary_rpc_method_handler( - servicer.Heartbeat, - request_deserializer=minivirt_dot_host__pb2.HeartbeatRequest.FromString, - response_serializer=minivirt_dot_host__pb2.HeartbeatResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'HostService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class HostService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def CreateBootstrapToken(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/HostService/CreateBootstrapToken', - minivirt_dot_host__pb2.CreateBootstrapTokenRequest.SerializeToString, - minivirt_dot_host__pb2.CreateBootstrapTokenResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetHost(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/HostService/GetHost', - minivirt_dot_host__pb2.Host.SerializeToString, - minivirt_dot_host__pb2.Host.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListHosts(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/HostService/ListHosts', - minivirt_dot_host__pb2.ListHostsRequest.SerializeToString, - minivirt_dot_host__pb2.ListHostsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Register(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/HostService/Register', - minivirt_dot_host__pb2.RegisterHostRequest.SerializeToString, - minivirt_dot_host__pb2.Host.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Deregister(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/HostService/Deregister', - minivirt_dot_host__pb2.Host.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Heartbeat(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/HostService/Heartbeat', - minivirt_dot_host__pb2.HeartbeatRequest.SerializeToString, - minivirt_dot_host__pb2.HeartbeatResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/minivirt/image.py b/minivirt/image.py deleted file mode 100644 index 436512a..0000000 --- a/minivirt/image.py +++ /dev/null @@ -1,91 +0,0 @@ -from io import BytesIO - -import pycdlib -import yaml - - -def _read_from_cloud_config_file(data, section): - section_data = BytesIO() - iso = pycdlib.PyCdlib() - iso.open_fp(BytesIO(data)) - iso.get_file_from_iso_fp(section_data, joliet_path=section) - iso.close() - return section_data.getvalue().decode() - - -def read_user_data_from_cloud_config_image(data): - return _read_from_cloud_config_file(data, "/user-data") - - -def read_ip_from_cloud_config_image(data): - network_config = _read_from_cloud_config_file(data, "/network-config") - network_config_dict = yaml.safe_load(network_config) - cidr = network_config_dict["ethernets"]["primary"]["addresses"][0] - ip, prefix = cidr.split("/") - return ip - - -def create_cloud_config_image( - domain_id, user_data, mac, network, network6, address, address6, gateway, gateway6, name -): - assert gateway in network - assert address in network - - if network6 is not None: - assert gateway6 in network6 - assert address6 in network6 - - network_config = f"""version: 2 -ethernets: - primary: - match: - macaddress: "{mac}" - set-name: "ens2" - dhcp4: false - dhcp6: false - # default libvirt network - addresses: - - {address}/{network.prefixlen} - {f"- {address6}/{network6.prefixlen}" if address6 is not None else ""} - gateway4: {gateway} - {f"gateway6: {gateway6}" if gateway6 is not None else ""} - nameservers: - addresses: - - {gateway} - {f"- {gateway6}" if gateway6 is not None else ""} -""" - - meta_config = f"""instance-id: {domain_id} -local-hostname: {name} -""" - - iso = pycdlib.PyCdlib() - iso.new( - interchange_level=3, - joliet=3, - rock_ridge="1.09", - vol_ident="cidata", - sys_ident="LINUX", - ) - - iso_config = { - "network-config": network_config, - "meta-data": meta_config, - "user-data": user_data, - } - - for section_name, data_string in iso_config.items(): - data = data_string.encode() - iso.add_fp( - BytesIO(data), - len(data), - iso_path=f'/{section_name.replace("-", "").upper()}.;1', - rr_name=section_name, - joliet_path=f"/{section_name}", - ) - - result = BytesIO() - iso.write_fp(result) - iso.close() - - return result.getvalue() diff --git a/minivirt/main.py b/minivirt/main.py deleted file mode 100644 index f4e69a8..0000000 --- a/minivirt/main.py +++ /dev/null @@ -1,297 +0,0 @@ -import argparse -import logging -import os -import re -from concurrent import futures - -import grpc -import libvirt -from grpc_reflection.v1alpha import reflection -from sqlalchemy import create_engine, event -from sqlalchemy.engine import Engine -from sqlalchemy.orm import sessionmaker -from sqlalchemy.pool import StaticPool - -from minivirt import ( - controller_pb2_grpc, - daemon_pb2_grpc, - dns_pb2_grpc, - domain_pb2, - domain_pb2_grpc, - host_pb2, - host_pb2_grpc, - port_forwarding_pb2_grpc, - route_pb2_grpc, - volume_pb2_grpc, -) -from minivirt.controller import Controller -from minivirt.daemon import DaemonService -from minivirt.dns_controller import DNSController -from minivirt.host import HostController, HostService -from minivirt.migrations import run_migrations -from minivirt.port_forwarding import IPTablesPortForwardingSynchronizer -from minivirt.utils import UnaryUnaryInterceptor -from minivirt.version import __version__ - -libvirt.registerErrorHandler(lambda u, e: None, None) - - -@event.listens_for(Engine, "connect") -def set_sqlite_pragma(dbapi_connection, connection_record): - cursor = dbapi_connection.cursor() - cursor.execute("PRAGMA foreign_keys=ON") - cursor.close() - - -def start_controller(args): - host, port = args.bind - host = host or "0.0.0.0" - - if args.debug: - logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) - - engine = create_engine( - f"sqlite:///{os.path.join(args.config, 'controller.sqlite3')}", - connect_args={"check_same_thread": False}, - poolclass=StaticPool, - future=True, - ) - run_migrations(engine) - session_factory = sessionmaker(engine, future=True) - - dns_controller = DNSController(session_factory) - dns_controller.start(port=5353) - - server = grpc.server( - futures.ThreadPoolExecutor(max_workers=10), interceptors=[UnaryUnaryInterceptor()] - ) - - creds = read_grpc_creds(args.client_ca_cert, args.server_cert, args.server_key) - - host_controller = HostController(session_factory, to_channel_creds(creds)) - controller = Controller( - session_factory=session_factory, - host_controller=host_controller, - dns_controller=dns_controller, - ) - controller_pb2_grpc.add_ControllerServiceServicer_to_server(controller, server) - dns_pb2_grpc.add_DNSServicer_to_server(controller, server) - domain_pb2_grpc.add_DomainServiceServicer_to_server(controller, server) - port_forwarding_pb2_grpc.add_PortForwardingServiceServicer_to_server(controller, server) - route_pb2_grpc.add_RouteServiceServicer_to_server(controller, server) - volume_pb2_grpc.add_VolumeServiceServicer_to_server(controller, server) - host_pb2_grpc.add_HostServiceServicer_to_server( - HostService(host_controller, session_factory), server - ) - - server.add_secure_port(f"{host}:{port}", to_server_creds(creds)) - reflection.enable_server_reflection( - [ - service_descriptor.full_name - for service_descriptor in domain_pb2.DESCRIPTOR.services_by_name.values() - ] - + [reflection.SERVICE_NAME], - server, - ) - - logging.info(f"Starting Controller ({__version__})") - server.start() - server.wait_for_termination() - - -def read_grpc_creds(ca_cert_path, cert_path, key_path): - with ( - open(ca_cert_path, "rb") as ca_cert, - open(cert_path, "rb") as cert, - open(key_path, "rb") as key, - ): - root_certificate = ca_cert.read() - certificate_chain = cert.read() - private_key = key.read() - - return (root_certificate, certificate_chain, private_key) - - -def to_channel_creds(triple): - (root_certificate, certificate_chain, private_key) = triple - return grpc.ssl_channel_credentials( - root_certificates=root_certificate, - certificate_chain=certificate_chain, - private_key=private_key, - ) - - -def to_server_creds(triple): - (root_certificate, certificate_chain, private_key) = triple - return grpc.ssl_server_credentials( - [(private_key, certificate_chain)], - root_certificates=root_certificate, - require_client_auth=True, - ) - - -def get_controller_channel(args): - controller_host, controller_port = args.controller - client_key_pair_provided = args.client_cert is not None and args.client_key is not None - - assert args.server_ca_cert is not None - assert client_key_pair_provided - - return grpc.secure_channel( - f"{controller_host}:{controller_port}", - to_channel_creds(read_grpc_creds(args.server_ca_cert, args.client_cert, args.client_key)), - ) - - -def start_daemon(args): - addr, port = args.bind - port = port or 0 - addr = addr or "0.0.0.0" - - if args.debug: - logging.getLogger("sqlalchemy.engine").setLevel(logging.INFO) - - engine = create_engine( - f"sqlite:///{os.path.join(args.config, 'daemon.sqlite3')}", - connect_args={"check_same_thread": False}, - poolclass=StaticPool, - future=True, - ) - run_migrations(engine) - session_factory = sessionmaker(engine, future=True) - - daemon = grpc.server( - futures.ThreadPoolExecutor(max_workers=10), interceptors=[UnaryUnaryInterceptor()] - ) - daemon.add_secure_port( - f"{addr}:{port}", - to_server_creds(read_grpc_creds(args.server_ca_cert, args.client_cert, args.client_key)), - ) - - controller_channel = get_controller_channel(args) - - daemon_service = DaemonService( - session_factory, - IPTablesPortForwardingSynchronizer( - controller_pb2_grpc.ControllerServiceStub(controller_channel), - args.dns_server, - ), - controller_channel, - ) - daemon_pb2_grpc.add_DaemonServiceServicer_to_server(daemon_service, daemon) - daemon_service.sync() - - logging.info(f"Starting Daemon ({__version__})") - daemon.start() - daemon.wait_for_termination() - - -def register_host(args): - addr, port = args.bind - port = port or 0 - addr = addr or "0.0.0.0" - - controller_channel = get_controller_channel(args) - - host_client = host_pb2_grpc.HostServiceStub(controller_channel) - token = host_client.CreateBootstrapToken(host_pb2.CreateBootstrapTokenRequest()).token - host_client.Register( - host_pb2.RegisterHostRequest( - token=token, - host=host_pb2.Host( - name=args.name, - address=f"{addr}:{port}", - ), - ) - ) - - logging.info(f"Successfully registered host ({__version__})") - - -def deregister_host(args): - controller_channel = get_controller_channel(args) - - host_client = host_pb2_grpc.HostServiceStub(controller_channel) - host_client.Deregister(host_pb2.Host(name=args.name)) - - logging.info(f"Successfully deregistered host ({__version__})") - - -def main(): - logging.basicConfig( - level=logging.DEBUG, format="%(asctime)s %(levelname)s:%(name)s:%(message)s" - ) - - p = re.compile(r"^(\S*):(\d+)$") - - def bind_address(s): - match = p.match(s) - if not match: - raise argparse.ArgumentTypeError("invalid bind address: " + s) - res = match.group(1), int(match.group(2)) - return res - - parser = argparse.ArgumentParser( - description="restvirt", formatter_class=argparse.ArgumentDefaultsHelpFormatter - ) - subparsers = parser.add_subparsers() - - controller_parser = subparsers.add_parser("controller") - controller_parser.add_argument("--debug", action="store_true", help="run in debug mode") - controller_parser.add_argument( - "-b", "--bind", type=bind_address, default=":8090", help="controller bind address" - ) - controller_parser.add_argument( - "-c", "--config", default="/etc/restvirt", help="configuration folder" - ) - controller_parser.add_argument("--server-cert") - controller_parser.add_argument("--server-key") - controller_parser.add_argument("--client-ca-cert") - controller_parser.set_defaults(func=start_controller) - - daemon_parser = subparsers.add_parser("daemon") - daemon_parser.add_argument("--name", default="default", help="host's name") - daemon_parser.add_argument("--debug", action="store_true", help="run in debug mode") - daemon_parser.add_argument("--dns-server", help="custom DNS server") - daemon_parser.add_argument( - "-b", "--bind", type=bind_address, default="127.0.0.1:8099", help="daemon bind address" - ) - daemon_parser.add_argument( - "-a", "--controller", type=bind_address, default="127.0.0.1:8094", help="controller address" - ) - daemon_parser.add_argument( - "-c", "--config", default="/etc/restvirt", help="configuration folder" - ) - daemon_parser.add_argument("--client-cert") - daemon_parser.add_argument("--client-key") - daemon_parser.add_argument("--server-ca-cert") - daemon_parser.set_defaults(func=start_daemon) - - register_parser = subparsers.add_parser("register") - register_parser.add_argument("--name", help="host's name") - register_parser.add_argument("-b", "--bind", type=bind_address, help="daemon bind address") - register_parser.add_argument( - "-a", "--controller", type=bind_address, default="127.0.0.1:8094", help="controller address" - ) - register_parser.add_argument("--client-cert") - register_parser.add_argument("--client-key") - register_parser.add_argument("--server-ca-cert") - register_parser.set_defaults(func=register_host) - - deregister_parser = subparsers.add_parser("deregister") - deregister_parser.add_argument("--name", help="host's name") - deregister_parser.add_argument( - "-a", "--controller", type=bind_address, default="127.0.0.1:8094", help="controller address" - ) - deregister_parser.add_argument("--client-cert") - deregister_parser.add_argument("--client-key") - deregister_parser.add_argument("--server-ca-cert") - deregister_parser.set_defaults(func=deregister_host) - - args = parser.parse_args() - logging.debug(args) - args.func(args) - - -if __name__ == "__main__": - main() diff --git a/minivirt/migrations.py b/minivirt/migrations.py deleted file mode 100644 index c281f13..0000000 --- a/minivirt/migrations.py +++ /dev/null @@ -1,116 +0,0 @@ -import itertools -import sqlite3 - -import sqlalchemy as sa - - -def _migration_0(engine): - with engine.connect() as conn: - conn.connection.executescript( - """ -BEGIN; - -ALTER TABLE domains ADD ipv6_address VARCHAR; -ALTER TABLE networks ADD cidr6 VARCHAR; - -DELETE FROM versions; -INSERT INTO versions VALUES('1'); - -COMMIT; -""" - ) - - -migrations = { - "0": _migration_0, -} - - -def run_migrations(engine: sa.engine.Engine): - create_initial(engine) - - with engine.connect() as conn: - connection = conn.connection - connection.row_factory = sqlite3.Row - cur = connection.cursor() - cur.row_factory = sqlite3.Row - try: - cur.execute("SELECT * FROM versions") - res = cur.fetchall() - assert len(res) == 1 - version = res[0]["version"] - finally: - cur.close() - - for key in itertools.dropwhile(lambda k: k != version, migrations): - print(f'Executing migration from version "{key}"') - migration_func = migrations[key] - migration_func(engine) - - -def create_initial(engine): - with engine.connect() as conn: - conn.connection.executescript( - """ -CREATE TABLE IF NOT EXISTS bootstrap_tokens ( - token VARCHAR NOT NULL, - expires_at DATETIME, - PRIMARY KEY (token) -); - -CREATE TABLE IF NOT EXISTS hosts ( - name VARCHAR NOT NULL, - address VARCHAR, - last_heartbeat DATETIME, - PRIMARY KEY (name) -); - -CREATE TABLE IF NOT EXISTS networks ( - id VARCHAR NOT NULL, - cidr VARCHAR, - PRIMARY KEY (id) -); - -CREATE TABLE IF NOT EXISTS route_tables ( - id INTEGER NOT NULL, - name VARCHAR, - PRIMARY KEY (id) -); - -CREATE TABLE IF NOT EXISTS port_forwardings ( - protocol VARCHAR NOT NULL, - source_port INTEGER NOT NULL, - target_ip VARCHAR, - target_port INTEGER, - PRIMARY KEY (protocol, source_port) -); - -CREATE TABLE IF NOT EXISTS dns_records ( - name VARCHAR NOT NULL, - type VARCHAR NOT NULL, - ttl INTEGER, - records VARCHAR, - PRIMARY KEY (name, type) -); - -CREATE TABLE IF NOT EXISTS domains ( - id VARCHAR NOT NULL, - private_ip VARCHAR, - os_type VARCHAR, - user_data TEXT, - PRIMARY KEY (id), - UNIQUE (private_ip) -); - -CREATE TABLE IF NOT EXISTS routes ( - destination VARCHAR NOT NULL, - gateways VARCHAR, - route_table_id INTEGER, - PRIMARY KEY (destination), - FOREIGN KEY(route_table_id) REFERENCES route_tables (id) ON DELETE CASCADE -); - -CREATE TABLE IF NOT EXISTS versions (version VARCHAR); -INSERT INTO versions SELECT '0' WHERE NOT EXISTS (SELECT * FROM versions); -""" - ) diff --git a/minivirt/models.py b/minivirt/models.py deleted file mode 100644 index 79cd2a9..0000000 --- a/minivirt/models.py +++ /dev/null @@ -1,132 +0,0 @@ -from sqlalchemy import Column, DateTime, ForeignKey, Integer, String, Text, TypeDecorator, Unicode -from sqlalchemy.orm import backref, registry, relationship - - -class StringList(TypeDecorator): - impl = Unicode - cache_ok = True - - def __init__(self, delimiter=","): - self.delimiter = delimiter - super().__init__() - - def process_bind_param(self, value, dialect): - assert all([self.delimiter not in e for e in value]) - return self.delimiter.join(value) - - def process_result_value(self, value, dialect): - return value.split(self.delimiter) - - -class StringSet(TypeDecorator): - impl = Unicode - cache_ok = True - - def __init__(self, delimiter=","): - self.delimiter = delimiter - super().__init__() - - def process_bind_param(self, value, dialect): - assert isinstance(value, set) - assert all([self.delimiter not in e for e in value]) - return self.delimiter.join(sorted(value)) - - def process_result_value(self, value, dialect): - return set(value.split(self.delimiter)) - - -mapper_registry = registry() -Base = mapper_registry.generate_base() - - -class BootstrapToken(Base): - __tablename__ = "bootstrap_tokens" - - token = Column(String, primary_key=True) - expires_at = Column(DateTime) - - def __repr__(self): - return f"BootstrapToken(token={self.token!r}, expires_at={self.expires_at!r})" - - -class Host(Base): - __tablename__ = "hosts" - - name = Column(String, primary_key=True) - address = Column(String) - last_heartbeat = Column(DateTime) - - def __repr__(self): - return f"Host(name={self.name!r}, address={self.address!r})" - - -class Network(Base): - __tablename__ = "networks" - - id = Column(String, primary_key=True) - cidr = Column(String) - cidr6 = Column(String) - - def __repr__(self): - return f"Network({self.id!r}: {self.cidr!r} {self.cidr6!r})" - - -class RouteTable(Base): - __tablename__ = "route_tables" - - id = Column(Integer, primary_key=True) - name = Column(String) - - def __repr__(self): - return f"RouteTable(id={self.id!r}, name={self.name!r})" - - -class Route(Base): - __tablename__ = "routes" - - destination = Column(String, primary_key=True) - gateways = Column(StringSet) - route_table_id = Column(Integer, ForeignKey("route_tables.id", ondelete="CASCADE")) - route_table = relationship( - "RouteTable", backref=backref("routes", cascade="all, delete-orphan", passive_deletes=True) - ) - - def __repr__(self): - return f"Route(dest={self.destination!r}, gateways={self.gateways!r}, table={self.route_table!r})" - - -class PortForwarding(Base): - __tablename__ = "port_forwardings" - - protocol = Column(String, primary_key=True) - source_port = Column(Integer, primary_key=True) - target_ip = Column(String) - target_port = Column(Integer) - - def __repr__(self): - return f"{self.protocol} :{self.source_port} -> {self.target_ip}:{self.target_port}" - - -class DNSRecord(Base): - __tablename__ = "dns_records" - - name = Column(String, primary_key=True) - type = Column(String, primary_key=True) - ttl = Column(Integer) - records = Column(StringList) - - def __repr__(self): - return f"DNSEntry({self.name} {self.type} {self.ttl} {' '.join(self.records)}" - - -class Domain(Base): - __tablename__ = "domains" - - id = Column(String, primary_key=True) - private_ip = Column(String, unique=True) - ipv6_address = Column(String, unique=True) - os_type = Column(String) - user_data = Column(Text) - - def __repr__(self): - return f"Domain(id={self.id} private_ip={self.private_ip} ipv6_address={self.ipv6_address})" diff --git a/minivirt/port_forwarding.py b/minivirt/port_forwarding.py deleted file mode 100644 index f9095c5..0000000 --- a/minivirt/port_forwarding.py +++ /dev/null @@ -1,301 +0,0 @@ -import ipaddress -import threading - -import libvirt -import nftables -from sqlalchemy import select - -from minivirt import domain_pb2 -from minivirt.daemon import _network_to_pb -from minivirt.models import PortForwarding - - -class IPTablesPortForwardingSynchronizer: - def __init__(self, controller, dns_addr=None): - self.controller = controller - self.lock = threading.Lock() - self.dns_addr = dns_addr - - def handle_sync(self, session, libvirt_conn: libvirt.virConnect): - with self.lock: - forwardings = session.execute(select(PortForwarding).filter()).scalars().all() - - table_name = "restvirt" - - nft = nftables.Nftables() - nft.set_json_output(True) - - rfc1918_nets = [ - { - "prefix": { - "addr": str(net.network_address), - "len": net.prefixlen, - } - } - for net in [ - ipaddress.ip_network(n) - for n in ["192.168.0.0/16", "172.16.0.0/12", "10.0.0.0/8"] - ] - ] - commands = [ - {"add": {"table": {"name": table_name, "family": "inet"}}}, - {"delete": {"table": {"name": table_name, "family": "inet"}}}, - {"add": {"table": {"name": table_name, "family": "inet"}}}, - { - "add": { - "chain": { - "table": table_name, - "family": "inet", - "name": "output", - "type": "nat", - "hook": "output", - "prio": -105, - "policy": "accept", - } - } - }, - { - "add": { - "chain": { - "table": table_name, - "family": "inet", - "name": "prerouting", - "type": "nat", - "hook": "prerouting", - "prio": -105, - "policy": "accept", - } - } - }, - { - "add": { - "chain": { - "table": table_name, - "family": "inet", - "name": "postrouting", - "type": "nat", - "hook": "postrouting", - "prio": 95, - "policy": "accept", - } - } - }, - { - "add": { - "chain": { - "table": table_name, - "family": "inet", - "name": "forward", - "type": "filter", - "hook": "forward", - "prio": -5, - "policy": "accept", - } - } - }, - { - "add": { # ensure rfc1918 rules - "rule": { - "table": table_name, - "family": "inet", - "chain": "postrouting", - "expr": [ - { - "match": { - "op": "in", - "left": {"payload": {"protocol": "ip", "field": "saddr"}}, - "right": {"set": rfc1918_nets}, - } - }, - { - "match": { - "op": "!=", - "left": {"payload": {"protocol": "ip", "field": "daddr"}}, - "right": {"set": rfc1918_nets}, - } - }, - { - "counter": None, - }, - {"masquerade": None}, - ], - } - } - }, - ] - - # FIXME: limit to eno2 src port - for f in forwardings: - commands.extend( - [ - { - "add": { - "rule": { - "table": table_name, - "family": "inet", - "chain": "output", - "expr": [ - { - "match": { - "op": "==", - "left": { - "payload": { - "protocol": f.protocol, - "field": "dport", - } - }, - "right": f.source_port, - } - }, - { - "counter": None, - }, - { - "dnat": { - "family": "ip", - "addr": f.target_ip, - "port": f.target_port, - } - }, - ], - } - } - }, - { - "add": { - "rule": { - "table": table_name, - "family": "inet", - "chain": "prerouting", - "expr": [ - { - "match": { - "op": "==", - "left": { - "payload": { - "protocol": f.protocol, - "field": "dport", - } - }, - "right": f.source_port, - } - }, - { - "counter": None, - }, - { - "dnat": { - "family": "ip", - "addr": f.target_ip, - "port": f.target_port, - } - }, - ], - } - } - }, - { - "add": { - "rule": { - "table": table_name, - "family": "inet", - "chain": "forward", - "expr": [ - { - "match": { - "op": "==", - "left": { - "payload": { - "protocol": f.protocol, - "field": "dport", - } - }, - "right": f.target_port, - } - }, - { - "match": { - "op": "==", - "left": { - "payload": {"protocol": "ip", "field": "daddr"} - }, - "right": f.target_ip, - } - }, - { - "counter": None, - }, - {"accept": None}, - ], - } - } - }, - ] - ) - - networks = [_network_to_pb(net) for net in libvirt_conn.listAllNetworks()] - for network in networks: - net = ipaddress.IPv4Network(network.cidr) - - dns_addr = self.dns_addr - if self.dns_addr is None: - dns_addr = str(net[1]) - - for chain in ["output", "prerouting"]: - for protocol in ["udp", "tcp"]: - commands.extend( - [ - { - "add": { # FIXME: use configurable target IP:port - "rule": { - "table": table_name, - "family": "inet", - "chain": chain, - "expr": [ - { - "match": { - "op": "==", - "left": { - "payload": { - "protocol": protocol, - "field": "dport", - } - }, - "right": 53, - } - }, - { - "match": { - "op": "==", - "left": { - "payload": { - "protocol": "ip", - "field": "daddr", - } - }, - "right": str(net[1]), - } - }, - { - "counter": None, - }, - { - "dnat": { - "family": "ip", - "addr": dns_addr, - "port": 5354, - } - }, - ], - } - } - }, - ] - ) - - rc, output, error = nft.json_cmd({"nftables": commands}) - # FIXME: replace with logging - print(rc) - print(output) - print(error) - assert rc == 0 diff --git a/minivirt/port_forwarding_pb2.py b/minivirt/port_forwarding_pb2.py deleted file mode 100644 index 868b34d..0000000 --- a/minivirt/port_forwarding_pb2.py +++ /dev/null @@ -1,37 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/port_forwarding.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x1eminivirt/port_forwarding.proto\x1a\x1bgoogle/protobuf/empty.proto\"O\n\x18PortForwardingIdentifier\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x10\n\x08protocol\x18\x02 \x01(\t\x12\x13\n\x0bsource_port\x18\x03 \x01(\r\"_\n\x0ePortForwarding\x12\x10\n\x08protocol\x18\x02 \x01(\t\x12\x13\n\x0bsource_port\x18\x03 \x01(\r\x12\x11\n\ttarget_ip\x18\x04 \x01(\t\x12\x13\n\x0btarget_port\x18\x05 \x01(\r\"*\n\x1aListPortForwardingsRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\"H\n\x1bListPortForwardingsResponse\x12)\n\x10port_forwardings\x18\x01 \x03(\x0b\x32\x0f.PortForwarding\"R\n\x18PutPortForwardingRequest\x12(\n\x0fport_forwarding\x18\x01 \x01(\x0b\x32\x0f.PortForwarding\x12\x0c\n\x04host\x18\x02 \x01(\t2\xbe\x02\n\x15PortForwardingService\x12\x41\n\x11GetPortForwarding\x12\x19.PortForwardingIdentifier\x1a\x0f.PortForwarding\"\x00\x12R\n\x13ListPortForwardings\x12\x1b.ListPortForwardingsRequest\x1a\x1c.ListPortForwardingsResponse\"\x00\x12\x41\n\x11PutPortForwarding\x12\x19.PutPortForwardingRequest\x1a\x0f.PortForwarding\"\x00\x12K\n\x14\x44\x65letePortForwarding\x12\x19.PortForwardingIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.port_forwarding_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _PORTFORWARDINGIDENTIFIER._serialized_start=63 - _PORTFORWARDINGIDENTIFIER._serialized_end=142 - _PORTFORWARDING._serialized_start=144 - _PORTFORWARDING._serialized_end=239 - _LISTPORTFORWARDINGSREQUEST._serialized_start=241 - _LISTPORTFORWARDINGSREQUEST._serialized_end=283 - _LISTPORTFORWARDINGSRESPONSE._serialized_start=285 - _LISTPORTFORWARDINGSRESPONSE._serialized_end=357 - _PUTPORTFORWARDINGREQUEST._serialized_start=359 - _PUTPORTFORWARDINGREQUEST._serialized_end=441 - _PORTFORWARDINGSERVICE._serialized_start=444 - _PORTFORWARDINGSERVICE._serialized_end=762 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/port_forwarding_pb2_grpc.py b/minivirt/port_forwarding_pb2_grpc.py deleted file mode 100644 index 0441b5d..0000000 --- a/minivirt/port_forwarding_pb2_grpc.py +++ /dev/null @@ -1,166 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import port_forwarding_pb2 as minivirt_dot_port__forwarding__pb2 - - -class PortForwardingServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetPortForwarding = channel.unary_unary( - '/PortForwardingService/GetPortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - ) - self.ListPortForwardings = channel.unary_unary( - '/PortForwardingService/ListPortForwardings', - request_serializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.FromString, - ) - self.PutPortForwarding = channel.unary_unary( - '/PortForwardingService/PutPortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.SerializeToString, - response_deserializer=minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - ) - self.DeletePortForwarding = channel.unary_unary( - '/PortForwardingService/DeletePortForwarding', - request_serializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - - -class PortForwardingServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def GetPortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListPortForwardings(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutPortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeletePortForwarding(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_PortForwardingServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetPortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.GetPortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.PortForwarding.SerializeToString, - ), - 'ListPortForwardings': grpc.unary_unary_rpc_method_handler( - servicer.ListPortForwardings, - request_deserializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.SerializeToString, - ), - 'PutPortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.PutPortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.FromString, - response_serializer=minivirt_dot_port__forwarding__pb2.PortForwarding.SerializeToString, - ), - 'DeletePortForwarding': grpc.unary_unary_rpc_method_handler( - servicer.DeletePortForwarding, - request_deserializer=minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'PortForwardingService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class PortForwardingService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetPortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/PortForwardingService/GetPortForwarding', - minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListPortForwardings(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/PortForwardingService/ListPortForwardings', - minivirt_dot_port__forwarding__pb2.ListPortForwardingsRequest.SerializeToString, - minivirt_dot_port__forwarding__pb2.ListPortForwardingsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutPortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/PortForwardingService/PutPortForwarding', - minivirt_dot_port__forwarding__pb2.PutPortForwardingRequest.SerializeToString, - minivirt_dot_port__forwarding__pb2.PortForwarding.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeletePortForwarding(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/PortForwardingService/DeletePortForwarding', - minivirt_dot_port__forwarding__pb2.PortForwardingIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/minivirt/route.py b/minivirt/route.py deleted file mode 100644 index a336eee..0000000 --- a/minivirt/route.py +++ /dev/null @@ -1,133 +0,0 @@ -import ipaddress -from typing import Dict, Set - -from sqlalchemy import delete, select - -from minivirt import route_pb2 -from minivirt.models import Route, RouteTable - - -class SyncEventHandler: - def handle_sync(self, session): - pass - - -class GenericRouteTableController: - id_range_min, id_range_max = 30069, 30169 - - def __init__(self, session_factory, sync_handler=SyncEventHandler()): - self.session_factory = session_factory - self.sync_handler = sync_handler - - def route_tables(self): - with self.session_factory() as session: - return session.execute(select(RouteTable)).scalars().all() - - def route_table(self, id): - with self.session_factory() as session: - return ( - session.execute(select(RouteTable).filter(RouteTable.id == id)) - .scalars() - .one_or_none() - ) - - def _get_available_id(self, session): - ids = session.execute(select(RouteTable.id).order_by(RouteTable.id)).scalars().all() - if not ids or ids[0] > self.id_range_min: - return self.id_range_min - for i in range(len(ids) - 1): - if ids[i + 1] - ids[i] > 1: - return ids[i] + 1 - assert ids[-1] < self.id_range_max - return ids[-1] + 1 - - def create_route_table(self, r: route_pb2.RouteTable): - with self.session_factory() as session: - route = RouteTable( - id=self._get_available_id(session), - name=r.name, - ) - session.add(route) - session.commit() - self.sync_handler.handle_sync(session) - - return route_pb2.RouteTable( - id=route.id, - name=route.name, - ) - - def remove_route_table(self, id): - with self.session_factory() as session: - res = session.execute(delete(RouteTable).where(RouteTable.id == id)) - if res.rowcount == 0: - return False - - assert res.rowcount == 1 - session.commit() - self.sync_handler.handle_sync(session) - return True - - def sync(self): - with self.session_factory() as session: - self.sync_handler.handle_sync(session) - - -AliasIPConf = Dict[ipaddress.IPv4Network, Set[ipaddress.IPv4Address]] - -TABLE_ID = 69 - - -class GenericRouteController: - def __init__(self, session_factory, sync_handler=SyncEventHandler()): - self.session_factory = session_factory - self.sync_handler = sync_handler - - def routes(self, route_table_id=None): - with self.session_factory() as session: - return ( - session.execute(select(Route).filter(Route.route_table_id == route_table_id)) - .scalars() - .all() - ) - - def route(self, route_table_id, destination): - with self.session_factory() as session: - return ( - session.execute( - select(Route).filter( - Route.route_table_id == route_table_id, - Route.destination == destination, - ) - ) - .scalars() - .one_or_none() - ) - - def put_route(self, r: route_pb2.Route): - route = Route( - destination=r.destination, - gateways=set(r.gateways), - route_table_id=r.route_table_id, - ) - with self.session_factory() as session: - merged = session.merge(route) - if session.is_modified(merged): - session.commit() - self.sync_handler.handle_sync(session) - - return r - - def remove_route(self, route_table_id, destination): - with self.session_factory() as session: - session.execute( - delete(Route).where( - Route.destination == destination, - Route.route_table_id == route_table_id, - ) - ) - session.commit() - self.sync_handler.handle_sync(session) - - def sync(self): - with self.session_factory() as session: - self.sync_handler.handle_sync(session) diff --git a/minivirt/route_pb2.py b/minivirt/route_pb2.py deleted file mode 100644 index 6133ea9..0000000 --- a/minivirt/route_pb2.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/route.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x14minivirt/route.proto\x1a\x1bgoogle/protobuf/empty.proto\"<\n\nRouteTable\x12\x14\n\x0cnetwork_name\x18\x01 \x01(\t\x12\n\n\x02id\x18\x02 \x01(\r\x12\x0c\n\x04name\x18\x03 \x01(\t\"\"\n\x14RouteTableIdentifier\x12\n\n\x02id\x18\x01 \x01(\r\".\n\x16ListRouteTablesRequest\x12\x14\n\x0cnetwork_name\x18\x01 \x01(\t\"<\n\x17ListRouteTablesResponse\x12!\n\x0croute_tables\x18\x01 \x03(\x0b\x32\x0b.RouteTable\";\n\x17\x43reateRouteTableRequest\x12 \n\x0broute_table\x18\x01 \x01(\x0b\x32\x0b.RouteTable\">\n\x0fRouteIdentifier\x12\x16\n\x0eroute_table_id\x18\x01 \x01(\r\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\t\"F\n\x05Route\x12\x16\n\x0eroute_table_id\x18\x01 \x01(\r\x12\x13\n\x0b\x64\x65stination\x18\x02 \x01(\t\x12\x10\n\x08gateways\x18\x03 \x03(\t\"+\n\x11ListRoutesRequest\x12\x16\n\x0eroute_table_id\x18\x01 \x01(\r\",\n\x12ListRoutesResponse\x12\x16\n\x06routes\x18\x01 \x03(\x0b\x32\x06.Route\"(\n\x0fPutRouteRequest\x12\x15\n\x05route\x18\x01 \x01(\x0b\x32\x06.Route\"\r\n\x0bSyncRequest2\x83\x04\n\x0cRouteService\x12\x35\n\rGetRouteTable\x12\x15.RouteTableIdentifier\x1a\x0b.RouteTable\"\x00\x12\x46\n\x0fListRouteTables\x12\x17.ListRouteTablesRequest\x1a\x18.ListRouteTablesResponse\"\x00\x12;\n\x10\x43reateRouteTable\x12\x18.CreateRouteTableRequest\x1a\x0b.RouteTable\"\x00\x12\x43\n\x10\x44\x65leteRouteTable\x12\x15.RouteTableIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12&\n\x08GetRoute\x12\x10.RouteIdentifier\x1a\x06.Route\"\x00\x12\x37\n\nListRoutes\x12\x12.ListRoutesRequest\x1a\x13.ListRoutesResponse\"\x00\x12&\n\x08PutRoute\x12\x10.PutRouteRequest\x1a\x06.Route\"\x00\x12\x39\n\x0b\x44\x65leteRoute\x12\x10.RouteIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x12.\n\x04Sync\x12\x0c.SyncRequest\x1a\x16.google.protobuf.Empty\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.route_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _ROUTETABLE._serialized_start=53 - _ROUTETABLE._serialized_end=113 - _ROUTETABLEIDENTIFIER._serialized_start=115 - _ROUTETABLEIDENTIFIER._serialized_end=149 - _LISTROUTETABLESREQUEST._serialized_start=151 - _LISTROUTETABLESREQUEST._serialized_end=197 - _LISTROUTETABLESRESPONSE._serialized_start=199 - _LISTROUTETABLESRESPONSE._serialized_end=259 - _CREATEROUTETABLEREQUEST._serialized_start=261 - _CREATEROUTETABLEREQUEST._serialized_end=320 - _ROUTEIDENTIFIER._serialized_start=322 - _ROUTEIDENTIFIER._serialized_end=384 - _ROUTE._serialized_start=386 - _ROUTE._serialized_end=456 - _LISTROUTESREQUEST._serialized_start=458 - _LISTROUTESREQUEST._serialized_end=501 - _LISTROUTESRESPONSE._serialized_start=503 - _LISTROUTESRESPONSE._serialized_end=547 - _PUTROUTEREQUEST._serialized_start=549 - _PUTROUTEREQUEST._serialized_end=589 - _SYNCREQUEST._serialized_start=591 - _SYNCREQUEST._serialized_end=604 - _ROUTESERVICE._serialized_start=607 - _ROUTESERVICE._serialized_end=1122 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/route_pb2_grpc.py b/minivirt/route_pb2_grpc.py deleted file mode 100644 index f6211f2..0000000 --- a/minivirt/route_pb2_grpc.py +++ /dev/null @@ -1,331 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import route_pb2 as minivirt_dot_route__pb2 - - -class RouteServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetRouteTable = channel.unary_unary( - '/RouteService/GetRouteTable', - request_serializer=minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.RouteTable.FromString, - ) - self.ListRouteTables = channel.unary_unary( - '/RouteService/ListRouteTables', - request_serializer=minivirt_dot_route__pb2.ListRouteTablesRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.ListRouteTablesResponse.FromString, - ) - self.CreateRouteTable = channel.unary_unary( - '/RouteService/CreateRouteTable', - request_serializer=minivirt_dot_route__pb2.CreateRouteTableRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.RouteTable.FromString, - ) - self.DeleteRouteTable = channel.unary_unary( - '/RouteService/DeleteRouteTable', - request_serializer=minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.GetRoute = channel.unary_unary( - '/RouteService/GetRoute', - request_serializer=minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.Route.FromString, - ) - self.ListRoutes = channel.unary_unary( - '/RouteService/ListRoutes', - request_serializer=minivirt_dot_route__pb2.ListRoutesRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.ListRoutesResponse.FromString, - ) - self.PutRoute = channel.unary_unary( - '/RouteService/PutRoute', - request_serializer=minivirt_dot_route__pb2.PutRouteRequest.SerializeToString, - response_deserializer=minivirt_dot_route__pb2.Route.FromString, - ) - self.DeleteRoute = channel.unary_unary( - '/RouteService/DeleteRoute', - request_serializer=minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.Sync = channel.unary_unary( - '/RouteService/Sync', - request_serializer=minivirt_dot_route__pb2.SyncRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - - -class RouteServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def GetRouteTable(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListRouteTables(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateRouteTable(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteRouteTable(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetRoute(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListRoutes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def PutRoute(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteRoute(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def Sync(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_RouteServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetRouteTable': grpc.unary_unary_rpc_method_handler( - servicer.GetRouteTable, - request_deserializer=minivirt_dot_route__pb2.RouteTableIdentifier.FromString, - response_serializer=minivirt_dot_route__pb2.RouteTable.SerializeToString, - ), - 'ListRouteTables': grpc.unary_unary_rpc_method_handler( - servicer.ListRouteTables, - request_deserializer=minivirt_dot_route__pb2.ListRouteTablesRequest.FromString, - response_serializer=minivirt_dot_route__pb2.ListRouteTablesResponse.SerializeToString, - ), - 'CreateRouteTable': grpc.unary_unary_rpc_method_handler( - servicer.CreateRouteTable, - request_deserializer=minivirt_dot_route__pb2.CreateRouteTableRequest.FromString, - response_serializer=minivirt_dot_route__pb2.RouteTable.SerializeToString, - ), - 'DeleteRouteTable': grpc.unary_unary_rpc_method_handler( - servicer.DeleteRouteTable, - request_deserializer=minivirt_dot_route__pb2.RouteTableIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'GetRoute': grpc.unary_unary_rpc_method_handler( - servicer.GetRoute, - request_deserializer=minivirt_dot_route__pb2.RouteIdentifier.FromString, - response_serializer=minivirt_dot_route__pb2.Route.SerializeToString, - ), - 'ListRoutes': grpc.unary_unary_rpc_method_handler( - servicer.ListRoutes, - request_deserializer=minivirt_dot_route__pb2.ListRoutesRequest.FromString, - response_serializer=minivirt_dot_route__pb2.ListRoutesResponse.SerializeToString, - ), - 'PutRoute': grpc.unary_unary_rpc_method_handler( - servicer.PutRoute, - request_deserializer=minivirt_dot_route__pb2.PutRouteRequest.FromString, - response_serializer=minivirt_dot_route__pb2.Route.SerializeToString, - ), - 'DeleteRoute': grpc.unary_unary_rpc_method_handler( - servicer.DeleteRoute, - request_deserializer=minivirt_dot_route__pb2.RouteIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'Sync': grpc.unary_unary_rpc_method_handler( - servicer.Sync, - request_deserializer=minivirt_dot_route__pb2.SyncRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'RouteService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class RouteService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetRouteTable(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/GetRouteTable', - minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - minivirt_dot_route__pb2.RouteTable.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListRouteTables(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/ListRouteTables', - minivirt_dot_route__pb2.ListRouteTablesRequest.SerializeToString, - minivirt_dot_route__pb2.ListRouteTablesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateRouteTable(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/CreateRouteTable', - minivirt_dot_route__pb2.CreateRouteTableRequest.SerializeToString, - minivirt_dot_route__pb2.RouteTable.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteRouteTable(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/DeleteRouteTable', - minivirt_dot_route__pb2.RouteTableIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetRoute(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/GetRoute', - minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - minivirt_dot_route__pb2.Route.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListRoutes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/ListRoutes', - minivirt_dot_route__pb2.ListRoutesRequest.SerializeToString, - minivirt_dot_route__pb2.ListRoutesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def PutRoute(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/PutRoute', - minivirt_dot_route__pb2.PutRouteRequest.SerializeToString, - minivirt_dot_route__pb2.Route.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteRoute(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/DeleteRoute', - minivirt_dot_route__pb2.RouteIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def Sync(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/RouteService/Sync', - minivirt_dot_route__pb2.SyncRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/minivirt/utils.py b/minivirt/utils.py deleted file mode 100644 index 7e0cd91..0000000 --- a/minivirt/utils.py +++ /dev/null @@ -1,39 +0,0 @@ -import logging -from timeit import default_timer as timer - -import grpc -import libvirt -from google.protobuf import empty_pb2 - - -class UnaryUnaryInterceptor(grpc.ServerInterceptor): - def intercept_service(self, continuation, handler_call_details): - next = continuation(handler_call_details) - if next is None: - return None - if next.unary_unary is None: - return next - - def letsgo(request, context): - start = timer() - try: - response = next.unary_unary(request, context) - except libvirt.libvirtError as e: - status_code = grpc.StatusCode.INTERNAL - if e.get_error_code() in [ - libvirt.VIR_ERR_NO_DOMAIN, - libvirt.VIR_ERR_NO_STORAGE_VOL, - ]: - status_code = grpc.StatusCode.NOT_FOUND - context.set_code(status_code) - context.set_details(f"{e} ({e.get_error_code()})") - response = empty_pb2.Empty() - - logging.debug(f"{handler_call_details.method} [{(timer() - start)*1000:.3f} ms]") - return response - - return grpc.unary_unary_rpc_method_handler( - letsgo, - request_deserializer=next.request_deserializer, - response_serializer=next.response_serializer, - ) diff --git a/minivirt/version.py b/minivirt/version.py deleted file mode 100644 index d5cfca6..0000000 --- a/minivirt/version.py +++ /dev/null @@ -1 +0,0 @@ -__version__ = "unknown" diff --git a/minivirt/volume_pb2.py b/minivirt/volume_pb2.py deleted file mode 100644 index 84b8819..0000000 --- a/minivirt/volume_pb2.py +++ /dev/null @@ -1,49 +0,0 @@ -# -*- coding: utf-8 -*- -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: minivirt/volume.proto -"""Generated protocol buffer code.""" -from google.protobuf.internal import builder as _builder -from google.protobuf import descriptor as _descriptor -from google.protobuf import descriptor_pool as _descriptor_pool -from google.protobuf import symbol_database as _symbol_database -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 - - -DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(b'\n\x15minivirt/volume.proto\x1a\x1bgoogle/protobuf/empty.proto\".\n\x10GetVolumeRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\"0\n\x06Volume\x12\n\n\x02id\x18\x01 \x01(\t\x12\x0c\n\x04name\x18\x02 \x01(\t\x12\x0c\n\x04size\x18\x03 \x01(\x04\"\"\n\x12ListVolumesRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\"/\n\x13ListVolumesResponse\x12\x18\n\x07volumes\x18\x01 \x03(\x0b\x32\x07.Volume\"<\n\x13\x43reateVolumeRequest\x12\x17\n\x06volume\x18\x01 \x01(\x0b\x32\x07.Volume\x12\x0c\n\x04host\x18\x02 \x01(\t\"<\n\x13UpdateVolumeRequest\x12\x0c\n\x04host\x18\x01 \x01(\t\x12\x17\n\x06volume\x18\x02 \x01(\x0b\x32\x07.Volume\"1\n\x13\x44\x65leteVolumeRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\"P\n\x1aVolumeAttachmentIdentifier\x12\x11\n\tdomain_id\x18\x01 \x01(\t\x12\x11\n\tvolume_id\x18\x02 \x01(\t\x12\x0c\n\x04host\x18\x03 \x01(\t\"N\n\x10VolumeAttachment\x12\x11\n\tdomain_id\x18\x01 \x01(\t\x12\x11\n\tvolume_id\x18\x02 \x01(\t\x12\x14\n\x0c\x64isk_address\x18\x03 \x01(\t\"?\n\x1cListVolumeAttachmentsRequest\x12\x11\n\tdomain_id\x18\x01 \x01(\t\x12\x0c\n\x04host\x18\x02 \x01(\t\"G\n\x1dListVolumeAttachmentsResponse\x12&\n\x0b\x61ttachments\x18\x01 \x03(\x0b\x32\x11.VolumeAttachment2\xc4\x04\n\rVolumeService\x12)\n\tGetVolume\x12\x11.GetVolumeRequest\x1a\x07.Volume\"\x00\x12:\n\x0bListVolumes\x12\x13.ListVolumesRequest\x1a\x14.ListVolumesResponse\"\x00\x12/\n\x0c\x43reateVolume\x12\x14.CreateVolumeRequest\x1a\x07.Volume\"\x00\x12/\n\x0cUpdateVolume\x12\x14.UpdateVolumeRequest\x1a\x07.Volume\"\x00\x12>\n\x0c\x44\x65leteVolume\x12\x14.DeleteVolumeRequest\x1a\x16.google.protobuf.Empty\"\x00\x12X\n\x15ListVolumeAttachments\x12\x1d.ListVolumeAttachmentsRequest\x1a\x1e.ListVolumeAttachmentsResponse\"\x00\x12G\n\x13GetVolumeAttachment\x12\x1b.VolumeAttachmentIdentifier\x1a\x11.VolumeAttachment\"\x00\x12@\n\x0c\x41ttachVolume\x12\x1b.VolumeAttachmentIdentifier\x1a\x11.VolumeAttachment\"\x00\x12\x45\n\x0c\x44\x65tachVolume\x12\x1b.VolumeAttachmentIdentifier\x1a\x16.google.protobuf.Empty\"\x00\x42\x06Z\x04.;pbb\x06proto3') - -_builder.BuildMessageAndEnumDescriptors(DESCRIPTOR, globals()) -_builder.BuildTopDescriptorsAndMessages(DESCRIPTOR, 'minivirt.volume_pb2', globals()) -if _descriptor._USE_C_DESCRIPTORS == False: - - DESCRIPTOR._options = None - DESCRIPTOR._serialized_options = b'Z\004.;pb' - _GETVOLUMEREQUEST._serialized_start=54 - _GETVOLUMEREQUEST._serialized_end=100 - _VOLUME._serialized_start=102 - _VOLUME._serialized_end=150 - _LISTVOLUMESREQUEST._serialized_start=152 - _LISTVOLUMESREQUEST._serialized_end=186 - _LISTVOLUMESRESPONSE._serialized_start=188 - _LISTVOLUMESRESPONSE._serialized_end=235 - _CREATEVOLUMEREQUEST._serialized_start=237 - _CREATEVOLUMEREQUEST._serialized_end=297 - _UPDATEVOLUMEREQUEST._serialized_start=299 - _UPDATEVOLUMEREQUEST._serialized_end=359 - _DELETEVOLUMEREQUEST._serialized_start=361 - _DELETEVOLUMEREQUEST._serialized_end=410 - _VOLUMEATTACHMENTIDENTIFIER._serialized_start=412 - _VOLUMEATTACHMENTIDENTIFIER._serialized_end=492 - _VOLUMEATTACHMENT._serialized_start=494 - _VOLUMEATTACHMENT._serialized_end=572 - _LISTVOLUMEATTACHMENTSREQUEST._serialized_start=574 - _LISTVOLUMEATTACHMENTSREQUEST._serialized_end=637 - _LISTVOLUMEATTACHMENTSRESPONSE._serialized_start=639 - _LISTVOLUMEATTACHMENTSRESPONSE._serialized_end=710 - _VOLUMESERVICE._serialized_start=713 - _VOLUMESERVICE._serialized_end=1293 -# @@protoc_insertion_point(module_scope) diff --git a/minivirt/volume_pb2_grpc.py b/minivirt/volume_pb2_grpc.py deleted file mode 100644 index 3c41da1..0000000 --- a/minivirt/volume_pb2_grpc.py +++ /dev/null @@ -1,331 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -import grpc - -from google.protobuf import empty_pb2 as google_dot_protobuf_dot_empty__pb2 -from minivirt import volume_pb2 as minivirt_dot_volume__pb2 - - -class VolumeServiceStub(object): - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetVolume = channel.unary_unary( - '/VolumeService/GetVolume', - request_serializer=minivirt_dot_volume__pb2.GetVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.ListVolumes = channel.unary_unary( - '/VolumeService/ListVolumes', - request_serializer=minivirt_dot_volume__pb2.ListVolumesRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.ListVolumesResponse.FromString, - ) - self.CreateVolume = channel.unary_unary( - '/VolumeService/CreateVolume', - request_serializer=minivirt_dot_volume__pb2.CreateVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.UpdateVolume = channel.unary_unary( - '/VolumeService/UpdateVolume', - request_serializer=minivirt_dot_volume__pb2.UpdateVolumeRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.Volume.FromString, - ) - self.DeleteVolume = channel.unary_unary( - '/VolumeService/DeleteVolume', - request_serializer=minivirt_dot_volume__pb2.DeleteVolumeRequest.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - self.ListVolumeAttachments = channel.unary_unary( - '/VolumeService/ListVolumeAttachments', - request_serializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.FromString, - ) - self.GetVolumeAttachment = channel.unary_unary( - '/VolumeService/GetVolumeAttachment', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.VolumeAttachment.FromString, - ) - self.AttachVolume = channel.unary_unary( - '/VolumeService/AttachVolume', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=minivirt_dot_volume__pb2.VolumeAttachment.FromString, - ) - self.DetachVolume = channel.unary_unary( - '/VolumeService/DetachVolume', - request_serializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - response_deserializer=google_dot_protobuf_dot_empty__pb2.Empty.FromString, - ) - - -class VolumeServiceServicer(object): - """Missing associated documentation comment in .proto file.""" - - def GetVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListVolumes(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def CreateVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def UpdateVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DeleteVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def ListVolumeAttachments(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def GetVolumeAttachment(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def AttachVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - def DetachVolume(self, request, context): - """Missing associated documentation comment in .proto file.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details('Method not implemented!') - raise NotImplementedError('Method not implemented!') - - -def add_VolumeServiceServicer_to_server(servicer, server): - rpc_method_handlers = { - 'GetVolume': grpc.unary_unary_rpc_method_handler( - servicer.GetVolume, - request_deserializer=minivirt_dot_volume__pb2.GetVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'ListVolumes': grpc.unary_unary_rpc_method_handler( - servicer.ListVolumes, - request_deserializer=minivirt_dot_volume__pb2.ListVolumesRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.ListVolumesResponse.SerializeToString, - ), - 'CreateVolume': grpc.unary_unary_rpc_method_handler( - servicer.CreateVolume, - request_deserializer=minivirt_dot_volume__pb2.CreateVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'UpdateVolume': grpc.unary_unary_rpc_method_handler( - servicer.UpdateVolume, - request_deserializer=minivirt_dot_volume__pb2.UpdateVolumeRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.Volume.SerializeToString, - ), - 'DeleteVolume': grpc.unary_unary_rpc_method_handler( - servicer.DeleteVolume, - request_deserializer=minivirt_dot_volume__pb2.DeleteVolumeRequest.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - 'ListVolumeAttachments': grpc.unary_unary_rpc_method_handler( - servicer.ListVolumeAttachments, - request_deserializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.FromString, - response_serializer=minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.SerializeToString, - ), - 'GetVolumeAttachment': grpc.unary_unary_rpc_method_handler( - servicer.GetVolumeAttachment, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=minivirt_dot_volume__pb2.VolumeAttachment.SerializeToString, - ), - 'AttachVolume': grpc.unary_unary_rpc_method_handler( - servicer.AttachVolume, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=minivirt_dot_volume__pb2.VolumeAttachment.SerializeToString, - ), - 'DetachVolume': grpc.unary_unary_rpc_method_handler( - servicer.DetachVolume, - request_deserializer=minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.FromString, - response_serializer=google_dot_protobuf_dot_empty__pb2.Empty.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - 'VolumeService', rpc_method_handlers) - server.add_generic_rpc_handlers((generic_handler,)) - - - # This class is part of an EXPERIMENTAL API. -class VolumeService(object): - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/GetVolume', - minivirt_dot_volume__pb2.GetVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListVolumes(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/ListVolumes', - minivirt_dot_volume__pb2.ListVolumesRequest.SerializeToString, - minivirt_dot_volume__pb2.ListVolumesResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def CreateVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/CreateVolume', - minivirt_dot_volume__pb2.CreateVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def UpdateVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/UpdateVolume', - minivirt_dot_volume__pb2.UpdateVolumeRequest.SerializeToString, - minivirt_dot_volume__pb2.Volume.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DeleteVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/DeleteVolume', - minivirt_dot_volume__pb2.DeleteVolumeRequest.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def ListVolumeAttachments(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/ListVolumeAttachments', - minivirt_dot_volume__pb2.ListVolumeAttachmentsRequest.SerializeToString, - minivirt_dot_volume__pb2.ListVolumeAttachmentsResponse.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def GetVolumeAttachment(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/GetVolumeAttachment', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - minivirt_dot_volume__pb2.VolumeAttachment.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def AttachVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/AttachVolume', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - minivirt_dot_volume__pb2.VolumeAttachment.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) - - @staticmethod - def DetachVolume(request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None): - return grpc.experimental.unary_unary(request, target, '/VolumeService/DetachVolume', - minivirt_dot_volume__pb2.VolumeAttachmentIdentifier.SerializeToString, - google_dot_protobuf_dot_empty__pb2.Empty.FromString, - options, channel_credentials, - insecure, call_credentials, compression, wait_for_ready, timeout, metadata) diff --git a/protos/minivirt/controller.proto b/protos/minivirt/controller.proto deleted file mode 100644 index fe4120d..0000000 --- a/protos/minivirt/controller.proto +++ /dev/null @@ -1,60 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; -import "minivirt/daemon.proto"; -import "minivirt/domain.proto"; -import "minivirt/volume.proto"; -import "minivirt/port_forwarding.proto"; -import "minivirt/dns.proto"; -import "minivirt/route.proto"; - -service ControllerService { - rpc GetDNSRecord(DNSRecordIdentifier) returns (DNSRecord) {} - rpc ListDNSRecords(ListDNSRecordsRequest) returns (ListDNSRecordsResponse) {} - rpc PutDNSRecord(PutDNSRecordRequest) returns (DNSRecord) {} - rpc DeleteDNSRecord(DNSRecordIdentifier) returns (google.protobuf.Empty) {} - - rpc GetNetwork(GetNetworkRequest) returns (Network) {} - rpc ListNetworks(ListNetworksRequest) returns (ListNetworksResponse) {} - rpc CreateNetwork(CreateNetworkRequest) returns (Network) {} - rpc DeleteNetwork(DeleteNetworkRequest) returns (google.protobuf.Empty) {} - - rpc StartDomain(StartDomainRequest) returns (google.protobuf.Empty) {} - rpc StopDomain(StopDomainRequest) returns (google.protobuf.Empty) {} - rpc GetDomain(GetDomainRequest) returns (Domain) {} - rpc ListDomains(ListDomainsRequest) returns (ListDomainsResponse) {} - rpc CreateDomain(CreateDomainRequest) returns (Domain) {} - rpc DeleteDomain(DeleteDomainRequest) returns (google.protobuf.Empty) {} - - rpc DownloadImage(DownloadImageRequest) returns (stream ImageChunk) {} - - rpc GetVolume(GetVolumeRequest) returns (Volume) {} - rpc ListVolumes(ListVolumesRequest) returns (ListVolumesResponse) {} - rpc CreateVolume(CreateVolumeRequest) returns (Volume) {} - rpc UpdateVolume(UpdateVolumeRequest) returns (Volume) {} - rpc DeleteVolume(DeleteVolumeRequest) returns (google.protobuf.Empty) {} - - rpc ListVolumeAttachments(ListVolumeAttachmentsRequest) returns (ListVolumeAttachmentsResponse) {} - rpc GetVolumeAttachment(VolumeAttachmentIdentifier) returns (VolumeAttachment) {} - rpc AttachVolume(VolumeAttachmentIdentifier) returns (VolumeAttachment) {} - rpc DetachVolume(VolumeAttachmentIdentifier) returns (google.protobuf.Empty) {} - - rpc GetPortForwarding(PortForwardingIdentifier) returns (PortForwarding) {} - rpc ListPortForwardings(ListPortForwardingsRequest) returns (ListPortForwardingsResponse) {} - rpc PutPortForwarding(PutPortForwardingRequest) returns (PortForwarding) {} - rpc DeletePortForwarding(PortForwardingIdentifier) returns (google.protobuf.Empty) {} - - rpc GetRouteTable(RouteTableIdentifier) returns (RouteTable) {} - rpc ListRouteTables(ListRouteTablesRequest) returns (ListRouteTablesResponse) {} - rpc CreateRouteTable(CreateRouteTableRequest) returns (RouteTable) {} - rpc DeleteRouteTable(RouteTableIdentifier) returns (google.protobuf.Empty) {} - - rpc GetRoute(RouteIdentifier) returns (Route) {} - rpc ListRoutes(ListRoutesRequest) returns (ListRoutesResponse) {} - rpc PutRoute(PutRouteRequest) returns (Route) {} - rpc DeleteRoute(RouteIdentifier) returns (google.protobuf.Empty) {} - - rpc SyncRoutes(SyncRoutesRequest) returns (google.protobuf.Empty) {} -} diff --git a/protos/minivirt/daemon.proto b/protos/minivirt/daemon.proto deleted file mode 100644 index 93dc9b9..0000000 --- a/protos/minivirt/daemon.proto +++ /dev/null @@ -1,44 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; -import "minivirt/domain.proto"; -import "minivirt/volume.proto"; -import "minivirt/port_forwarding.proto"; - -message SyncRoutesRequest {} - -service DaemonService { - rpc GetNetwork(GetNetworkRequest) returns (Network) {} - rpc ListNetworks(ListNetworksRequest) returns (ListNetworksResponse) {} - rpc CreateNetwork(CreateNetworkRequest) returns (Network) {} - rpc DeleteNetwork(DeleteNetworkRequest) returns (google.protobuf.Empty) {} - - rpc StartDomain(StartDomainRequest) returns (google.protobuf.Empty) {} - rpc StopDomain(StopDomainRequest) returns (google.protobuf.Empty) {} - rpc GetDomain(GetDomainRequest) returns (Domain) {} - rpc ListDomains(ListDomainsRequest) returns (ListDomainsResponse) {} - rpc CreateDomain(CreateDomainRequest) returns (Domain) {} - rpc DeleteDomain(DeleteDomainRequest) returns (google.protobuf.Empty) {} - - rpc DownloadImage(DownloadImageRequest) returns (stream ImageChunk) {} - - rpc GetVolume(GetVolumeRequest) returns (Volume) {} - rpc ListVolumes(ListVolumesRequest) returns (ListVolumesResponse) {} - rpc CreateVolume(CreateVolumeRequest) returns (Volume) {} - rpc UpdateVolume(UpdateVolumeRequest) returns (Volume) {} - rpc DeleteVolume(DeleteVolumeRequest) returns (google.protobuf.Empty) {} - - rpc ListVolumeAttachments(ListVolumeAttachmentsRequest) returns (ListVolumeAttachmentsResponse) {} - rpc GetVolumeAttachment(VolumeAttachmentIdentifier) returns (VolumeAttachment) {} - rpc AttachVolume(VolumeAttachmentIdentifier) returns (VolumeAttachment) {} - rpc DetachVolume(VolumeAttachmentIdentifier) returns (google.protobuf.Empty) {} - - rpc GetPortForwarding(PortForwardingIdentifier) returns (PortForwarding) {} - rpc ListPortForwardings(ListPortForwardingsRequest) returns (ListPortForwardingsResponse) {} - rpc PutPortForwarding(PutPortForwardingRequest) returns (PortForwarding) {} - rpc DeletePortForwarding(PortForwardingIdentifier) returns (google.protobuf.Empty) {} - - rpc SyncRoutes(SyncRoutesRequest) returns (google.protobuf.Empty) {} -} diff --git a/protos/minivirt/dns.proto b/protos/minivirt/dns.proto deleted file mode 100644 index 53b6d5a..0000000 --- a/protos/minivirt/dns.proto +++ /dev/null @@ -1,34 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; - -message DNSRecordIdentifier { - string name = 1; - string type = 2; -} - -message DNSRecord { - string name = 1; - string type = 2; - uint64 ttl = 3; - repeated string records = 4; -} - -message ListDNSRecordsRequest {} - -message ListDNSRecordsResponse { - repeated DNSRecord dns_records = 1; -} - -message PutDNSRecordRequest { - DNSRecord dns_record = 1; -} - -service DNS { - rpc GetDNSRecord(DNSRecordIdentifier) returns (DNSRecord) {} - rpc ListDNSRecords(ListDNSRecordsRequest) returns (ListDNSRecordsResponse) {} - rpc PutDNSRecord(PutDNSRecordRequest) returns (DNSRecord) {} - rpc DeleteDNSRecord(DNSRecordIdentifier) returns (google.protobuf.Empty) {} -} diff --git a/protos/minivirt/domain.proto b/protos/minivirt/domain.proto deleted file mode 100644 index aa7e76b..0000000 --- a/protos/minivirt/domain.proto +++ /dev/null @@ -1,113 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; -import "google/protobuf/timestamp.proto"; - -message StartDomainRequest { - string host = 1; - string uuid = 2; -} - -message StopDomainRequest { - string host = 1; - string uuid = 2; - bool force = 3; -} - -message GetDomainRequest { - string uuid = 1; - string host = 2; -} - -message Domain { - uint64 id = 1; - string uuid = 2; - string name = 3; - uint32 vcpu = 4; - uint64 memory = 5; - string network = 6; - string bridge = 7; - string state = 8; - string private_ip = 9; - string ipv6_address = 15; - string user_data = 10; - bool nested_virtualization = 11; - string base_image = 12; - google.protobuf.Timestamp created_at = 13; - string os_type = 14; -} - -message ListDomainsRequest { - string host = 1; -} - -message ListDomainsResponse { - repeated Domain domains = 1; -} - -message CreateDomainRequest { - Domain domain = 1; - string host = 2; -} - -message DeleteDomainRequest { - string uuid = 1; - string host = 2; -} - -message DownloadImageRequest { - string domain_id = 1; - string host = 2; -} - -message ImageChunk { - bytes bytes = 1; -} - - -message GetNetworkRequest { - string uuid = 1; - string host = 2; -} - -message Network { - string uuid = 1; - string name = 2; - string cidr = 3; - string cidr6 = 4; -} - -message ListNetworksRequest { - string host = 1; -} - -message ListNetworksResponse { - repeated Network networks = 1; -} - -message CreateNetworkRequest { - Network network = 1; - string host = 2; -} - -message DeleteNetworkRequest { - string uuid = 1; - string host = 2; -} - - -service DomainService { - rpc GetDomain(GetDomainRequest) returns (Domain) {} - rpc ListDomains(ListDomainsRequest) returns (ListDomainsResponse) {} - rpc CreateDomain(CreateDomainRequest) returns (Domain) {} - rpc DeleteDomain(DeleteDomainRequest) returns (google.protobuf.Empty) {} - - rpc DownloadImage(DownloadImageRequest) returns (stream ImageChunk) {} - - rpc GetNetwork(GetNetworkRequest) returns (Network) {} - rpc ListNetworks(ListNetworksRequest) returns (ListNetworksResponse) {} - rpc CreateNetwork(CreateNetworkRequest) returns (Network) {} - rpc DeleteNetwork(DeleteNetworkRequest) returns (google.protobuf.Empty) {} -} diff --git a/protos/minivirt/host.proto b/protos/minivirt/host.proto deleted file mode 100644 index c3ab844..0000000 --- a/protos/minivirt/host.proto +++ /dev/null @@ -1,46 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; - -message CreateBootstrapTokenRequest { - string expires_at = 1; -} - -message CreateBootstrapTokenResponse { - string token = 1; -} - -message Host { - string name = 1; - string address = 2; -} - -message ListHostsRequest {} - -message ListHostsResponse { - repeated Host hosts = 1; -} - -message RegisterHostRequest { - Host host = 1; - string token = 2; -} - -message HeartbeatRequest { - Host host = 1; -} - -message HeartbeatResponse { -} - -service HostService { - rpc CreateBootstrapToken(CreateBootstrapTokenRequest) returns (CreateBootstrapTokenResponse) {} - rpc GetHost(Host) returns (Host) {} - rpc ListHosts(ListHostsRequest) returns (ListHostsResponse) {} - rpc Register(RegisterHostRequest) returns (Host) {} - rpc Deregister(Host) returns (google.protobuf.Empty) {} - - rpc Heartbeat(HeartbeatRequest) returns (HeartbeatResponse) {} -} diff --git a/protos/minivirt/port_forwarding.proto b/protos/minivirt/port_forwarding.proto deleted file mode 100644 index 1151264..0000000 --- a/protos/minivirt/port_forwarding.proto +++ /dev/null @@ -1,38 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; - -message PortForwardingIdentifier { - string host = 1; - string protocol = 2; - uint32 source_port = 3; -} - -message PortForwarding { - string protocol = 2; - uint32 source_port = 3; - string target_ip = 4; - uint32 target_port = 5; -} - -message ListPortForwardingsRequest { - string host = 1; -} - -message ListPortForwardingsResponse { - repeated PortForwarding port_forwardings = 1; -} - -message PutPortForwardingRequest { - PortForwarding port_forwarding = 1; - string host = 2; -} - -service PortForwardingService { - rpc GetPortForwarding(PortForwardingIdentifier) returns (PortForwarding) {} - rpc ListPortForwardings(ListPortForwardingsRequest) returns (ListPortForwardingsResponse) {} - rpc PutPortForwarding(PutPortForwardingRequest) returns (PortForwarding) {} - rpc DeletePortForwarding(PortForwardingIdentifier) returns (google.protobuf.Empty) {} -} diff --git a/protos/minivirt/route.proto b/protos/minivirt/route.proto deleted file mode 100644 index a375d89..0000000 --- a/protos/minivirt/route.proto +++ /dev/null @@ -1,67 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; - -message RouteTable { - string network_name = 1; - uint32 id = 2; - string name = 3; -} - -message RouteTableIdentifier { - uint32 id = 1; -} - -message ListRouteTablesRequest { - string network_name = 1; -} - -message ListRouteTablesResponse { - repeated RouteTable route_tables = 1; -} - -message CreateRouteTableRequest { - RouteTable route_table = 1; -} - -message RouteIdentifier { - uint32 route_table_id = 1; - string destination = 2; -} - -message Route { - uint32 route_table_id = 1; - string destination = 2; - repeated string gateways = 3; -} - -message ListRoutesRequest { - uint32 route_table_id = 1; -} - -message ListRoutesResponse { - repeated Route routes = 1; -} - -message PutRouteRequest { - Route route = 1; -} - -message SyncRequest { -} - -service RouteService { - rpc GetRouteTable(RouteTableIdentifier) returns (RouteTable) {} - rpc ListRouteTables(ListRouteTablesRequest) returns (ListRouteTablesResponse) {} - rpc CreateRouteTable(CreateRouteTableRequest) returns (RouteTable) {} - rpc DeleteRouteTable(RouteTableIdentifier) returns (google.protobuf.Empty) {} - - rpc GetRoute(RouteIdentifier) returns (Route) {} - rpc ListRoutes(ListRoutesRequest) returns (ListRoutesResponse) {} - rpc PutRoute(PutRouteRequest) returns (Route) {} - rpc DeleteRoute(RouteIdentifier) returns (google.protobuf.Empty) {} - - rpc Sync(SyncRequest) returns (google.protobuf.Empty) {} -} diff --git a/protos/minivirt/volume.proto b/protos/minivirt/volume.proto deleted file mode 100644 index ec1cd07..0000000 --- a/protos/minivirt/volume.proto +++ /dev/null @@ -1,73 +0,0 @@ -syntax = "proto3"; - -option go_package = ".;pb"; - -import "google/protobuf/empty.proto"; - -message GetVolumeRequest { - string uuid = 1; - string host = 2; -} - -message Volume { - string id = 1; - string name = 2; - uint64 size = 3; -} - -message ListVolumesRequest { - string host = 1; -} - -message ListVolumesResponse { - repeated Volume volumes = 1; -} - -message CreateVolumeRequest { - Volume volume = 1; - string host = 2; -} - -message UpdateVolumeRequest { - string host = 1; - Volume volume = 2; -} - -message DeleteVolumeRequest { - string uuid = 1; - string host = 2; -} - -message VolumeAttachmentIdentifier { - string domain_id = 1; - string volume_id = 2; - string host = 3; -} - -message VolumeAttachment { - string domain_id = 1; - string volume_id = 2; - string disk_address = 3; -} - -message ListVolumeAttachmentsRequest { - string domain_id = 1; - string host = 2; -} - -message ListVolumeAttachmentsResponse { - repeated VolumeAttachment attachments = 1; -} - -service VolumeService { - rpc GetVolume(GetVolumeRequest) returns (Volume) {} - rpc ListVolumes(ListVolumesRequest) returns (ListVolumesResponse) {} - rpc CreateVolume(CreateVolumeRequest) returns (Volume) {} - rpc UpdateVolume(UpdateVolumeRequest) returns (Volume) {} - rpc DeleteVolume(DeleteVolumeRequest) returns (google.protobuf.Empty) {} - - rpc ListVolumeAttachments(ListVolumeAttachmentsRequest) returns (ListVolumeAttachmentsResponse) {} - rpc GetVolumeAttachment(VolumeAttachmentIdentifier) returns (VolumeAttachment) {} - rpc AttachVolume(VolumeAttachmentIdentifier) returns (VolumeAttachment) {} - rpc DetachVolume(VolumeAttachmentIdentifier) returns (google.protobuf.Empty) {} -} diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 2a9d90d..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,18 +0,0 @@ -#[project.scripts] -#restvirt="main:main" - -[tool.black] -line-length = 100 -exclude = ''' -( - migrations/ - | venv/ - | .*_pb2(_grpc)?.py -) -''' - -[tool.isort] -profile="black" -combine_as_imports="true" -skip_glob=["*_pb2.py","*_pb2_grpc.py"] -line_length=100 diff --git a/virtuerl/rebar.config b/rebar.config similarity index 100% rename from virtuerl/rebar.config rename to rebar.config diff --git a/virtuerl/rebar.lock b/rebar.lock similarity index 100% rename from virtuerl/rebar.lock rename to rebar.lock diff --git a/requirements-dev.txt b/requirements-dev.txt deleted file mode 100644 index 6820cd1..0000000 --- a/requirements-dev.txt +++ /dev/null @@ -1,5 +0,0 @@ -pytest==7.2.0 -isort[colors]==5.10.1 -black==22.6.0 -fabric==2.7.1 -grpcio-tools==1.51.1 diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index 35bb0d5..0000000 --- a/requirements.txt +++ /dev/null @@ -1,14 +0,0 @@ -libvirt-python==8.10.0 -grpcio==1.51.1 -grpcio-reflection==1.51.1 -protobuf==4.21.10 -pycdlib==1.12.0 -pyroute2==0.7.2 -git+https://salsa.debian.org/pkg-netfilter-team/pkg-nftables.git@upstream/1.0.4#egg=nftables&subdirectory=py -python-iptables==1.0.0 -SQLAlchemy==1.4.44 -xmltodict==0.12.0 -dnslib==0.9.16 -dnspython==2.2.1 -PyYAML==6.0 -requests==2.31.0 diff --git a/setup.py b/setup.py deleted file mode 100644 index 551e719..0000000 --- a/setup.py +++ /dev/null @@ -1,31 +0,0 @@ -from setuptools import find_packages, setup - -from minivirt.version import __version__ - -setup( - name="restvirt", - version="0.1", # TODO: use __version__ instead - packages=find_packages(), - url="", - license="Apache", - author="Ilya Verbitskiy", - author_email="ilya@verbit.io", - description="", - entry_points={"console_scripts": ["restvirt=minivirt.main:main"]}, - install_requires=[ - "libvirt-python==8.10.0", - "grpcio==1.51.1", - "grpcio-reflection==1.51.1", - "protobuf==4.21.10", - "pycdlib==1.12.0", - "pyroute2==0.7.2", - "nftables @ git+https://salsa.debian.org/pkg-netfilter-team/pkg-nftables.git@upstream/1.0.4#egg=nftables&subdirectory=py", - "python-iptables==1.0.0", - "SQLAlchemy==1.4.44", - "xmltodict==0.12.0", - "dnslib==0.9.16", - "dnspython==2.2.1", - "PyYAML==6.0", - "requests==2.31.0", - ], -) diff --git a/snap/hooks/configure b/snap/hooks/configure deleted file mode 100755 index 4622a34..0000000 --- a/snap/hooks/configure +++ /dev/null @@ -1,19 +0,0 @@ -#!/bin/sh -e - -mkdir -p "$SNAP_DATA/var/run/bird/" -if [ ! -f "$SNAP_DATA/etc/bird/minivirt.conf" ]; then - mkdir -p "$SNAP_DATA/etc/bird/" - cp "$SNAP/etc/bird/minivirt.conf" "$SNAP_DATA/etc/bird/minivirt.conf" -fi - -controller_args="$(snapctl get controller.args)" -if [ -z "$controller_args" ]; then - snapctl set controller.args='-c $SNAP_COMMON' -fi - -daemon_args="$(snapctl get daemon.args)" -if [ -z "$daemon_args" ]; then - snapctl set daemon.args='-c $SNAP_COMMON' -fi - -snapctl restart minivirt diff --git a/snap/hooks/install b/snap/hooks/install deleted file mode 100644 index 2140bca..0000000 --- a/snap/hooks/install +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -snapctl stop --disable minivirt diff --git a/snap/local/bin/bird-wrapper b/snap/local/bin/bird-wrapper deleted file mode 100755 index e113aaa..0000000 --- a/snap/local/bin/bird-wrapper +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec bird -f -c "$SNAP_DATA/etc/bird/minivirt.conf" -s "$SNAP_DATA/var/run/bird/bird.ctl" diff --git a/snap/local/bin/birdc-wrapper b/snap/local/bin/birdc-wrapper deleted file mode 100755 index 2dc229f..0000000 --- a/snap/local/bin/birdc-wrapper +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec birdc -s "$SNAP_DATA/var/run/bird/bird.ctl" "$@" diff --git a/snap/local/bin/restvirt-controller b/snap/local/bin/restvirt-controller deleted file mode 100755 index 50ed1e7..0000000 --- a/snap/local/bin/restvirt-controller +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec restvirt controller $(snapctl get controller.args | envsubst) diff --git a/snap/local/bin/restvirt-daemon b/snap/local/bin/restvirt-daemon deleted file mode 100755 index 533826b..0000000 --- a/snap/local/bin/restvirt-daemon +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec restvirt daemon $(snapctl get daemon.args | envsubst) diff --git a/snap/local/bin/restvirt-deregister b/snap/local/bin/restvirt-deregister deleted file mode 100755 index 92cc0de..0000000 --- a/snap/local/bin/restvirt-deregister +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec restvirt deregister "$@" diff --git a/snap/local/bin/restvirt-register b/snap/local/bin/restvirt-register deleted file mode 100755 index ed0eaa7..0000000 --- a/snap/local/bin/restvirt-register +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec restvirt register "$@" diff --git a/snap/local/bin/unbound-wrapper b/snap/local/bin/unbound-wrapper deleted file mode 100755 index 5c544be..0000000 --- a/snap/local/bin/unbound-wrapper +++ /dev/null @@ -1,3 +0,0 @@ -#!/bin/sh -e - -exec unbound -d -p -c "$SNAP/etc/unbound/minivirt.conf" diff --git a/snap/local/etc/bird/minivirt.conf b/snap/local/etc/bird/minivirt.conf deleted file mode 100644 index 255aaa0..0000000 --- a/snap/local/etc/bird/minivirt.conf +++ /dev/null @@ -1,229 +0,0 @@ -# This is a basic configuration file, which contains boilerplate options and -# some basic examples. It allows the BIRD daemon to start but will not cause -# anything else to happen. -# -# Please refer to the BIRD User's Guide documentation, which is also available -# online at http://bird.network.cz/ in HTML format, for more information on -# configuring BIRD and adding routing protocols. - -# Configure logging -log syslog all; -# log "/var/log/bird.log" { debug, trace, info, remote, warning, error, auth, fatal, bug }; - -# Set router ID. It is a unique identification of your router, usually one of -# IPv4 addresses of the router. It is recommended to configure it explicitly. -# router id 198.51.100.1; - -# Turn on global debugging of all protocols (all messages or just selected classes) -# debug protocols all; -# debug protocols { events, states }; - -# Turn on internal watchdog -# watchdog warning 5 s; -# watchdog timeout 30 s; - -# You can define your own constants -# define my_asn = 65000; -# define my_addr = 198.51.100.1; - -# Tables master4 and master6 are defined by default -# ipv4 table master4; -# ipv6 table master6; - -# Define more tables, e.g. for policy routing or as MRIB -# ipv4 table mrib4; -# ipv6 table mrib6; - -# The Device protocol is not a real routing protocol. It does not generate any -# routes and it only serves as a module for getting information about network -# interfaces from the kernel. It is necessary in almost any configuration. -protocol device { -} - -# The direct protocol is not a real routing protocol. It automatically generates -# direct routes to all network interfaces. Can exist in as many instances as you -# wish if you want to populate multiple routing tables with direct routes. -protocol direct { - disabled; # Disable by default - ipv4; # Connect to default IPv4 table - ipv6; # ... and to default IPv6 table -} - -# The Kernel protocol is not a real routing protocol. Instead of communicating -# with other routers in the network, it performs synchronization of BIRD -# routing tables with the OS kernel. One instance per table. -protocol kernel { - merge paths on; - ipv4 { # Connect protocol to IPv4 table by channel -# table master4; # Default IPv4 table is master4 - import all; # Import to table, default is import all - export all; # Export to protocol. default is export none - }; -# learn; # Learn alien routes from the kernel -# kernel table 30068; # Kernel table to synchronize with (default: main) -} - -# Another instance for IPv6, skipping default options -protocol kernel { - ipv6 { export all; }; -} - -# Static routes (Again, there can be multiple instances, for different address -# families and to disable/enable various groups of static routes on the fly). -protocol static { - ipv4; # Again, IPv4 channel with default options - -# route 0.0.0.0/0 via 198.51.100.10; -# route 192.0.2.0/24 blackhole; -# route 10.0.0.0/8 unreachable; -# route 10.2.0.0/24 via "eth0"; -# # Static routes can be defined with optional attributes -# route 10.1.1.0/24 via 198.51.100.3 { rip_metric = 3; }; -# route 10.1.2.0/24 via 198.51.100.3 { ospf_metric1 = 100; }; -# route 10.1.3.0/24 via 198.51.100.4 { ospf_metric2 = 100; }; -} - -# Pipe protocol connects two routing tables. Beware of loops. -# protocol pipe { -# table master4; # No ipv4/ipv6 channel definition like in other protocols -# peer table mrib4; -# import all; # Direction peer table -> table -# export all; # Direction table -> peer table -# } - -# RIP example, both RIP and RIPng are supported -# protocol rip { -# ipv4 { -# # Export direct, static routes and ones from RIP itself -# import all; -# export where source ~ [ RTS_DEVICE, RTS_STATIC, RTS_RIP ]; -# }; -# interface "eth*" { -# update time 10; # Default period is 30 -# timeout time 60; # Default timeout is 180 -# authentication cryptographic; # No authentication by default -# password "hello" { algorithm hmac sha256; }; # Default is MD5 -# }; -# } - -# OSPF example, both OSPFv2 and OSPFv3 are supported -# protocol ospf v3 { -# ipv6 { -# import all; -# export where source = RTS_STATIC; -# }; -# area 0 { -# interface "eth*" { -# type broadcast; # Detected by default -# cost 10; # Interface metric -# hello 5; # Default hello perid 10 is too long -# }; -# interface "tun*" { -# type ptp; # PtP mode, avoids DR selection -# cost 100; # Interface metric -# hello 5; # Default hello perid 10 is too long -# }; -# interface "dummy0" { -# stub; # Stub interface, just propagate it -# }; -# }; -#} - -# Define simple filter as an example for BGP import filter -# See https://gitlab.labs.nic.cz/labs/bird/wikis/BGP_filtering for more examples -# filter rt_import -# { -# if bgp_path.first != 64496 then accept; -# if bgp_path.len > 64 then accept; -# if bgp_next_hop != from then accept; -# reject; -# } - -protocol bgp k8s { - local as 64513; - neighbor range 192.168.122.0/24 port 179 as 64513; - direct; - rr client; - passive on; - ipv4 { - add paths on; - import all; - export all; - }; -} - -# protocol bgp up { -# local port 178 as 64513; -# neighbor 192.168.122.111 as 64513; -# direct; -# ipv4 { -# add paths on; -# import all; -# export none; -# }; -# } - -# BGP example, explicit name 'uplink1' is used instead of default 'bgp1' -# protocol bgp uplink1 { -# description "My BGP uplink"; -# local 198.51.100.1 as 65000; -# neighbor 198.51.100.10 as 64496; -# hold time 90; # Default is 240 -# password "secret"; # Password used for MD5 authentication -# -# ipv4 { # regular IPv4 unicast (1/1) -# import filter rt_import; -# export where source ~ [ RTS_STATIC, RTS_BGP ]; -# }; -# -# ipv6 { # regular IPv6 unicast (2/1) -# import filter rt_import; -# export filter { # The same as 'where' expression above -# if source ~ [ RTS_STATIC, RTS_BGP ] -# then accept; -# else reject; -# }; -# }; -# -# ipv4 multicast { # IPv4 multicast topology (1/2) -# table mrib4; # explicit IPv4 table -# import filter rt_import; -# export all; -# }; -# -# ipv6 multicast { # IPv6 multicast topology (2/2) -# table mrib6; # explicit IPv6 table -# import filter rt_import; -# export all; -# }; -#} - -# Template example. Using templates to define IBGP route reflector clients. -# template bgp rr_clients { -# local 10.0.0.1 as 65000; -# neighbor as 65000; -# rr client; -# rr cluster id 1.0.0.1; -# -# ipv4 { -# import all; -# export where source = RTS_BGP; -# }; -# -# ipv6 { -# import all; -# export where source = RTS_BGP; -# }; -# } -# -# protocol bgp client1 from rr_clients { -# neighbor 10.0.1.1; -# } -# -# protocol bgp client2 from rr_clients { -# neighbor 10.0.2.1; -# } -# -# protocol bgp client3 from rr_clients { -# neighbor 10.0.3.1; -# } diff --git a/snap/local/etc/unbound/minivirt.conf b/snap/local/etc/unbound/minivirt.conf deleted file mode 100644 index 383e96a..0000000 --- a/snap/local/etc/unbound/minivirt.conf +++ /dev/null @@ -1,20 +0,0 @@ -server: - #logfile: "/var/log/unbound/unbound.log" - verbosity: 1 - chroot: "" - username: "" - port: 5354 - interface: 0.0.0.0 - interface: ::0 - access-control: 192.168.0.0/16 allow - access-control: 10.0.0.0/8 allow - access-control: fc00::/7 allow - do-ip6: yes - do-not-query-localhost: no - domain-insecure: "internal" - directory: "." -remote-control: - control-enable: no -stub-zone: - name: "internal" - stub-addr: 127.0.0.1@5353 diff --git a/snap/snapcraft.yaml b/snap/snapcraft.yaml deleted file mode 100644 index 8553d93..0000000 --- a/snap/snapcraft.yaml +++ /dev/null @@ -1,83 +0,0 @@ -name: minivirt # you probably want to 'snapcraft register ' -base: core22 # the base snap is the execution environment for this snap -version: 'git' # just for humans, typically '1.2+git' or '1.3.2' -summary: Single-line elevator pitch for your amazing snap # 79 char long summary -description: | - This is my-snap's description. You have a paragraph or two to tell the - most important story about your snap. Keep it under 100 words though, - we live in tweetspace and your description wants to look good in the snap - store. - -grade: stable # must be 'stable' to release into candidate/stable channels -confinement: strict # use 'strict' once you have the right plugs and slots - -apps: - controller: - command: bin/restvirt-controller - daemon: simple - plugs: - - network - - network-bind - unbound: - command: bin/unbound-wrapper - daemon: simple - after: - - controller - plugs: - - network - - network-bind - bird: - command: bin/bird-wrapper - daemon: simple - before: - - daemon - plugs: - - network - - network-bind - - network-control - birdc: - command: bin/birdc-wrapper - register: - command: bin/restvirt-register - plugs: - - network - - network-bind - deregister: - command: bin/restvirt-deregister - plugs: - - network - - network-bind - daemon: - command: bin/restvirt-daemon - daemon: simple - after: - - controller - restart-condition: always - restart-delay: 2s - plugs: - - libvirt - - network - - network-bind - - network-control - - firewall-control - -parts: - wrapper: - plugin: dump - source: snap/local/ - stage-packages: - - gettext-base - minivirt: - # See 'snapcraft plugins' - plugin: python - source: ./ - build-packages: - - git - - libvirt-dev - - pkg-config - stage-packages: - - libvirt0 - - libbrotli1 # kill me please - - libnftables1 - - unbound - - bird2 diff --git a/virtuerl/src/virtuerl.app.src b/src/virtuerl.app.src similarity index 100% rename from virtuerl/src/virtuerl.app.src rename to src/virtuerl.app.src diff --git a/virtuerl/src/virtuerl_api.erl b/src/virtuerl_api.erl similarity index 100% rename from virtuerl/src/virtuerl_api.erl rename to src/virtuerl_api.erl diff --git a/virtuerl/src/virtuerl_app.erl b/src/virtuerl_app.erl similarity index 100% rename from virtuerl/src/virtuerl_app.erl rename to src/virtuerl_app.erl diff --git a/virtuerl/src/virtuerl_ghac.erl b/src/virtuerl_ghac.erl similarity index 100% rename from virtuerl/src/virtuerl_ghac.erl rename to src/virtuerl_ghac.erl diff --git a/virtuerl/src/virtuerl_img.erl b/src/virtuerl_img.erl similarity index 100% rename from virtuerl/src/virtuerl_img.erl rename to src/virtuerl_img.erl diff --git a/virtuerl/src/virtuerl_ipam.erl b/src/virtuerl_ipam.erl similarity index 100% rename from virtuerl/src/virtuerl_ipam.erl rename to src/virtuerl_ipam.erl diff --git a/virtuerl/src/virtuerl_mgt.erl b/src/virtuerl_mgt.erl similarity index 100% rename from virtuerl/src/virtuerl_mgt.erl rename to src/virtuerl_mgt.erl diff --git a/virtuerl/src/virtuerl_net.erl b/src/virtuerl_net.erl similarity index 100% rename from virtuerl/src/virtuerl_net.erl rename to src/virtuerl_net.erl diff --git a/virtuerl/src/virtuerl_pubsub.erl b/src/virtuerl_pubsub.erl similarity index 100% rename from virtuerl/src/virtuerl_pubsub.erl rename to src/virtuerl_pubsub.erl diff --git a/virtuerl/src/virtuerl_qemu.erl b/src/virtuerl_qemu.erl similarity index 100% rename from virtuerl/src/virtuerl_qemu.erl rename to src/virtuerl_qemu.erl diff --git a/virtuerl/src/virtuerl_qmp.erl b/src/virtuerl_qmp.erl similarity index 100% rename from virtuerl/src/virtuerl_qmp.erl rename to src/virtuerl_qmp.erl diff --git a/virtuerl/src/virtuerl_sup.erl b/src/virtuerl_sup.erl similarity index 100% rename from virtuerl/src/virtuerl_sup.erl rename to src/virtuerl_sup.erl diff --git a/virtuerl/src/virtuerl_ui.erl b/src/virtuerl_ui.erl similarity index 100% rename from virtuerl/src/virtuerl_ui.erl rename to src/virtuerl_ui.erl diff --git a/virtuerl/src/virtuerl_util.erl b/src/virtuerl_util.erl similarity index 100% rename from virtuerl/src/virtuerl_util.erl rename to src/virtuerl_util.erl diff --git a/virtuerl/src/virtuerl_vnc.erl b/src/virtuerl_vnc.erl similarity index 100% rename from virtuerl/src/virtuerl_vnc.erl rename to src/virtuerl_vnc.erl diff --git a/virtuerl/src/virtuerl_vnc_proxy.erl b/src/virtuerl_vnc_proxy.erl similarity index 100% rename from virtuerl/src/virtuerl_vnc_proxy.erl rename to src/virtuerl_vnc_proxy.erl diff --git a/virtuerl/test/ipam.erl b/test/ipam.erl similarity index 100% rename from virtuerl/test/ipam.erl rename to test/ipam.erl diff --git a/virtuerl/test/scheduler.erl b/test/scheduler.erl similarity index 100% rename from virtuerl/test/scheduler.erl rename to test/scheduler.erl diff --git a/virtuerl/test/virtuerl_SUITE.erl b/test/virtuerl_SUITE.erl similarity index 100% rename from virtuerl/test/virtuerl_SUITE.erl rename to test/virtuerl_SUITE.erl diff --git a/tests/integration/test_integration.py b/tests/integration/test_integration.py deleted file mode 100644 index fa437d2..0000000 --- a/tests/integration/test_integration.py +++ /dev/null @@ -1,211 +0,0 @@ -import datetime -import io -from time import sleep -from urllib.parse import urljoin -from urllib.request import urlopen - -import grpc -import pytest -from fabric import Connection -from paramiko.ed25519key import Ed25519Key - -from minivirt import controller_pb2_grpc, domain_pb2, port_forwarding_pb2, volume_pb2 - - -@pytest.fixture -def client(): - channel = grpc.secure_channel( - "localhost:8093", - grpc.ssl_channel_credentials( - root_certificates=b"""-----BEGIN CERTIFICATE----- -MIICCjCCAY+gAwIBAgIUSl7KWjtgvG9rNMz7hhYRKy5LsB8wCgYIKoZIzj0EAwIw -RDELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjERMA8GA1UECgwIbWluaXZp -cnQxETAPBgNVBAMMCG1pbml2aXJ0MB4XDTIzMDcwODIzMjUyMFoXDTMzMDcwNTIz -MjUyMFowRDELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjERMA8GA1UECgwI -bWluaXZpcnQxETAPBgNVBAMMCG1pbml2aXJ0MHYwEAYHKoZIzj0CAQYFK4EEACID -YgAEI3nOFzsWO3w8qGLSjDSiX3OWCH7qBRcTjt/luPjXLqe3DVcFQPLYN31PaggR -o0jCjrKklxqtzHmmMdMRnyoRPbQOQPRa9N177a2s97M5ZJQVkeFL8WRUf7x1P0Cd -SZvco0IwQDAdBgNVHQ4EFgQUde9ormRTZys4Nt81qAPcSm1qQWMwDwYDVR0TAQH/ -BAUwAwEB/zAOBgNVHQ8BAf8EBAMCAYYwCgYIKoZIzj0EAwIDaQAwZgIxAJTpUOUz -RJwMLNUEa4qIgdamMuqyl5h6ghT9zX5BLsX3cFs+MqJ/J0HcKDJd81lVlQIxAPCG -hy/zgj6wy28S8GWe8KdbZ73BJtC5MyOu6hHD9EpZ1hT8K3q0VIwMEyUMmbv3Xw== ------END CERTIFICATE----- -""", - certificate_chain=b"""-----BEGIN CERTIFICATE----- -MIICeTCCAf+gAwIBAgIUVG1gWhFwRQ5kzxwRzF6V5h6D8ZYwCgYIKoZIzj0EAwIw -RDELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjERMA8GA1UECgwIbWluaXZp -cnQxETAPBgNVBAMMCG1pbml2aXJ0MB4XDTIzMDcwODIzMzA0MloXDTI1MDcwNzIz -MzA0MlowRDELMAkGA1UEBhMCREUxDzANBgNVBAgMBkJlcmxpbjERMA8GA1UECgwI -bWluaXZpcnQxETAPBgNVBAMMCG1pbml2aXJ0MHYwEAYHKoZIzj0CAQYFK4EEACID -YgAEHWV9eL3/egpqcgTaMDPWga2xpfTZCc66yNxkVGPsw5BWE/EXvWtuUCjDmHWo -HOdrbt7iI9lA9VnSwlC9PeIvX4lK2dXNOpn3GJlZ8JkjpZZBg0mxaUt6vQMyGSco -cOOAo4GxMIGuMB8GA1UdIwQYMBaAFHXvaK5kU2crODbfNagD3EptakFjMAwGA1Ud -EwEB/wQCMAAwDgYDVR0PAQH/BAQDAgWgMCAGA1UdJQEB/wQWMBQGCCsGAQUFBwMB -BggrBgEFBQcDAjAsBgNVHREEJTAjgglsb2NhbGhvc3SHBH8AAAGHEAAAAAAAAAAA -AAAAAAAAAAEwHQYDVR0OBBYEFDtlzMapZ4eV0/m8ina1GM3biELeMAoGCCqGSM49 -BAMCA2gAMGUCMECXLmHsWMTaFRK+qWaBRZMLuhFNixMsSmmHHIqGlvIrWFa5MiN6 -RaZ7aTGa/HMKZAIxAPRJZ11Vp1BNBszSiswk32hsck4JP9h1hn00IMu33iK0+q22 -Jv73oZy3l4gQmLlCDg== ------END CERTIFICATE----- -""", - private_key=b"""-----BEGIN PRIVATE KEY----- -MIG2AgEAMBAGByqGSM49AgEGBSuBBAAiBIGeMIGbAgEBBDCIJQuTNENeEnhjCtdV -GXoFgh69LQ+Ms5B/i0jWMSqMALL26uG6NNM4nvHgIMbChKGhZANiAAQdZX14vf96 -CmpyBNowM9aBrbGl9NkJzrrI3GRUY+zDkFYT8Re9a25QKMOYdagc52tu3uIj2UD1 -WdLCUL094i9fiUrZ1c06mfcYmVnwmSOllkGDSbFpS3q9AzIZJyhw44A= ------END PRIVATE KEY----- -""", - ), - ) - return controller_pb2_grpc.ControllerServiceStub(channel) - - -def test_create_domain_ipv4_linux(client: controller_pb2_grpc.ControllerServiceStub): - network = client.CreateNetwork( - domain_pb2.CreateNetworkRequest( - network=domain_pb2.Network( - name="restvirt", - cidr="192.168.69.0/24", - ) - ) - ) - dom = client.CreateDomain( - domain_pb2.CreateDomainRequest( - domain=domain_pb2.Domain( - name="test", - vcpu=1, - memory=512, - private_ip="192.168.69.69", - network=network.uuid, - user_data="""#cloud-config""", - ), - ) - ) - dom = client.GetDomain(domain_pb2.GetDomainRequest(uuid=dom.uuid)) - assert dom.private_ip == "192.168.69.69" - - client.DeleteDomain(domain_pb2.DeleteDomainRequest(uuid=dom.uuid)) - client.DeleteNetwork(domain_pb2.DeleteNetworkRequest(uuid=network.uuid)) - - -def test_create_domain_linux(client: controller_pb2_grpc.ControllerServiceStub): - network = client.CreateNetwork( - domain_pb2.CreateNetworkRequest( - network=domain_pb2.Network( - name="restvirt", - cidr="192.168.69.0/24", - cidr6="fd8d:dd47:05bc:5307::/64", - ) - ) - ) - dom = client.CreateDomain( - domain_pb2.CreateDomainRequest( - domain=domain_pb2.Domain( - name="test", - vcpu=1, - memory=512, - private_ip="192.168.69.69", - ipv6_address="fd8d:dd47:05bc:5307::10", - network=network.uuid, - user_data="""#cloud-config - -users: - - name: tester - shell: /bin/bash - sudo: ALL=(ALL) NOPASSWD:ALL - ssh_authorized_keys: - - ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAIBDCT3LrJenezXzP9T6519IgpVCP1uv6f5iQwZ+IDdFc - -packages: - - nginx - -runcmd: - - service nginx restart -""", - ), - ) - ) - - dom = client.GetDomain(domain_pb2.GetDomainRequest(uuid=dom.uuid)) - assert dom.ipv6_address == "fd8d:dd47:05bc:5307::10" - - fwd = port_forwarding_pb2.PortForwarding( - protocol="tcp", - source_port=8080, - target_ip="192.168.69.69", - target_port=80, - ) - client.PutPortForwarding(port_forwarding_pb2.PutPortForwardingRequest(port_forwarding=fwd)) - - response = wait_for_http("http://192.168.69.1:8080") - assert "Welcome to nginx!" in response - - private_ssh_key = """-----BEGIN OPENSSH PRIVATE KEY----- -b3BlbnNzaC1rZXktdjEAAAAABG5vbmUAAAAEbm9uZQAAAAAAAAABAAAAMwAAAAtzc2gtZW -QyNTUxOQAAACAQwk9y6yXp3s18z/U+udfSIKVQj9br+n+YkMGfiA3RXAAAAJhEeSndRHkp -3QAAAAtzc2gtZWQyNTUxOQAAACAQwk9y6yXp3s18z/U+udfSIKVQj9br+n+YkMGfiA3RXA -AAAEC9jx0pxfKwyPq3RpOsCef7UA2pqBzAj2+bqVTix2f0fRDCT3LrJenezXzP9T6519Ig -pVCP1uv6f5iQwZ+IDdFcAAAAFWlseWFASWx5YXMtaU1hYy5sb2NhbA== ------END OPENSSH PRIVATE KEY----- -""" - with io.StringIO(private_ssh_key) as f: - pkey = Ed25519Key.from_private_key(f) - conn = Connection("192.168.69.69", "tester", connect_kwargs={"pkey": pkey}) - conn.config.run.in_stream = False - - old_root_vol_size = int(conn.run("lsblk /dev/vda -bndo SIZE").stdout) - assert old_root_vol_size == 20 * 1024**3 - - volumes = client.ListVolumes(volume_pb2.ListVolumesRequest()) - volumes = {v.name: v for v in volumes.volumes} - root_vol_name = f"{dom.name}-root.qcow2" - assert root_vol_name in volumes - - wait_until_stopped(client, dom.uuid) - client.UpdateVolume( - volume_pb2.UpdateVolumeRequest( - volume=volume_pb2.Volume(id=root_vol_name, size=30 * 1024**3) - ) - ) - - client.StartDomain(domain_pb2.StartDomainRequest(uuid=dom.uuid)) - response = wait_for_http("http://192.168.69.1:8080") - assert "Welcome to nginx!" in response - response = wait_for_http("http://[fd8d:dd47:05bc:5307::10]") - assert "Welcome to nginx!" in response - - new_root_vol_size = int(conn.run("lsblk /dev/vda -bndo SIZE").stdout) - assert new_root_vol_size == 30 * 1024**3 - - client.DeletePortForwarding( - port_forwarding_pb2.PortForwardingIdentifier(protocol="tcp", source_port=8080) - ) - client.DeleteDomain(domain_pb2.DeleteDomainRequest(uuid=dom.uuid)) - client.DeleteNetwork(domain_pb2.DeleteNetworkRequest(uuid=network.uuid)) - - -def wait_for_http(server, path="/", timeout=datetime.timedelta(seconds=180)): - end_time = datetime.datetime.now() + timeout - while True: - try: - with urlopen(urljoin(server, path)) as resp: - return resp.read().decode() - except: - now = datetime.datetime.now() - if now >= end_time: - raise Exception("Timed out") - sleep(min((end_time - now).total_seconds(), 10)) - - -def wait_until_stopped(client, domain_uuid, timeout=datetime.timedelta(seconds=180)): - end_time = datetime.datetime.now() + timeout - while True: - dom = client.GetDomain(domain_pb2.GetDomainRequest(uuid=domain_uuid)) - if dom.state == "SHUTOFF": - break - - client.StopDomain(domain_pb2.StopDomainRequest(uuid=domain_uuid)) - now = datetime.datetime.now() - if now >= end_time: - raise Exception("Timed out") - sleep(min((end_time - now).total_seconds(), 10)) diff --git a/tests/unit/__init__.py b/tests/unit/__init__.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py deleted file mode 100644 index bce86d3..0000000 --- a/tests/unit/conftest.py +++ /dev/null @@ -1,231 +0,0 @@ -import contextlib -import sys -from concurrent import futures - -import grpc -import pytest -from google.protobuf import empty_pb2 -from sqlalchemy import create_engine, event -from sqlalchemy.engine import Engine -from sqlalchemy.orm import sessionmaker -from sqlalchemy.pool import StaticPool - -from minivirt import controller_pb2_grpc, daemon_pb2_grpc, host_pb2, host_pb2_grpc -from minivirt.controller import Controller -from minivirt.dns_controller import DNSController -from minivirt.host import HostController, HostService -from minivirt.models import Base - -OPERATING_SYSTEMS = {"darwin", "linux", "windows"} - - -def pytest_addoption(parser): - parser.addoption("--pool-dir", default="/data/restvirt") - - -@pytest.fixture(scope="session") -def pool_dir(pytestconfig): - return pytestconfig.getoption("pool_dir") - - -def pytest_configure(config): - for os in OPERATING_SYSTEMS: - config.addinivalue_line("markers", f"{os}: mark tests to only run on {os} operating system") - - -def pytest_runtest_setup(item): - supported_platforms = OPERATING_SYSTEMS.intersection(mark.name for mark in item.iter_markers()) - plat = sys.platform - if supported_platforms and plat not in supported_platforms: - pytest.skip("cannot run on platform {}".format(plat)) - - -def pytest_collection_modifyitems(items): - for item in items: - os = item.nodeid.split("_")[-1] - if os in OPERATING_SYSTEMS: - item.add_marker(os) - - -@event.listens_for(Engine, "connect") -def set_sqlite_pragma(dbapi_connection, connection_record): - cursor = dbapi_connection.cursor() - cursor.execute("PRAGMA foreign_keys=ON") - cursor.close() - - -@pytest.fixture -def engine(): - engine = create_engine( - "sqlite:///:memory:", - connect_args={"check_same_thread": False}, - poolclass=StaticPool, - echo=True, - future=True, - ) - Base.metadata.create_all(engine) - yield engine - Base.metadata.drop_all(engine) - - -@pytest.fixture -def session_factory(engine): - return sessionmaker(engine, future=True) - - -@pytest.fixture -def dns_controller(session_factory): - return DNSController(session_factory) - - -class DaemonDummy(daemon_pb2_grpc.DaemonServiceServicer): - def SyncRoutes(self, request, context): - return empty_pb2.Empty() - - -@pytest.fixture -def controller_channel(session_factory, dns_controller): - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[]) - port = server.add_insecure_port("localhost:0") - channel = grpc.insecure_channel(f"localhost:{port}") - - host_controller = HostController(session_factory) - controller_pb2_grpc.add_ControllerServiceServicer_to_server( - Controller(session_factory, host_controller, dns_controller), - server, - ) - host_pb2_grpc.add_HostServiceServicer_to_server( - HostService(host_controller, session_factory), server - ) - - dns_controller.start() - server.start() - yield channel - server.stop(1) - dns_controller.stop() - - -@pytest.fixture -def host_client(controller_channel): - return host_pb2_grpc.HostServiceStub(controller_channel) - - -@pytest.fixture -def controller_client_dummy(controller_channel, host_client): - daemon = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[]) - daemon_port = daemon.add_insecure_port("localhost:0") - - daemon_pb2_grpc.add_DaemonServiceServicer_to_server(DaemonDummy(), daemon) - - token = host_client.CreateBootstrapToken(host_pb2.CreateBootstrapTokenRequest()).token - host_client.Register( - host_pb2.RegisterHostRequest( - token=token, - host=host_pb2.Host( - name="test", - address=f"localhost:{daemon_port}", - ), - ) - ) - - daemon.start() - yield controller_pb2_grpc.ControllerServiceStub(controller_channel) - daemon.stop(1) - - -@pytest.fixture -def controller_client(session_factory, controller_channel, host_client): - from minivirt.daemon import DaemonService - from minivirt.port_forwarding import IPTablesPortForwardingSynchronizer - from minivirt.utils import UnaryUnaryInterceptor - - daemon = grpc.server( - futures.ThreadPoolExecutor(max_workers=10), interceptors=[UnaryUnaryInterceptor()] - ) - daemon_port = daemon.add_insecure_port("localhost:0") - - daemon_service = DaemonService( - session_factory, - IPTablesPortForwardingSynchronizer( - controller_pb2_grpc.ControllerServiceStub(controller_channel), - ), - controller_channel, - ) - daemon_pb2_grpc.add_DaemonServiceServicer_to_server( - daemon_service, - daemon, - ) - daemon_service.sync() - - token = host_client.CreateBootstrapToken(host_pb2.CreateBootstrapTokenRequest()).token - host_client.Register( - host_pb2.RegisterHostRequest( - token=token, - host=host_pb2.Host( - name="test", - address=f"localhost:{daemon_port}", - ), - ) - ) - - daemon.start() - yield controller_pb2_grpc.ControllerServiceStub(controller_channel) - daemon.stop(1) - - -@contextlib.contextmanager -def dummy_controller(dns_port=53): - engine = create_engine( - "sqlite:///:memory:", - connect_args={"check_same_thread": False}, - poolclass=StaticPool, - echo=False, - future=True, - ) - Base.metadata.create_all(engine) - session_factory = sessionmaker(engine) - - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[]) - port = server.add_insecure_port("localhost:0") - controller_channel = grpc.insecure_channel(f"localhost:{port}") - - dns_controller = DNSController(session_factory) - - host_controller = HostController(session_factory) - controller_pb2_grpc.add_ControllerServiceServicer_to_server( - Controller(session_factory, host_controller, dns_controller), - server, - ) - host_pb2_grpc.add_HostServiceServicer_to_server( - HostService(host_controller, session_factory), server - ) - - dns_controller.start(dns_port) - server.start() - - daemon = grpc.server(futures.ThreadPoolExecutor(max_workers=10), interceptors=[]) - daemon_port = daemon.add_insecure_port("localhost:0") - - daemon_pb2_grpc.add_DaemonServiceServicer_to_server(DaemonDummy(), daemon) - - host_client = host_pb2_grpc.HostServiceStub(controller_channel) - token = host_client.CreateBootstrapToken(host_pb2.CreateBootstrapTokenRequest()).token - host_client.Register( - host_pb2.RegisterHostRequest( - token=token, - host=host_pb2.Host( - name="test", - address=f"localhost:{daemon_port}", - ), - ) - ) - - daemon.start() - - try: - yield controller_pb2_grpc.ControllerServiceStub(controller_channel) - finally: - daemon.stop(1) - server.stop(1) - dns_controller.stop() - Base.metadata.drop_all(engine) diff --git a/tests/unit/test_dns.py b/tests/unit/test_dns.py deleted file mode 100644 index e00ca7a..0000000 --- a/tests/unit/test_dns.py +++ /dev/null @@ -1,151 +0,0 @@ -import grpc -import pytest -from dnslib import CLASS, QTYPE, RCODE, RR, DNSQuestion, DNSRecord -from sqlalchemy import create_engine -from sqlalchemy.orm import sessionmaker -from sqlalchemy.pool import StaticPool - -from minivirt import dns_pb2, dns_pb2_grpc, models -from minivirt.dns_controller import DNSController -from minivirt.models import Base - -from .conftest import dummy_controller - - -class DNSClient: - def __init__(self, host="localhost", port=53): - self.host = host - self.port = port - - def query(self, name, qtype, qclass="IN"): - q = DNSRecord(q=DNSQuestion(name, getattr(QTYPE, qtype), getattr(CLASS, qclass))) - raw = q.send(self.host, self.port) - return DNSRecord.parse(raw) - - -@pytest.fixture -def dns_client(dns_controller): - yield DNSClient() - - -@pytest.fixture -def client(controller_client_dummy): - return controller_client_dummy - - -def test_dns_put(client: dns_pb2_grpc.DNSStub, dns_client): - client.PutDNSRecord( - dns_pb2.PutDNSRecordRequest( - dns_record=dns_pb2.DNSRecord( - name="mydomain.internal", - type="A", - ttl=60, - records=["192.168.1.1"], - ) - ) - ) - records = client.ListDNSRecords(dns_pb2.ListDNSRecordsRequest()).dns_records - assert len(records) == 1 - assert dns_client.query("mydomain.internal", "A").rr == RR.fromZone( - "mydomain.internal. 60 IN A 192.168.1.1" - ) - - client.PutDNSRecord( - dns_pb2.PutDNSRecordRequest( - dns_record=dns_pb2.DNSRecord( - name="mydomain.internal", - type="A", - ttl=120, - records=["192.168.1.2"], - ) - ) - ) - records = client.ListDNSRecords(dns_pb2.ListDNSRecordsRequest()).dns_records - assert len(records) == 1 - assert dns_client.query("mydomain.internal", "A").rr == RR.fromZone( - "mydomain.internal. 120 IN A 192.168.1.2" - ) - - -def test_dns_get(client: dns_pb2_grpc.DNSStub): - client.PutDNSRecord( - dns_pb2.PutDNSRecordRequest( - dns_record=dns_pb2.DNSRecord( - name="mydomain.internal", - type="A", - ttl=120, - records=["192.168.1.2"], - ) - ) - ) - - record = client.GetDNSRecord(dns_pb2.DNSRecordIdentifier(name="mydomain.internal", type="A")) - assert record.records == ["192.168.1.2"] - - with pytest.raises(grpc.RpcError) as e: - client.GetDNSRecord(dns_pb2.DNSRecordIdentifier(name="non-existing.internal", type="A")) - assert e.value.code() == grpc.StatusCode.NOT_FOUND - - -# def test_dns_forward(client: dns_pb2_grpc.DNSStub, dns_client): -# assert dns_client.query("google.com", "A").header.rcode == RCODE.NOERROR -# assert dns_client.query("non-existing.internal", "A").header.rcode == RCODE.NXDOMAIN - - -def test_dns_delete(client: dns_pb2_grpc.DNSStub): - client.PutDNSRecord( - dns_pb2.PutDNSRecordRequest( - dns_record=dns_pb2.DNSRecord( - name="mydomain.internal", - type="A", - ttl=120, - records=["192.168.1.2"], - ) - ) - ) - - client.DeleteDNSRecord(dns_pb2.DNSRecordIdentifier(name="mydomain.internal", type="A")) - records = client.ListDNSRecords(dns_pb2.ListDNSRecordsRequest()).dns_records - assert len(records) == 0 - - -def test_dns_delegation(): - engine = create_engine( - "sqlite:///:memory:", - connect_args={"check_same_thread": False}, - poolclass=StaticPool, - echo=False, - future=True, - ) - Base.metadata.create_all(engine) - sessfact = sessionmaker(engine) - upstream_dns = DNSController(sessfact) - with sessfact() as session: - session.merge( - models.DNSRecord(name="test.delegated.internal", type="A", records=["192.168.11.11"]) - ) - session.commit() - upstream_dns.start() - - with dummy_controller(dns_port=30053) as client: - client.PutDNSRecord( - dns_pb2.PutDNSRecordRequest( - dns_record=dns_pb2.DNSRecord( - name="delegated.internal", - type="NS", - ttl=120, - records=["127.0.0.1"], - ) - ) - ) - - dns_client = DNSClient(port=30053) - resp = dns_client.query("test.delegated.internal", "A") - assert len(resp.ar) == 0 - assert len(resp.auth) == 1 - assert resp.auth[0].rtype == QTYPE.NS - assert resp.auth[0].rname == "delegated.internal" - assert str(resp.auth[0].rdata) == "127.0.0.1." - assert not resp.header.ra - - upstream_dns.stop() diff --git a/tests/unit/test_domain.py b/tests/unit/test_domain.py deleted file mode 100644 index 3558f2e..0000000 --- a/tests/unit/test_domain.py +++ /dev/null @@ -1,110 +0,0 @@ -import datetime -from time import sleep -from urllib.parse import urljoin -from urllib.request import urlopen - -import pytest - -from minivirt import domain_pb2, domain_pb2_grpc - - -@pytest.fixture -def conn(): - import libvirt - - conn = libvirt.open("qemu:///system?socket=/var/run/libvirt/libvirt-sock") - yield conn - conn.close() - - -@pytest.fixture -def client(controller_client, pool_dir, conn): - yield controller_client - - img_pool = conn.storagePoolLookupByName("restvirtimages") - for vol in img_pool.listAllVolumes(): - vol.delete() - img_pool.destroy() - img_pool.delete() - img_pool.undefine() - - for dom in conn.listAllDomains(): - try: - dom.destroy() - except: - pass - dom.undefine() - - -def test_libvirt_linux(): - import libvirt - - libvirt.getVersion() - - -def test_network_linux(client: domain_pb2_grpc.DomainServiceStub): - network = client.CreateNetwork( - domain_pb2.CreateNetworkRequest( - host="test", - network=domain_pb2.Network( - name="restvirt", - cidr="192.168.69.0/24", - ), - ) - ) - - resp = client.GetNetwork(domain_pb2.GetNetworkRequest(host="test", uuid=network.uuid)) - assert resp.name == "restvirt" - assert resp.cidr == "192.168.69.0/24" - - client.DeleteNetwork(domain_pb2.DeleteNetworkRequest(host="test", uuid=network.uuid)) - - -# def test_create_domain_linux(client: domain_pb2_grpc.DomainServiceStub): -# network = client.CreateNetwork( -# domain_pb2.CreateNetworkRequest( -# network=domain_pb2.Network( -# name="restvirt", -# cidr="192.168.69.0/24", -# ) -# ) -# ) -# dom = client.CreateDomain( -# domain_pb2.CreateDomainRequest( -# host="test", -# domain=domain_pb2.Domain( -# name="test", -# vcpu=1, -# memory=512, -# private_ip="192.168.69.69", -# network=network.name, -# user_data="""#cloud-config -# -# packages: -# - nginx -# -# runcmd: -# - service nginx restart -# """, -# ), -# ) -# ) -# -# response = wait_for_http("http://192.168.69.69") -# assert "Welcome to nginx!" in response -# -# client.DeleteDomain(domain_pb2.DeleteDomainRequest(host="test", uuid=dom.uuid)) -# client.DeleteNetwork(domain_pb2.DeleteNetworkRequest(uuid=network.uuid)) -# -# -# def wait_for_http(server, path="/", timeout=datetime.timedelta(seconds=180)): -# end_time = datetime.datetime.now() + timeout -# while True: -# try: -# with urlopen(urljoin(server, path)) as resp: -# return resp.read().decode() -# except: -# now = datetime.datetime.now() -# if now >= end_time: -# raise Exception("Timed out") -# sleep(min((end_time - now).total_seconds(), 10)) diff --git a/tests/unit/test_host.py b/tests/unit/test_host.py deleted file mode 100644 index ab8344d..0000000 --- a/tests/unit/test_host.py +++ /dev/null @@ -1,52 +0,0 @@ -from datetime import datetime, timedelta - -import grpc -import pytest - -from minivirt import host_pb2, host_pb2_grpc - - -@pytest.fixture -def client(host_client): - return host_client - - -def test_register(client: host_pb2_grpc.HostServiceStub): - assert len(client.ListHosts(host_pb2.ListHostsRequest()).hosts) == 0 - - token = client.CreateBootstrapToken(host_pb2.CreateBootstrapTokenRequest()).token - client.Register( - host_pb2.RegisterHostRequest( - token=token, - host=host_pb2.Host( - name="yourmom", - address="localhost:8333", - ), - ) - ) - hosts = client.ListHosts(host_pb2.ListHostsRequest()).hosts - assert len(hosts) == 1 - host = hosts[0] - assert host.address == "localhost:8333" - - client.Deregister(host_pb2.Host(name="yourmom")) - assert len(client.ListHosts(host_pb2.ListHostsRequest()).hosts) == 0 - - -def test_register_expired(client: host_pb2_grpc.HostServiceStub): - token = client.CreateBootstrapToken( - host_pb2.CreateBootstrapTokenRequest( - expires_at=(datetime.utcnow() - timedelta(seconds=10)).isoformat() - ) - ).token - with pytest.raises(grpc.RpcError) as e: - client.Register( - host_pb2.RegisterHostRequest( - token=token, - host=host_pb2.Host( - name="yourmom", - address="localhost:8333", - ), - ) - ) - assert e.value.code() == grpc.StatusCode.INVALID_ARGUMENT diff --git a/tests/unit/test_image.py b/tests/unit/test_image.py deleted file mode 100644 index f445200..0000000 --- a/tests/unit/test_image.py +++ /dev/null @@ -1,35 +0,0 @@ -from ipaddress import ip_address, ip_network - -import pytest - -from minivirt.image import ( - create_cloud_config_image, - read_ip_from_cloud_config_image, - read_user_data_from_cloud_config_image, -) - - -@pytest.fixture -def data(): - return create_cloud_config_image( - domain_id="domain_id", - user_data="hello world", - mac="mac_address", - network=ip_network("192.168.1.0/24"), - network6=ip_network("fd8d:dd47:05bc:5307::/64"), - address=ip_address("192.168.1.43"), - address6=ip_address("fd8d:dd47:05bc:5307::10"), - gateway=ip_address("192.168.1.1"), - gateway6=ip_address("fd8d:dd47:05bc:5307::1"), - name="name", - ) - - -def test_read_ip(data): - ip = read_ip_from_cloud_config_image(data) - assert ip == "192.168.1.43" - - -def test_read_user_data(data): - user_data = read_user_data_from_cloud_config_image(data) - assert user_data == "hello world" diff --git a/tests/unit/test_port_forwarding.py b/tests/unit/test_port_forwarding.py deleted file mode 100644 index 8a7c9a7..0000000 --- a/tests/unit/test_port_forwarding.py +++ /dev/null @@ -1,141 +0,0 @@ -import grpc -import pytest - -from minivirt import port_forwarding_pb2, port_forwarding_pb2_grpc - - -@pytest.fixture -def client(controller_client): - return controller_client - - -def test_port_forwarding_get_linux(client: port_forwarding_pb2_grpc.PortForwardingServiceStub): - identifier = port_forwarding_pb2.PortForwardingIdentifier( - host="test", protocol="tcp", source_port=2020 - ) - with pytest.raises(grpc.RpcError) as e: - client.GetPortForwarding(identifier) - assert e.value.code() == grpc.StatusCode.NOT_FOUND - - fwd = port_forwarding_pb2.PortForwarding( - protocol="tcp", - source_port=2020, - target_ip="192.168.1.69", - target_port=2021, - ) - client.PutPortForwarding( - port_forwarding_pb2.PutPortForwardingRequest(host="test", port_forwarding=fwd) - ) - forwarding = client.GetPortForwarding(identifier) - assert forwarding.target_ip == "192.168.1.69" - assert forwarding.target_port == 2021 - - -def test_port_forwarding_put_linux(client: port_forwarding_pb2_grpc.PortForwardingServiceStub): - fwd = port_forwarding_pb2.PortForwarding( - protocol="tcp", - source_port=2020, - target_ip="192.168.1.69", - target_port=2021, - ) - client.PutPortForwarding( - port_forwarding_pb2.PutPortForwardingRequest(host="test", port_forwarding=fwd) - ) - fwds = client.ListPortForwardings( - port_forwarding_pb2.ListPortForwardingsRequest(host="test") - ).port_forwardings - assert len(fwds) == 1 - assert fwds[0].target_ip == "192.168.1.69" - - fwds = client.ListPortForwardings( - port_forwarding_pb2.ListPortForwardingsRequest(host="test") - ).port_forwardings - assert len(fwds) == 1 - assert fwds[0].target_ip == "192.168.1.69" - - fwd.target_ip = "192.168.1.70" - client.PutPortForwarding( - port_forwarding_pb2.PutPortForwardingRequest(host="test", port_forwarding=fwd) - ) - fwds = client.ListPortForwardings( - port_forwarding_pb2.ListPortForwardingsRequest(host="test") - ).port_forwardings - assert len(fwds) == 1 - assert fwds[0].target_ip == "192.168.1.70" - - -def test_port_forwarding_linux(client: port_forwarding_pb2_grpc.PortForwardingServiceStub): - import nftables - - fwd = port_forwarding_pb2.PortForwarding( - protocol="tcp", - source_port=2020, - target_ip="192.168.1.69", - target_port=2021, - ) - client.PutPortForwarding( - port_forwarding_pb2.PutPortForwardingRequest(host="test", port_forwarding=fwd) - ) - - table_name = "restvirt" - nft = nftables.Nftables() - nft.set_json_output(True) - nft.set_stateless_output(True) - - _, output, _ = nft.json_cmd( - { - "nftables": [ - { - "list": { - "table": { - "family": "inet", - "name": table_name, - } - } - } - ] - } - ) - output = output["nftables"] - all_rules = [rule["rule"] for rule in output if "rule" in rule] - - rules = [rule for rule in all_rules if rule["chain"] == "forward"] - assert len(rules) == 1 - rule = rules[0] - assert rule["expr"] == [ - { - "match": { - "left": {"payload": {"field": "dport", "protocol": "tcp"}}, - "op": "==", - "right": 2021, - } - }, - { - "match": { - "left": {"payload": {"field": "daddr", "protocol": "ip"}}, - "op": "==", - "right": "192.168.1.69", - } - }, - {"counter": None}, - {"accept": None}, - ] - - rules = [rule for rule in all_rules if rule["chain"] == "prerouting"] - assert len(rules) == 1 - rule = rules[0] - assert rule["expr"] == [ - { - "match": { - "left": {"payload": {"field": "dport", "protocol": "tcp"}}, - "op": "==", - "right": 2020, - } - }, - {"counter": None}, - {"dnat": {"addr": "192.168.1.69", "family": "ip", "port": 2021}}, - ] - - client.DeletePortForwarding( - port_forwarding_pb2.PortForwardingIdentifier(host="test", protocol="tcp", source_port=2020) - ) diff --git a/tests/unit/test_route.py b/tests/unit/test_route.py deleted file mode 100644 index 3a8f363..0000000 --- a/tests/unit/test_route.py +++ /dev/null @@ -1,153 +0,0 @@ -import pytest -from pyroute2 import IPRoute - -from minivirt import controller_pb2_grpc, route_pb2 - - -@pytest.fixture -def client(controller_client_dummy): - return controller_client_dummy - - -def test_id_generation(client: controller_pb2_grpc.ControllerServiceStub): - req = route_pb2.CreateRouteTableRequest(route_table=route_pb2.RouteTable(name="XAXAXA")) - creates = [client.CreateRouteTable(req) for _ in range(3)] - ids = [resp.id for resp in creates] - client.DeleteRouteTable(route_pb2.RouteTableIdentifier(id=ids[1])) - resp = client.CreateRouteTable(req) - assert resp.id == ids[1] - - for _ in range(98): - client.CreateRouteTable(req) - - with pytest.raises(Exception): - client.CreateRouteTable(req) - - -def test_route_update(client: controller_pb2_grpc.ControllerServiceStub): - req = route_pb2.CreateRouteTableRequest(route_table=route_pb2.RouteTable(name="XAXAXA")) - resp = client.CreateRouteTable(req) - route_table_id = resp.id - client.PutRoute( - route_pb2.PutRouteRequest( - route=route_pb2.Route( - route_table_id=route_table_id, - destination="10.6.1.0/24", - gateways=["192.168.0.1"], - ) - ) - ) - client.PutRoute( - route_pb2.PutRouteRequest( - route=route_pb2.Route( - route_table_id=route_table_id, - destination="10.6.1.0/24", - gateways=["192.168.0.2", "192.168.0.3"], - ) - ) - ) - routes = client.ListRoutes(route_pb2.ListRoutesRequest(route_table_id=route_table_id)).routes - assert len(routes) == 1 - assert sorted(routes[0].gateways) == ["192.168.0.2", "192.168.0.3"] - - -def test_route_delete(client: controller_pb2_grpc.ControllerServiceStub): - req = route_pb2.CreateRouteTableRequest(route_table=route_pb2.RouteTable(name="XAXAXA")) - resp = client.CreateRouteTable(req) - route_table_id = resp.id - route = client.PutRoute( - route_pb2.PutRouteRequest( - route=route_pb2.Route( - route_table_id=route_table_id, - destination="10.6.1.0/24", - gateways=["192.168.0.1"], - ) - ) - ) - routes = client.ListRoutes(route_pb2.ListRoutesRequest(route_table_id=route_table_id)).routes - assert len(routes) == 1 - - client.DeleteRoute( - route_pb2.RouteIdentifier( - route_table_id=route.route_table_id, - destination=route.destination, - ) - ) - routes = client.ListRoutes(route_pb2.ListRoutesRequest(route_table_id=route_table_id)).routes - assert len(routes) == 0 - - client.DeleteRoute( - route_pb2.RouteIdentifier( - route_table_id=route.route_table_id, - destination=route.destination, - ) - ) - - -def test_route_table_delete(client: controller_pb2_grpc.ControllerServiceStub): - req = route_pb2.CreateRouteTableRequest(route_table=route_pb2.RouteTable(name="XAXAXA")) - resp = client.CreateRouteTable(req) - route_table_id = resp.id - client.PutRoute( - route_pb2.PutRouteRequest( - route=route_pb2.Route( - route_table_id=route_table_id, - destination="10.6.1.0/24", - gateways=["192.168.0.1"], - ) - ) - ) - - client.DeleteRouteTable(route_pb2.RouteTableIdentifier(id=route_table_id)) - routes = client.ListRoutes(route_pb2.ListRoutesRequest(route_table_id=route_table_id)).routes - assert len(routes) == 0 - - client.DeleteRouteTable(route_pb2.RouteTableIdentifier(id=route_table_id)) - - -@pytest.fixture -def rtnl_api(): - with IPRoute() as ip: - yield ip - - -@pytest.fixture -def client_iproute(controller_client, rtnl_api): - rtnl_api.link("add", ifname="restvirtbr0", kind="dummy") - dev = rtnl_api.link_lookup(ifname="restvirtbr0")[0] - rtnl_api.addr("add", index=dev, address="10.69.69.0", mask=24) - rtnl_api.link("set", index=dev, state="up") - - yield controller_client - - rtnl_api.link("del", ifname="restvirtbr0") - - -def test_route_linux(client_iproute: controller_pb2_grpc.ControllerServiceStub, rtnl_api: IPRoute): - client = client_iproute - req = route_pb2.CreateRouteTableRequest(route_table=route_pb2.RouteTable(name="XAXAXA")) - resp = client.CreateRouteTable(req) - route_table_id = resp.id - route = client.PutRoute( - route_pb2.PutRouteRequest( - route=route_pb2.Route( - route_table_id=route_table_id, - destination="10.69.42.0/24", - gateways=["10.69.69.1"], - ) - ) - ) - - r = rtnl_api.route("get", dst="10.69.42.1")[0] - assert r.get_attr("RTA_GATEWAY") == "10.69.69.1" - - client.DeleteRoute( - route_pb2.RouteIdentifier( - route_table_id=route.route_table_id, - destination=route.destination, - ) - ) - assert len(rtnl_api.get_routes(table=route_table_id)) == 0 - - client.DeleteRouteTable(route_pb2.RouteTableIdentifier(id=route_table_id)) - assert len(rtnl_api.get_rules(priority=route_table_id)) == 0 diff --git a/virtuerl/.gitignore b/virtuerl/.gitignore deleted file mode 100644 index 78647f9..0000000 --- a/virtuerl/.gitignore +++ /dev/null @@ -1,25 +0,0 @@ -*.iml -.DS_Store -.vagrant/ -khepri*/ - -.rebar3 -_build -_checkouts -_vendor -.eunit -*.o -*.beam -*.plt -*.swp -*.swo -.erlang.cookie -ebin -log -erl_crash.dump -.rebar -logs -#.idea -#*.iml -rebar3.crashdump -*~ diff --git a/virtuerl/.idea/.gitignore b/virtuerl/.idea/.gitignore deleted file mode 100644 index 24de6c7..0000000 --- a/virtuerl/.idea/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# Default ignored files -/shelf/ -/workspace.xml -misc.xml -rebar.xml diff --git a/virtuerl/.idea/codeStyles/Project.xml b/virtuerl/.idea/codeStyles/Project.xml deleted file mode 100644 index 919ce1f..0000000 --- a/virtuerl/.idea/codeStyles/Project.xml +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/virtuerl/.idea/codeStyles/codeStyleConfig.xml b/virtuerl/.idea/codeStyles/codeStyleConfig.xml deleted file mode 100644 index a55e7a1..0000000 --- a/virtuerl/.idea/codeStyles/codeStyleConfig.xml +++ /dev/null @@ -1,5 +0,0 @@ - - - - \ No newline at end of file diff --git a/virtuerl/.idea/modules.xml b/virtuerl/.idea/modules.xml deleted file mode 100644 index d627cff..0000000 --- a/virtuerl/.idea/modules.xml +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/virtuerl/.idea/vcs.xml b/virtuerl/.idea/vcs.xml deleted file mode 100644 index 6c0b863..0000000 --- a/virtuerl/.idea/vcs.xml +++ /dev/null @@ -1,6 +0,0 @@ - - - - - - \ No newline at end of file diff --git a/virtuerl/LICENSE.md b/virtuerl/LICENSE.md deleted file mode 100644 index b1ceda4..0000000 --- a/virtuerl/LICENSE.md +++ /dev/null @@ -1,186 +0,0 @@ -# Apache License -Version 2.0, January 2004 - -http://www.apache.org/licenses/ - -TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - -## 1. Definitions. - -"License" shall mean the terms and conditions for use, reproduction, and -distribution as defined by Sections 1 through 9 of this document. - -"Licensor" shall mean the copyright owner or entity authorized by the copyright -owner that is granting the License. - -"Legal Entity" shall mean the union of the acting entity and all other entities -that control, are controlled by, or are under common control with that entity. -For the purposes of this definition, "control" means (i) the power, direct or -indirect, to cause the direction or management of such entity, whether by -contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the -outstanding shares, or (iii) beneficial ownership of such entity. - -"You" (or "Your") shall mean an individual or Legal Entity exercising -permissions granted by this License. - -"Source" form shall mean the preferred form for making modifications, including -but not limited to software source code, documentation source, and configuration -files. - -"Object" form shall mean any form resulting from mechanical transformation or -translation of a Source form, including but not limited to compiled object code, -generated documentation, and conversions to other media types. - -"Work" shall mean the work of authorship, whether in Source or Object form, made -available under the License, as indicated by a copyright notice that is included -in or attached to the work (an example is provided in the Appendix below). - -"Derivative Works" shall mean any work, whether in Source or Object form, that -is based on (or derived from) the Work and for which the editorial revisions, -annotations, elaborations, or other modifications represent, as a whole, an -original work of authorship. For the purposes of this License, Derivative Works -shall not include works that remain separable from, or merely link (or bind by -name) to the interfaces of, the Work and Derivative Works thereof. - -"Contribution" shall mean any work of authorship, including the original version -of the Work and any modifications or additions to that Work or Derivative Works -thereof, that is intentionally submitted to Licensor for inclusion in the Work -by the copyright owner or by an individual or Legal Entity authorized to submit -on behalf of the copyright owner. For the purposes of this definition, -"submitted" means any form of electronic, verbal, or written communication sent -to the Licensor or its representatives, including but not limited to -communication on electronic mailing lists, source code control systems, and -issue tracking systems that are managed by, or on behalf of, the Licensor for -the purpose of discussing and improving the Work, but excluding communication -that is conspicuously marked or otherwise designated in writing by the copyright -owner as "Not a Contribution." - -"Contributor" shall mean Licensor and any individual or Legal Entity on behalf -of whom a Contribution has been received by Licensor and subsequently -incorporated within the Work. - -## 2. Grant of Copyright License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable copyright license to reproduce, prepare Derivative Works of, -publicly display, publicly perform, sublicense, and distribute the Work and such -Derivative Works in Source or Object form. - -## 3. Grant of Patent License. - -Subject to the terms and conditions of this License, each Contributor hereby -grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, -irrevocable (except as stated in this section) patent license to make, have -made, use, offer to sell, sell, import, and otherwise transfer the Work, where -such license applies only to those patent claims licensable by such Contributor -that are necessarily infringed by their Contribution(s) alone or by combination -of their Contribution(s) with the Work to which such Contribution(s) was -submitted. If You institute patent litigation against any entity (including a -cross-claim or counterclaim in a lawsuit) alleging that the Work or a -Contribution incorporated within the Work constitutes direct or contributory -patent infringement, then any patent licenses granted to You under this License -for that Work shall terminate as of the date such litigation is filed. - -## 4. Redistribution. - -You may reproduce and distribute copies of the Work or Derivative Works thereof -in any medium, with or without modifications, and in Source or Object form, -provided that You meet the following conditions: - -1. You must give any other recipients of the Work or Derivative Works a copy of - this License; and - -2. You must cause any modified files to carry prominent notices stating that - You changed the files; and - -3. You must retain, in the Source form of any Derivative Works that You - distribute, all copyright, patent, trademark, and attribution notices from - the Source form of the Work, excluding those notices that do not pertain to - any part of the Derivative Works; and - -4. If the Work includes a "NOTICE" text file as part of its distribution, then - any Derivative Works that You distribute must include a readable copy of the - attribution notices contained within such NOTICE file, excluding those - notices that do not pertain to any part of the Derivative Works, in at least - one of the following places: within a NOTICE text file distributed as part - of the Derivative Works; within the Source form or documentation, if - provided along with the Derivative Works; or, within a display generated by - the Derivative Works, if and wherever such third-party notices normally - appear. The contents of the NOTICE file are for informational purposes only - and do not modify the License. You may add Your own attribution notices - within Derivative Works that You distribute, alongside or as an addendum to - the NOTICE text from the Work, provided that such additional attribution - notices cannot be construed as modifying the License. - -You may add Your own copyright statement to Your modifications and may provide -additional or different license terms and conditions for use, reproduction, or -distribution of Your modifications, or for any such Derivative Works as a whole, -provided Your use, reproduction, and distribution of the Work otherwise complies -with the conditions stated in this License. - -## 5. Submission of Contributions. - -Unless You explicitly state otherwise, any Contribution intentionally submitted -for inclusion in the Work by You to the Licensor shall be under the terms and -conditions of this License, without any additional terms or conditions. -Notwithstanding the above, nothing herein shall supersede or modify the terms of -any separate license agreement you may have executed with Licensor regarding -such Contributions. - -## 6. Trademarks. - -This License does not grant permission to use the trade names, trademarks, -service marks, or product names of the Licensor, except as required for -reasonable and customary use in describing the origin of the Work and -reproducing the content of the NOTICE file. - -## 7. Disclaimer of Warranty. - -Unless required by applicable law or agreed to in writing, Licensor provides the -Work (and each Contributor provides its Contributions) on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, -including, without limitation, any warranties or conditions of TITLE, NON- -INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are -solely responsible for determining the appropriateness of using or -redistributing the Work and assume any risks associated with Your exercise of -permissions under this License. - -## 8. Limitation of Liability. - -In no event and under no legal theory, whether in tort (including negligence), -contract, or otherwise, unless required by applicable law (such as deliberate -and grossly negligent acts) or agreed to in writing, shall any Contributor be -liable to You for damages, including any direct, indirect, special, incidental, -or consequential damages of any character arising as a result of this License or -out of the use or inability to use the Work (including but not limited to -damages for loss of goodwill, work stoppage, computer failure or malfunction, or -any and all other commercial damages or losses), even if such Contributor has -been advised of the possibility of such damages. - -## 9. Accepting Warranty or Additional Liability. - -While redistributing the Work or Derivative Works thereof, You may choose to -offer, and charge a fee for, acceptance of support, warranty, indemnity, or -other liability obligations and/or rights consistent with this License. However, -in accepting such obligations, You may act only on Your own behalf and on Your -sole responsibility, not on behalf of any other Contributor, and only if You -agree to indemnify, defend, and hold each Contributor harmless for any liability -incurred by, or claims asserted against, such Contributor by reason of your -accepting any such warranty or additional liability. - -END OF TERMS AND CONDITIONS - -Copyright 2023, Ilya Verbitskiy . - -Licensed under the Apache License, Version 2.0 (the "License"); -you may not use this file except in compliance with the License. -You may obtain a copy of the License at - -http://www.apache.org/licenses/LICENSE-2.0 - -Unless required by applicable law or agreed to in writing, software -distributed under the License is distributed on an "AS IS" BASIS, -WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -See the License for the specific language governing permissions and -limitations under the License. \ No newline at end of file diff --git a/virtuerl/README.md b/virtuerl/README.md deleted file mode 100644 index 8f86b0e..0000000 --- a/virtuerl/README.md +++ /dev/null @@ -1,57 +0,0 @@ -virtuerl -===== - -An OTP application - -# Required packages -```sh -sudo apt install ovmf swtpm -``` - -# Windows Guests - -## Disable boot prompt -```sh -sudo mount -o loop Win11_23H2_EnglishInternational_x64v2.iso /mnt/win - -genisoimage \ - --allow-limited-size \ - -no-emul-boot \ - -b "boot/etfsboot.com" \ - -boot-load-seg 0 \ - -boot-load-size 8 \ - -eltorito-alt-boot \ - -no-emul-boot \ - -e "efi/microsoft/boot/efisys_noprompt.bin" \ - -boot-load-size 1 \ - -iso-level 4 \ - -udf \ - -o "win.iso" \ - /mnt/win/ -``` - -# Running - -On the server - -Make sure IP forwarding is enabled (`/etc/sysctl.conf`) -``` -# Uncomment the next line to enable packet forwarding for IPv4 -net.ipv4.ip_forward=1 -# Uncomment the next line to enable packet forwarding for IPv6 -net.ipv6.conf.all.forwarding=1 -``` -Run `sysctl -w` to commit changes. - -```sh -sudo -s ./erts-13.1.5/bin/erl -mode embedded -boot releases/0.7.0+build.61.ref8fc0b7e/start -config releases/0.7.0+build.61.ref8fc0b7e/sys.config -proto_dist inet6_tcp -name verbit@verbit.in-berlin.de -setcookie abcdef -``` - -Locally -```sh -rebar3 compile -erl -name moi -proto_dist inet6_tcp -setcookie abcdef -pa _build/default/lib/*/ebin -hidden -(moi@t460s.lan)1> net_adm:ping('virtuerl@a.in6.dev'). -pong -(moi@t460s.lan)2> virtuerl_ui:start('virtuerl@a.in6.dev'). -``` diff --git a/virtuerl/Vagrantfile b/virtuerl/Vagrantfile deleted file mode 100644 index 543bf43..0000000 --- a/virtuerl/Vagrantfile +++ /dev/null @@ -1,77 +0,0 @@ -# -*- mode: ruby -*- -# vi: set ft=ruby : - -# All Vagrant configuration is done below. The "2" in Vagrant.configure -# configures the configuration version (we support older styles for -# backwards compatibility). Please don't change it unless you know what -# you're doing. -Vagrant.configure("2") do |config| - # The most common configuration options are documented and commented below. - # For a complete reference, please see the online documentation at - # https://docs.vagrantup.com. - - # Every Vagrant development environment requires a box. You can search for - # boxes at https://vagrantcloud.com/search. - config.vm.box = "debian/bookworm64" - - # Disable automatic box update checking. If you disable this, then - # boxes will only be checked for updates when the user runs - # `vagrant box outdated`. This is not recommended. - # config.vm.box_check_update = false - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine. In the example below, - # accessing "localhost:8080" will access port 80 on the guest machine. - # NOTE: This will enable public access to the opened port - # config.vm.network "forwarded_port", guest: 80, host: 8080 - - # Create a forwarded port mapping which allows access to a specific port - # within the machine from a port on the host machine and only allow access - # via 127.0.0.1 to disable public access - # config.vm.network "forwarded_port", guest: 80, host: 8080, host_ip: "127.0.0.1" - - # Create a private network, which allows host-only access to the machine - # using a specific IP. - # config.vm.network "private_network", ip: "192.168.33.10" - - # Create a public network, which generally matched to bridged network. - # Bridged networks make the machine appear as another physical device on - # your network. - # config.vm.network "public_network" - - # Share an additional folder to the guest VM. The first argument is - # the path on the host to the actual folder. The second argument is - # the path on the guest to mount the folder. And the optional third - # argument is a set of non-required options. - config.vm.synced_folder "../", "/restvirt" - - # Disable the default share of the current code directory. Doing this - # provides improved isolation between the vagrant box and your host - # by making sure your Vagrantfile isn't accessable to the vagrant box. - # If you use this you may want to enable additional shared subfolders as - # shown above. - config.vm.synced_folder ".", "/vagrant", disabled: true - - # Provider-specific configuration so you can fine-tune various - # backing providers for Vagrant. These expose provider-specific options. - # Example for VirtualBox: - # - config.vm.provider "virtualbox" do |vb| - # # Display the VirtualBox GUI when booting the machine - # vb.gui = true - # - # Customize the amount of memory on the VM: - vb.memory = "1024" - end - # - # View the documentation for the provider you are using for more - # information on available options. - - # Enable provisioning with a shell script. Additional provisioners such as - # Ansible, Chef, Docker, Puppet and Salt are also available. Please see the - # documentation for more information about their specific syntax and use. - # config.vm.provision "shell", inline: <<-SHELL - # apt-get update - # apt-get install -y apache2 - # SHELL -end diff --git a/virtuerl/bird.conf b/virtuerl/bird.conf deleted file mode 100644 index 4351773..0000000 --- a/virtuerl/bird.conf +++ /dev/null @@ -1,171 +0,0 @@ -# This is a basic configuration file, which contains boilerplate options and -# some basic examples. It allows the BIRD daemon to start but will not cause -# anything else to happen. -# -# Please refer to the BIRD User's Guide documentation, which is also available -# online at http://bird.network.cz/ in HTML format, for more information on -# configuring BIRD and adding routing protocols. - -# Configure logging -# log syslog all; -log stderr all; -# log "/var/log/bird.log" { debug, trace, info, remote, warning, error, auth, fatal, bug }; - -# Set router ID. It is a unique identification of your router, usually one of -# IPv4 addresses of the router. It is recommended to configure it explicitly. -# router id 198.51.100.1; - -# Turn on global debugging of all protocols (all messages or just selected classes) -# debug protocols all; -# debug protocols { events, states }; - -# Turn on internal watchdog -# watchdog warning 5 s; -# watchdog timeout 30 s; - -# You can define your own constants -# define my_asn = 65000; -# define my_addr = 198.51.100.1; - -# Tables master4 and master6 are defined by default -# ipv4 table master4; -# ipv6 table master6; - -# Define more tables, e.g. for policy routing or as MRIB -# ipv4 table mrib4; -# ipv6 table mrib6; - -# The Device protocol is not a real routing protocol. It does not generate any -# routes and it only serves as a module for getting information about network -# interfaces from the kernel. It is necessary in almost any configuration. -protocol device { -} - -# The direct protocol is not a real routing protocol. It automatically generates -# direct routes to all network interfaces. Can exist in as many instances as you -# wish if you want to populate multiple routing tables with direct routes. -protocol direct { - disabled; # Disable by default - ipv4; # Connect to default IPv4 table - ipv6; # ... and to default IPv6 table -} - -# The Kernel protocol is not a real routing protocol. Instead of communicating -# with other routers in the network, it performs synchronization of BIRD -# routing tables with the OS kernel. One instance per table. -protocol kernel { - ipv4 { # Connect protocol to IPv4 table by channel -# table master4; # Default IPv4 table is master4 -# import all; # Import to table, default is import all - export all; # Export to protocol. default is export none - }; -# learn; # Learn alien routes from the kernel -# kernel table 10; # Kernel table to synchronize with (default: main) -} - -# Another instance for IPv6, skipping default options -protocol kernel { - ipv6 { export all; }; -} - -# Static routes (Again, there can be multiple instances, for different address -# families and to disable/enable various groups of static routes on the fly). -protocol static { - ipv4; # Again, IPv4 channel with default options - -# route 0.0.0.0/0 via 198.51.100.10; -# route 192.0.2.0/24 blackhole; -# route 10.0.0.0/8 unreachable; -# route 10.2.0.0/24 via "eth0"; -# # Static routes can be defined with optional attributes -# route 10.1.1.0/24 via 198.51.100.3 { rip_metric = 3; }; -# route 10.1.2.0/24 via 198.51.100.3 { ospf_metric1 = 100; }; -# route 10.1.3.0/24 via 198.51.100.4 { ospf_metric2 = 100; }; -} - -include "birderl.conf"; - -protocol bgp { - local as 65000 port 9179; - neighbor range 192.168.0.0/16 as 65001; - passive; - ipv4 { - import all; - export all; - }; -} - -# Define simple filter as an example for BGP import filter -# See https://gitlab.labs.nic.cz/labs/bird/wikis/BGP_filtering for more examples -# filter rt_import -# { -# if bgp_path.first != 64496 then accept; -# if bgp_path.len > 64 then accept; -# if bgp_next_hop != from then accept; -# reject; -# } - -# BGP example, explicit name 'uplink1' is used instead of default 'bgp1' -# protocol bgp uplink1 { -# description "My BGP uplink"; -# local 198.51.100.1 as 65000; -# neighbor 198.51.100.10 as 64496; -# hold time 90; # Default is 240 -# password "secret"; # Password used for MD5 authentication -# -# ipv4 { # regular IPv4 unicast (1/1) -# import filter rt_import; -# export where source ~ [ RTS_STATIC, RTS_BGP ]; -# }; -# -# ipv6 { # regular IPv6 unicast (2/1) -# import filter rt_import; -# export filter { # The same as 'where' expression above -# if source ~ [ RTS_STATIC, RTS_BGP ] -# then accept; -# else reject; -# }; -# }; -# -# ipv4 multicast { # IPv4 multicast topology (1/2) -# table mrib4; # explicit IPv4 table -# import filter rt_import; -# export all; -# }; -# -# ipv6 multicast { # IPv6 multicast topology (2/2) -# table mrib6; # explicit IPv6 table -# import filter rt_import; -# export all; -# }; -#} - -# Template example. Using templates to define IBGP route reflector clients. -# template bgp rr_clients { -# local 10.0.0.1 as 65000; -# neighbor as 65000; -# rr client; -# rr cluster id 1.0.0.1; -# -# ipv4 { -# import all; -# export where source = RTS_BGP; -# }; -# -# ipv6 { -# import all; -# export where source = RTS_BGP; -# }; -# } -# -# protocol bgp client1 from rr_clients { -# neighbor 10.0.1.1; -# } -# -# protocol bgp client2 from rr_clients { -# neighbor 10.0.2.1; -# } -# -# protocol bgp client3 from rr_clients { -# neighbor 10.0.3.1; -# } diff --git a/virtuerl/erlang_ls.config b/virtuerl/erlang_ls.config deleted file mode 100644 index d7edc4a..0000000 --- a/virtuerl/erlang_ls.config +++ /dev/null @@ -1,9 +0,0 @@ -apps_dirs: - - "_build/default/lib/*" -include_dirs: - - "include" - - "_build/default/lib/*/include" - - "_build/default/lib" - - "_build/default/lib/khepri" -deps_dirs: - - "_build/default/lib/*"