name: Test Infrastructure files

on:
  push:
    branches:
      - main
  pull_request:
    paths:
      - 'infrastructure_files/**'
      - '.github/workflows/test-infrastructure-files.yml'
      - 'management/cmd/**'
      - 'signal/cmd/**'

concurrency:
  group: ${{ github.workflow }}-${{ github.ref }}-${{ github.head_ref || github.actor_id }}
  cancel-in-progress: true

jobs:
  test-docker-compose:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        store: [ 'sqlite', 'postgres', 'mysql' ]
    services:
      postgres:
        image: ${{ (matrix.store == 'postgres') && 'postgres' || '' }}
        env:
          POSTGRES_USER: netbird
          POSTGRES_PASSWORD: postgres
          POSTGRES_DB: netbird
        options: >-
          --health-cmd pg_isready
          --health-interval 10s
          --health-timeout 5s
        ports:
          - 5432:5432
      mysql:
        image: ${{ (matrix.store == 'mysql') && 'mysql' || '' }}
        env:
          MYSQL_USER: netbird
          MYSQL_PASSWORD: mysql
          MYSQL_ROOT_PASSWORD: mysqlroot
          MYSQL_DATABASE: netbird
        options: >-
          --health-cmd "mysqladmin ping --silent"
          --health-interval 10s
          --health-timeout 5s
        ports:
          - 3306:3306
    steps:
      - name: Set Database Connection String
        run: |
          if [ "${{ matrix.store }}" == "postgres" ]; then
            echo "NETBIRD_STORE_ENGINE_POSTGRES_DSN=host=$(hostname -I | awk '{print $1}') user=netbird password=postgres dbname=netbird port=5432" >> $GITHUB_ENV
          else
            echo "NETBIRD_STORE_ENGINE_POSTGRES_DSN==" >> $GITHUB_ENV
          fi
          if [ "${{ matrix.store }}" == "mysql" ]; then
            echo "NETBIRD_STORE_ENGINE_MYSQL_DSN=netbird:mysql@tcp($(hostname -I | awk '{print $1}'):3306)/netbird" >> $GITHUB_ENV
          else
            echo "NETBIRD_STORE_ENGINE_MYSQL_DSN==" >> $GITHUB_ENV
          fi

      - name: Install jq
        run: sudo apt-get install -y jq

      - name: Install curl
        run: sudo apt-get install -y curl

      - name: Install Go
        uses: actions/setup-go@v5
        with:
          go-version: "1.23.x"

      - name: Cache Go modules
        uses: actions/cache@v4
        with:
          path: ~/go/pkg/mod
          key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
          restore-keys: |
            ${{ runner.os }}-go-

      - name: Checkout code
        uses: actions/checkout@v4

      - name: cp setup.env
        run: cp infrastructure_files/tests/setup.env infrastructure_files/

      - name: run configure
        working-directory: infrastructure_files
        run: bash -x configure.sh
        env:
          CI_NETBIRD_DOMAIN: localhost
          CI_NETBIRD_AUTH_CLIENT_ID: testing.client.id
          CI_NETBIRD_AUTH_CLIENT_SECRET: testing.client.secret
          CI_NETBIRD_AUTH_AUDIENCE: testing.ci
          CI_NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT: https://example.eu.auth0.com/.well-known/openid-configuration
          CI_NETBIRD_USE_AUTH0: true
          CI_NETBIRD_MGMT_IDP: "none"
          CI_NETBIRD_IDP_MGMT_CLIENT_ID: testing.client.id
          CI_NETBIRD_IDP_MGMT_CLIENT_SECRET: testing.client.secret
          CI_NETBIRD_AUTH_SUPPORTED_SCOPES: "openid profile email offline_access api email_verified"
          CI_NETBIRD_STORE_CONFIG_ENGINE: ${{ matrix.store }}
          NETBIRD_STORE_ENGINE_POSTGRES_DSN: ${{ env.NETBIRD_STORE_ENGINE_POSTGRES_DSN }}
          NETBIRD_STORE_ENGINE_MYSQL_DSN: ${{ env.NETBIRD_STORE_ENGINE_MYSQL_DSN }}
          CI_NETBIRD_MGMT_IDP_SIGNKEY_REFRESH: false

      - name: check values
        working-directory: infrastructure_files/artifacts
        env:
          CI_NETBIRD_DOMAIN: localhost
          CI_NETBIRD_AUTH_CLIENT_ID: testing.client.id
          CI_NETBIRD_AUTH_CLIENT_SECRET: testing.client.secret
          CI_NETBIRD_AUTH_AUDIENCE: testing.ci
          CI_NETBIRD_AUTH_OIDC_CONFIGURATION_ENDPOINT: https://example.eu.auth0.com/.well-known/openid-configuration
          CI_NETBIRD_USE_AUTH0: true
          CI_NETBIRD_AUTH_SUPPORTED_SCOPES: "openid profile email offline_access api email_verified"
          CI_NETBIRD_AUTH_AUTHORITY: https://example.eu.auth0.com/
          CI_NETBIRD_AUTH_JWT_CERTS: https://example.eu.auth0.com/.well-known/jwks.json
          CI_NETBIRD_AUTH_TOKEN_ENDPOINT: https://example.eu.auth0.com/oauth/token
          CI_NETBIRD_AUTH_DEVICE_AUTH_ENDPOINT: https://example.eu.auth0.com/oauth/device/code
          CI_NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT: https://example.eu.auth0.com/authorize
          CI_NETBIRD_AUTH_REDIRECT_URI: "/peers"
          CI_NETBIRD_TOKEN_SOURCE: "idToken"
          CI_NETBIRD_AUTH_USER_ID_CLAIM: "email"
          CI_NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE: "super"
          CI_NETBIRD_AUTH_DEVICE_AUTH_SCOPE: "openid email"
          CI_NETBIRD_MGMT_IDP: "none"
          CI_NETBIRD_IDP_MGMT_CLIENT_ID: testing.client.id
          CI_NETBIRD_IDP_MGMT_CLIENT_SECRET: testing.client.secret
          CI_NETBIRD_SIGNAL_PORT: 12345
          CI_NETBIRD_STORE_CONFIG_ENGINE: ${{ matrix.store }}
          NETBIRD_STORE_ENGINE_POSTGRES_DSN: '${{ env.NETBIRD_STORE_ENGINE_POSTGRES_DSN }}$'
          NETBIRD_STORE_ENGINE_MYSQL_DSN: '${{ env.NETBIRD_STORE_ENGINE_MYSQL_DSN }}$'
          CI_NETBIRD_MGMT_IDP_SIGNKEY_REFRESH: false
          CI_NETBIRD_TURN_EXTERNAL_IP: "1.2.3.4"

        run: |
          set -x
          grep AUTH_CLIENT_ID docker-compose.yml | grep $CI_NETBIRD_AUTH_CLIENT_ID
          grep AUTH_CLIENT_SECRET docker-compose.yml | grep $CI_NETBIRD_AUTH_CLIENT_SECRET
          grep AUTH_AUTHORITY docker-compose.yml | grep $CI_NETBIRD_AUTH_AUTHORITY
          grep AUTH_AUDIENCE docker-compose.yml | grep $CI_NETBIRD_AUTH_AUDIENCE
          grep AUTH_SUPPORTED_SCOPES docker-compose.yml | grep "$CI_NETBIRD_AUTH_SUPPORTED_SCOPES"
          grep USE_AUTH0 docker-compose.yml | grep $CI_NETBIRD_USE_AUTH0
          grep NETBIRD_MGMT_API_ENDPOINT docker-compose.yml | grep "$CI_NETBIRD_DOMAIN:33073"
          grep AUTH_REDIRECT_URI docker-compose.yml | grep $CI_NETBIRD_AUTH_REDIRECT_URI
          grep AUTH_SILENT_REDIRECT_URI docker-compose.yml | egrep 'AUTH_SILENT_REDIRECT_URI=$'
          grep $CI_NETBIRD_SIGNAL_PORT docker-compose.yml | grep ':80'
          grep LETSENCRYPT_DOMAIN docker-compose.yml | egrep 'LETSENCRYPT_DOMAIN=$'
          grep NETBIRD_TOKEN_SOURCE docker-compose.yml | grep $CI_NETBIRD_TOKEN_SOURCE
          grep AuthUserIDClaim management.json | grep $CI_NETBIRD_AUTH_USER_ID_CLAIM
          grep -A 3 DeviceAuthorizationFlow management.json | grep -A 1 ProviderConfig | grep Audience | grep $CI_NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE
          grep -A 3 DeviceAuthorizationFlow management.json | grep -A 1 ProviderConfig | grep Audience | grep $CI_NETBIRD_AUTH_DEVICE_AUTH_AUDIENCE
          grep Engine management.json  | grep "$CI_NETBIRD_STORE_CONFIG_ENGINE"
          grep IdpSignKeyRefreshEnabled management.json | grep "$CI_NETBIRD_MGMT_IDP_SIGNKEY_REFRESH"
          grep UseIDToken management.json | grep false
          grep -A 1 IdpManagerConfig management.json | grep ManagerType | grep $CI_NETBIRD_MGMT_IDP
          grep -A 3 IdpManagerConfig management.json | grep -A 1 ClientConfig | grep Issuer | grep $CI_NETBIRD_AUTH_AUTHORITY
          grep -A 4 IdpManagerConfig management.json | grep -A 2 ClientConfig | grep TokenEndpoint | grep $CI_NETBIRD_AUTH_TOKEN_ENDPOINT
          grep -A 5 IdpManagerConfig management.json | grep -A 3 ClientConfig | grep ClientID | grep $CI_NETBIRD_IDP_MGMT_CLIENT_ID
          grep -A 6 IdpManagerConfig management.json | grep -A 4 ClientConfig | grep ClientSecret | grep $CI_NETBIRD_IDP_MGMT_CLIENT_SECRET
          grep -A 7 IdpManagerConfig management.json | grep -A 5 ClientConfig | grep GrantType | grep client_credentials
          grep -A 10 PKCEAuthorizationFlow management.json | grep -A 10 ProviderConfig | grep Audience | grep $CI_NETBIRD_AUTH_AUDIENCE
          grep -A 10 PKCEAuthorizationFlow management.json | grep -A 10 ProviderConfig | grep ClientID | grep $CI_NETBIRD_AUTH_CLIENT_ID
          grep -A 10 PKCEAuthorizationFlow management.json | grep -A 10 ProviderConfig | grep ClientSecret | grep $CI_NETBIRD_AUTH_CLIENT_SECRET
          grep -A 10 PKCEAuthorizationFlow management.json | grep -A 10 ProviderConfig | grep AuthorizationEndpoint | grep $CI_NETBIRD_AUTH_PKCE_AUTHORIZATION_ENDPOINT
          grep -A 10 PKCEAuthorizationFlow management.json | grep -A 10 ProviderConfig | grep TokenEndpoint | grep $CI_NETBIRD_AUTH_TOKEN_ENDPOINT
          grep -A 10 PKCEAuthorizationFlow management.json | grep -A 10 ProviderConfig | grep Scope | grep "$CI_NETBIRD_AUTH_SUPPORTED_SCOPES"
          grep -A 10 PKCEAuthorizationFlow management.json | grep -A 10 ProviderConfig | grep -A 3 RedirectURLs | grep "http://localhost:53000"
          grep "external-ip" turnserver.conf | grep $CI_NETBIRD_TURN_EXTERNAL_IP
          grep "NETBIRD_STORE_ENGINE_MYSQL_DSN=$NETBIRD_STORE_ENGINE_MYSQL_DSN" docker-compose.yml
          grep NETBIRD_STORE_ENGINE_POSTGRES_DSN docker-compose.yml | egrep "$NETBIRD_STORE_ENGINE_POSTGRES_DSN"
          # check relay values
          grep "NB_EXPOSED_ADDRESS=$CI_NETBIRD_DOMAIN:33445" docker-compose.yml
          grep "NB_LISTEN_ADDRESS=:33445" docker-compose.yml
          grep '33445:33445' docker-compose.yml
          grep -A 10 'relay:' docker-compose.yml | egrep 'NB_AUTH_SECRET=.+$'
          grep -A 7 Relay management.json | grep "rel://$CI_NETBIRD_DOMAIN:33445"
          grep -A 7 Relay management.json | egrep '"Secret": ".+"'

      - name: Install modules
        run: go mod tidy

      - name: check git status
        run: git --no-pager diff --exit-code

      - name: Build management binary
        working-directory: management
        run: CGO_ENABLED=1 go build -o netbird-mgmt main.go

      - name: Build management docker image
        working-directory: management
        run: |
          docker build -t netbirdio/management:latest .

      - name: Build signal binary
        working-directory: signal
        run: CGO_ENABLED=0 go build -o netbird-signal main.go

      - name: Build signal docker image
        working-directory: signal
        run: |
          docker build -t netbirdio/signal:latest .

      - name: Build relay binary
        working-directory: relay
        run: CGO_ENABLED=0 go build -o netbird-relay main.go

      - name: Build relay docker image
        working-directory: relay
        run: |
          docker build -t netbirdio/relay:latest .

      - name: run docker compose up
        working-directory: infrastructure_files/artifacts
        run: |
          docker compose up -d
          sleep 5
          docker compose ps
          docker compose logs --tail=20

      - name: test running containers
        run: |
          count=$(docker compose ps --format json | jq '. | select(.Name | contains("artifacts")) | .State' | grep -c running)
          test $count -eq 5 || docker compose logs
        working-directory: infrastructure_files/artifacts

      - name: test geolocation databases
        working-directory: infrastructure_files/artifacts
        run: |
          sleep 30
          docker compose exec management ls -l /var/lib/netbird/ | grep -i GeoLite2-City_[0-9]*.mmdb
          docker compose exec management ls -l /var/lib/netbird/ | grep -i geonames_[0-9]*.db

  test-getting-started-script:
    runs-on: ubuntu-latest
    steps:
      - name: Install jq
        run: sudo apt-get install -y jq

      - name: Checkout code
        uses: actions/checkout@v4

      - name: run script with Zitadel PostgreSQL
        run: NETBIRD_DOMAIN=use-ip bash -x infrastructure_files/getting-started-with-zitadel.sh

      - name: test Caddy file gen postgres
        run: test -f Caddyfile

      - name: test docker-compose file gen postgres
        run: test -f docker-compose.yml

      - name: test management.json file gen postgres
        run: test -f management.json

      - name: test turnserver.conf file gen postgres
        run: |
          set -x
          test -f turnserver.conf
          grep external-ip turnserver.conf

      - name: test zitadel.env file gen postgres
        run: test -f zitadel.env

      - name: test dashboard.env file gen postgres
        run: test -f dashboard.env

      - name: test relay.env file gen postgres
        run: test -f relay.env

      - name: test zdb.env file gen postgres
        run: test -f zdb.env

      - name: Postgres run cleanup
        run: |
          docker compose down --volumes --rmi all
          rm -rf docker-compose.yml Caddyfile zitadel.env dashboard.env machinekey/zitadel-admin-sa.token turnserver.conf management.json zdb.env

      - name: run script with Zitadel CockroachDB
        run: bash -x infrastructure_files/getting-started-with-zitadel.sh
        env:
          NETBIRD_DOMAIN: use-ip
          ZITADEL_DATABASE: cockroach

      - name: test Caddy file gen CockroachDB
        run: test -f Caddyfile

      - name: test docker-compose file gen CockroachDB
        run: test -f docker-compose.yml

      - name: test management.json file gen CockroachDB
        run: test -f management.json

      - name: test turnserver.conf file gen CockroachDB
        run: |
          set -x
          test -f turnserver.conf
          grep external-ip turnserver.conf

      - name: test zitadel.env file gen CockroachDB
        run: test -f zitadel.env

      - name: test dashboard.env file gen CockroachDB
        run: test -f dashboard.env

      - name: test relay.env file gen CockroachDB
        run: test -f relay.env