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: Checkout code
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          persist-credentials: false

      - name: Install Go
        uses: actions/setup-go@924ae3a1cded613372ab5595356fb5720e22ba16 # v6.5.0
        with:
          go-version-file: "go.mod"

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

      - name: Setup MySQL privileges
        if: matrix.store == 'mysql'
        run: |
          sleep 10
          mysql -h 127.0.0.1 -u root -pmysqlroot -e "
            GRANT SYSTEM_VARIABLES_ADMIN ON *.* TO 'netbird'@'%';
            FLUSH PRIVILEGES;
          "

      - 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"
          CI_NETBIRD_MGMT_DISABLE_DEFAULT_POLICY: false

        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=rels://$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 "rels://$CI_NETBIRD_DOMAIN:33445"
          grep -A 7 Relay management.json | egrep '"Secret": ".+"'
          grep DisablePromptLogin management.json | grep 'true'
          grep LoginFlag management.json | grep 0
          grep DisableDefaultPolicy management.json | grep "$CI_NETBIRD_MGMT_DISABLE_DEFAULT_POLICY"

      - 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 --build-arg TARGETPLATFORM=. .

      - 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 --build-arg TARGETPLATFORM=. .

      - 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 --build-arg TARGETPLATFORM=. .

      - 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 logs
          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-legacy-getting-started-scripts:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
        with:
          persist-credentials: false

      - name: Verify Dex retirement notice
        run: |
          if infrastructure_files/getting-started-with-dex.sh >stdout.txt 2>stderr.txt; then
            echo "Expected the retired Dex installer to fail"
            exit 1
          fi
          test ! -s stdout.txt
          grep -Fq "Dex support is not deprecated." stderr.txt
          grep -Fq "https://docs.netbird.io/selfhosted/selfhosted-quickstart" stderr.txt
          grep -Fq "https://docs.netbird.io/selfhosted/identity-providers/local" stderr.txt
          grep -Fq "removed in NetBird v0.80" stderr.txt

      - name: Verify Zitadel retirement notice
        run: |
          if bash infrastructure_files/getting-started-with-zitadel.sh >stdout.txt 2>stderr.txt; then
            echo "Expected the retired Zitadel installer to fail"
            exit 1
          fi
          test ! -s stdout.txt
          grep -Fq "Zitadel support and existing Zitadel deployments are not deprecated." stderr.txt
          grep -Fq "https://docs.netbird.io/selfhosted/selfhosted-quickstart" stderr.txt
          grep -Fq "https://docs.netbird.io/selfhosted/identity-providers/zitadel" stderr.txt
          grep -Fq "https://docs.netbird.io/selfhosted/selfhosted-guide" stderr.txt
          grep -Fq "removed in NetBird v0.80" stderr.txt
