diff --git a/.github/workflows/test-pebble.yml b/.github/workflows/test-pebble.yml index 673c757..b064acd 100644 --- a/.github/workflows/test-pebble.yml +++ b/.github/workflows/test-pebble.yml @@ -1,4 +1,4 @@ -name: Docker Image CI +name: Integration testing on: push: @@ -13,6 +13,24 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v3 - - name: Build the Docker image - run: make compose + - uses: actions/checkout@v4 + - uses: DeterminateSystems/nix-installer-action@main + - uses: DeterminateSystems/magic-nix-cache-action@main + + - name: "Cache non nix Rust files" + id: cache-cargo + uses: "actions/cache@v4" + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + target_nix_test/ + save-always: true + key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} + restore-keys: ${{ runner.os }}-cargo- + + + - name: Run pebble based agnos tester + run: nix-shell integration-testing/shell.nix --pure --run agnos-test-script \ No newline at end of file diff --git a/.gitignore b/.gitignore index ea8c4bf..1e47e8c 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ /target +/target_nix_test \ No newline at end of file diff --git a/Makefile b/Makefile index b21b9df..a890b1c 100644 --- a/Makefile +++ b/Makefile @@ -3,18 +3,4 @@ build-release: strip target/release/agnos strip target/release/agnos-generate-accounts-keys ln target/release/agnos agnos - ln target/release/agnos-generate-accounts-keys agnos-generate-accounts-keys - -compose: dockers - $(MAKE) -C test-docker compose - -dockers: agnos-docker pebble-docker - -agnos-docker: - docker buildx build . -f test-docker/agnos/Dockerfile -t agnos - -bind9-docker: - docker buildx build test-docker/bind9 -f test-docker/bind9/Dockerfile -t bind9 - -pebble-docker: - docker buildx build test-docker/pebble -f test-docker/pebble/Dockerfile -t pebble \ No newline at end of file + ln target/release/agnos-generate-accounts-keys agnos-generate-accounts-keys \ No newline at end of file diff --git a/README.md b/README.md index 76811c7..1641741 100644 --- a/README.md +++ b/README.md @@ -69,6 +69,7 @@ Agnos leverages let's encrypt capability to follow DNS `NS` records. It requires 1. [Running agnos](#running-agnos) 1. [Systemd units](#systemd-units) 1. [Developers](#developers) + 1. [Integration testing](#integration-testing) @@ -231,4 +232,6 @@ PRs and issues are very welcome. Build using usual `cargo` commands. -The Makefile is for integration testing in a docker-compose. At the root, run `sudo make compose` (sudo is required to use docker) to test agnos using pebble. \ No newline at end of file +## Integration testing + +Integration testing is done using nix-shell. Launch it with `nix-shell integration-testing/shell.nix --pure --run agnos-test-script` \ No newline at end of file diff --git a/test-docker/agnos/config_test.toml b/integration-testing/agnos/config_test.toml similarity index 93% rename from test-docker/agnos/config_test.toml rename to integration-testing/agnos/config_test.toml index df3c002..02c7902 100644 --- a/test-docker/agnos/config_test.toml +++ b/integration-testing/agnos/config_test.toml @@ -1,6 +1,5 @@ # Address for the DNS server to listen on. -# The port should probably be 53. -dns_listen_addr = "0.0.0.0:53" +dns_listen_addr = "0.0.0.0:8053" # A first account # accounts are identified by diff --git a/integration-testing/pebble/cert.pem b/integration-testing/pebble/cert.pem new file mode 100644 index 0000000..aab7d22 --- /dev/null +++ b/integration-testing/pebble/cert.pem @@ -0,0 +1,19 @@ +-----BEGIN CERTIFICATE----- +MIIDHDCCAgSgAwIBAgIUHfOjSE6Azub1nsBON4jlIvxVW5MwDQYJKoZIhvcNAQEL +BQAwFDESMBAGA1UEAwwJMTI3LjAuMC4xMCAXDTI0MTAyODE3MjQwM1oYDzIxMjQx +MDA0MTcyNDAzWjAUMRIwEAYDVQQDDAkxMjcuMC4wLjEwggEiMA0GCSqGSIb3DQEB +AQUAA4IBDwAwggEKAoIBAQCktTY6y+LXtChHhjyLyHxtzziI1VBMgNPLqLaO7Tqh +5WQ8Ts2Q3tKEG0WQdolOIOkEvkn40CzN+oSYSxyD9ancwbMlGxaiud2X57gUd5Kr +8yV3J+o+X7DtfuFQ91jUSk+e//TXDp/YB9UpbUOdI4svqN/gLr2eev7ERdjrIMMu +ZstGn2/HBMGNI6EhSWwxfy4TkTjsNo6UKw7OMwYUW63LKoa9k2peL0cpho6e0K3d +MX3lCdWiaIZDjXwUboARtXSe5IuJjY19OrosVaf+qsDtaPoWxDDP0JXyx/YAbeuQ +9Xr4/VJzCRbZkitW9roPdmFRru1B8ppJ20piJDFlx0P5AgMBAAGjZDBiMB0GA1Ud +DgQWBBT2ZCDvsXPuG+miLDV6XplcUC3PQjAfBgNVHSMEGDAWgBT2ZCDvsXPuG+mi +LDV6XplcUC3PQjAPBgNVHRMBAf8EBTADAQH/MA8GA1UdEQQIMAaHBH8AAAEwDQYJ +KoZIhvcNAQELBQADggEBAKP5e5i4Ggx+vRJUmCQeRHBLSAG+DgE8vE8veAxeNjlB +FLQ6EAfdtjomSeuvxn4IMccIegNZVQVlOQB0r488dLHMkLzCd1iwLzw7mZ7aThCy +2xYK0GoLK8vednAQEY5xA6Og88onoEKTT483EfRFXs8dV14j7b77MsaC5afJ20VA +bJfMSXquMxCmu42t7m4IbyZXZ+Z9Qv8P8oE+Ur9SKjMxukblPaZzxcwGEC+B0zEe +L1uCpidZwuYpS6k06KfMCVzM+76WUVfpHtSMZgXRb8vMa0O/EX4anSE7KmfKyCcs +R4IwvS90+FX9i7GGAv6Y//38xLq9T1M1z8dQJbdq97o= +-----END CERTIFICATE----- diff --git a/integration-testing/pebble/key.pem b/integration-testing/pebble/key.pem new file mode 100644 index 0000000..7dd6816 --- /dev/null +++ b/integration-testing/pebble/key.pem @@ -0,0 +1,28 @@ +-----BEGIN PRIVATE KEY----- +MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQCktTY6y+LXtChH +hjyLyHxtzziI1VBMgNPLqLaO7Tqh5WQ8Ts2Q3tKEG0WQdolOIOkEvkn40CzN+oSY +SxyD9ancwbMlGxaiud2X57gUd5Kr8yV3J+o+X7DtfuFQ91jUSk+e//TXDp/YB9Up +bUOdI4svqN/gLr2eev7ERdjrIMMuZstGn2/HBMGNI6EhSWwxfy4TkTjsNo6UKw7O +MwYUW63LKoa9k2peL0cpho6e0K3dMX3lCdWiaIZDjXwUboARtXSe5IuJjY19Oros +Vaf+qsDtaPoWxDDP0JXyx/YAbeuQ9Xr4/VJzCRbZkitW9roPdmFRru1B8ppJ20pi +JDFlx0P5AgMBAAECggEAF2BmxXqJhA7cRqZ9MmOukVE/V2BbKLiCFt4npupxj2fE +zbBriZuuajSKr4G7ZBzUpakyS3+UVFmxdwH2Fp6H0L6nI+WP1WGm2zf2juUXqpL0 +ZtCB9P9U16hR51FryJmRamIuiFVZh2o5LUuGNKfGSengeGt52yPew9GcA2cffJa9 +CjGVO7jX5r2ZVMMwf6oYr+TzAq/uJ4OeXfavfAoEvlDDN+oHsQ/iEm52i5Bg9uo6 +BNUqaqw5Ab8pLEkwc7hWZcfNFInPAKUldxUthIcZy4bcyifNKj3bdjAENxyDcGrL +GUkdyOG0vqE4iAodbSxrM6aftasFLw8nj0gvl6YKZwKBgQDOMC78K+hKMr6wVk09 +otqh8nCeye2N7mGEktthpaIxfra6ld1dT37jviNla4Agfiavdx6jSfSdDqpL1kPZ +XgC/F0ZrFHJNtO5ycYtjkJQfd9lSJYR1eKEnngyBPSx8uJ087wljlf1CySfBJ4ha ++pMnobaaZnTVC7pyoToAVvnEuwKBgQDMf6d4kLgoQ9p5JJV1/ud4571DL9BnTs8P +vaxmK6qBbCFoekyVBAWiq9EA7zLeVY4zSKJvKSpWqgg429w4LKGskWV9S4lvItQ1 +44h8ZCnOEdDD8isfV5j1zxj+aaZlzk5uHlBE1/f0JWOEFyqECUqIxW218aP5x+V1 +uGrZR5Bo2wKBgQCB1BEhs7v2THGJsy27q7mi03daZKdyATHiOl5s49B2/eStJARY +5t9tI6JCECiDTSuqvITMKJsf8cYFLotWaTxrFoq+jgdTKqQh56DvNnAuSFbMxNbc +6PIAciJJlm1WsyA+5/yvehgYX3TqyKuxLapPACJsoiraoyHpX9+XqyxmVQKBgFd2 +qawZSYp/KuvxR7OF6H5/ryUTSDFHNaxn1VqFhpGAK/HBjQuXAsoGbofVxo3tTbqF +cGPW2XLjmkynTFMCU8u5DA1Ax3EvFlBOFswNEww99mo4I1VuY8+OWgRGL5MPX+Ad +OvuW20gizaNrPRXn22cP+dJ9nUJxyqRE0f5Ia21NAoGAOtYZjG72usz8oQWsDlBX +VFusjfk/GQZowSzwPSTrYg4UVgVrYZVdwrhPAYMI+CvEoGjSBTjb1x6NZRGG3MOM +ClFxlgfycHykMT2HwFvazwB1GayEBUYBCwSHI1mIjk67+x34xOzCpK2RVg26+QLs +JLl0MDIbeM4wUzr7ApAYe/4= +-----END PRIVATE KEY----- diff --git a/integration-testing/shell.nix b/integration-testing/shell.nix new file mode 100644 index 0000000..73a7cbb --- /dev/null +++ b/integration-testing/shell.nix @@ -0,0 +1,53 @@ +{ pkgs ? import {}}: + +let + inherit (pkgs) lib; + pebble_cert = ./pebble/cert.pem; + pebble_priv_key = ./pebble/key.pem; + pebble_config = pkgs.writeTextFile { + name = "pebble-config.json"; + text = builtins.toJSON + { pebble = { + certificate = pebble_cert; + privateKey = pebble_priv_key; + listenAddress = "0.0.0.0:14000"; + httpPort= 5002; + tlsPort= 5001; + }; + }; + }; + wait_for_it = pkgs.fetchurl { + url = "https://raw.githubusercontent.com/vishnubob/wait-for-it/81b1373f17855a4dc21156cfe1694c31d7d1792e/wait-for-it.sh"; + hash = "sha256-t6BPON4eUedFXs9jFRyMfkBb0tRaLU4W9kGdtzehJdY="; + }; + agnos_config = ./agnos/config_test.toml; + test-script = pkgs.writeShellScriptBin "agnos-test-script" + '' + set -xve + trap "trap - SIGTERM; [ -n \"$(jobs -p)\" ] && kill -- -$$" SIGINT SIGTERM EXIT + ${pkgs.pebble}/bin/pebble -config ${pebble_config} -strict -dnsserver 127.0.0.1:8053 & + export CARGO_TARGET_DIR=target_nix_test + ${pkgs.cargo}/bin/cargo build --release + OLDWORKDIR=$(pwd) + WORKDIR=$(mktemp -p target_nix_test -d) + cd $WORKDIR + $OLDWORKDIR/$CARGO_TARGET_DIR/release/agnos-generate-accounts-keys --key-size 2048 --no-confirm ${agnos_config} + bash ${wait_for_it} -t 0 127.0.0.1:14000 + $OLDWORKDIR/$CARGO_TARGET_DIR/release/agnos --debug --acme-url https://127.0.0.1:14000/dir --acme-serv-ca ${pebble_cert} ${agnos_config} + cd $OLDWORKDIR + rm -rf $WORKDIR + ''; +in +pkgs.mkShell { + nativeBuildInputs = with pkgs; [ killall rustc cargo gcc rustfmt clippy pebble pkg-config openssl mktemp]; + + # Certain Rust tools won't work without this + # This can also be fixed by using oxalica/rust-overlay and specifying the rust-src extension + # See https://discourse.nixos.org/t/rust-src-not-found-and-other-misadventures-of-developing-rust-on-nixos/11570/3?u=samuela. for more details. + RUST_SRC_PATH = "${pkgs.rust.packages.stable.rustPlatform.rustLibSrc}"; + + shellHook = '' + export PATH=${test-script}/bin:$PATH + ''; + +} \ No newline at end of file diff --git a/test-docker/Makefile b/test-docker/Makefile deleted file mode 100644 index 2facff2..0000000 --- a/test-docker/Makefile +++ /dev/null @@ -1,2 +0,0 @@ -compose: - docker-compose up --abort-on-container-exit --force-recreate \ No newline at end of file diff --git a/test-docker/agnos/Dockerfile b/test-docker/agnos/Dockerfile deleted file mode 100644 index 370841f..0000000 --- a/test-docker/agnos/Dockerfile +++ /dev/null @@ -1,37 +0,0 @@ -FROM lukemathwalker/cargo-chef:latest-rust-1.68.0 AS chef - -ENV CARGO_REGISTRIES_CRATES_IO_PROTOCOL=sparse - -WORKDIR /app - -FROM chef AS planner -COPY ./src ./src -COPY ./Cargo.toml ./Cargo.lock ./ -COPY ./test-docker/agnos/config_test.toml ./test-docker/agnos/config_test.toml -RUN cargo chef prepare --recipe-path recipe.json - -FROM chef AS builder -COPY --from=planner /app/recipe.json recipe.json -# Build dependencies - this is the caching Docker layer! -RUN cargo chef cook --recipe-path recipe.json -RUN wget https://raw.githubusercontent.com/letsencrypt/pebble/main/test/certs/pebble.minica.pem -O pebbleCA.pem -RUN wget https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh -O wait-for-it.sh -# Build application -COPY ./src ./src -COPY ./Cargo.toml ./Cargo.lock ./ -COPY ./test-docker/agnos/config_test.toml ./test-docker/agnos/config_test.toml - -RUN cargo build --bins -RUN /app/target/debug/agnos-generate-accounts-keys --key-size 2048 --no-confirm test-docker/agnos/config_test.toml - -EXPOSE 53/tcp 53/udp - -CMD ["bash", "wait-for-it.sh", "-t", "0", \ - "pebble:14000", \ - "--", \ - "/app/target/debug/agnos", \ - "--debug",\ - "--acme-url", "https://pebble:14000/dir",\ - "--acme-serv-ca", "pebbleCA.pem", \ - "test-docker/agnos/config_test.toml"\ - ] \ No newline at end of file diff --git a/test-docker/bind9/Dockerfile b/test-docker/bind9/Dockerfile deleted file mode 100644 index 4da10ef..0000000 --- a/test-docker/bind9/Dockerfile +++ /dev/null @@ -1,17 +0,0 @@ -FROM ubuntu:bionic - -RUN apt-get update \ - && apt-get install -y \ - bind9 \ - bind9utils \ - bind9-doc - -# Copy configuration files -COPY named.conf.options /etc/bind/ -COPY named.conf.local /etc/bind/ -COPY agnos.test.zone /etc/bind/zones/ - - -EXPOSE 53/udp 53/tcp 953/tcp - -CMD ["named","-g","-4","-d 1"] \ No newline at end of file diff --git a/test-docker/bind9/agnos.test.zone b/test-docker/bind9/agnos.test.zone deleted file mode 100644 index 8ae4a53..0000000 --- a/test-docker/bind9/agnos.test.zone +++ /dev/null @@ -1,19 +0,0 @@ -$TTL 604800 -@ IN SOA ns1.agnos.test. root.agnos.test. ( - 3 ; Serial - 604800 ; Refresh - 86400 ; Retry - 2419200 ; Expire - 604800 ) ; Negative Cache TTL -; -; name servers - NS records - IN NS ns1.agnos.test. - -; name servers - A records -ns1.agnos.test. IN A 10.20.0.2 - -agnos-ns.agnos.test. IN A 10.20.0.3 -_acme-challenge.a.agnos.test. IN NS agnos-ns.doma.in -_acme-challenge.b.agnos.test. IN NS agnos-ns.doma.in -_acme-challenge.c.agnos.test. IN NS agnos-ns.doma.in -_acme-challenge.subdomain.c.agnos.test. IN NS agnos-ns.doma.in \ No newline at end of file diff --git a/test-docker/bind9/named.conf.local b/test-docker/bind9/named.conf.local deleted file mode 100644 index 1059565..0000000 --- a/test-docker/bind9/named.conf.local +++ /dev/null @@ -1,4 +0,0 @@ -zone "agnos.test" { - type master; - file "/etc/bind/zones/agnos.test.zone"; -}; \ No newline at end of file diff --git a/test-docker/bind9/named.conf.options b/test-docker/bind9/named.conf.options deleted file mode 100644 index 3d6f50d..0000000 --- a/test-docker/bind9/named.conf.options +++ /dev/null @@ -1,9 +0,0 @@ -options { - directory "/var/cache/bind"; - - listen-on { any; }; - - forwarders { - 10.20.0.3; - }; -}; \ No newline at end of file diff --git a/test-docker/docker-compose.yml b/test-docker/docker-compose.yml deleted file mode 100644 index cec2877..0000000 --- a/test-docker/docker-compose.yml +++ /dev/null @@ -1,39 +0,0 @@ -version: '3' -services: - pebble: - image: pebble - ports: - - 14000:14000 # HTTPS ACME API - - 15000:15000 # HTTPS Management API - networks: - acmenet: - ipv4_address: 10.20.0.4 - - # bind9: - # image: bind9 - # tty: true - # expose: - # - 53/tcp - # - 53/udp - # - 953/tcp - # ports: - # - 5353:53/tcp - # - 5353:53/udp - # # command: sleep 3600 - # networks: - # acmenet: - # ipv4_address: 10.20.0.2 - - agnos: - image: agnos - networks: - acmenet: - ipv4_address: 10.20.0.3 - -networks: - acmenet: - driver: bridge - ipam: - driver: default - config: - - subnet: 10.20.0.0/24 \ No newline at end of file diff --git a/test-docker/pebble/Dockerfile b/test-docker/pebble/Dockerfile deleted file mode 100644 index 74ea932..0000000 --- a/test-docker/pebble/Dockerfile +++ /dev/null @@ -1,5 +0,0 @@ -FROM ghcr.io/letsencrypt/pebble:latest - -ENV PEBBLE_VA_NOSLEEP=1 - -CMD pebble -config /test/config/pebble-config.json -strict -dnsserver 10.20.0.3:53