Skip to content

Developers

Minh Tu Le edited this page Nov 2, 2025 · 4 revisions

Installation

  • Install asdf and asdf-golang. Then run asdf install to install the versions specified in .tool-versions.
  • Install Docker to run the KinD cluster
  • Install KinD to set up a local Kubernetes cluster
  • Install kubectl to interact with the cluster
  • Install helm-unittest plugin for unit-testing the Helm chart
    helm plugin install https://github.com/helm-unittest/helm-unittest.git
    
  • Install Caddy to run a local reverse proxy for the fake Controller in local development and testing
    • Before running Caddy, add the following line to the /etc/hosts file:
      127.0.0.1 acme.test
      

Running locally

tools/local/main.go script runs fake implementations of Twingate components (Client and Controller) to simulate a full end-to-end flow locally from user tools (like kubectl) to the protected resources (a KinD cluster) via a Gateway. The script will also set up the KinD cluster (if it doesn't already exist) with a relevant service account and RBAC rule for the local user.

To run the local setup, from the project's root directory:

  • Run sudo caddy run to start the Caddy reverse proxy using the configuration in Caddyfile. Make sure to update the /etc/hosts file.
  • Run go run ./tools/local/main.go
  • Run the command go run main.go start ... shown in the output to start the Gateway
    • To run the Gateway in GoLand,
      • Create a Go Build configuration
      • Set program arguments to start ... shown in the output. Alternatively, set environment variables instead of command flags.
  • Run kubectl --kubeconfig kubeconfig-local auth whoami to verify the setup is working.

Testing

Unit testing

  • Run make test to run Go unit tests.

Integration testing

  • Goal: Test Gateway functionality with real kubectl CLI and a Kubernetes cluster (using KinD). The Gateway runs as part of Go tests so code coverage is included.

  • Prerequisites:

    • Caddy
    • kubectl CLI
    • Note that KinD clusters are created and instrumented by each test so no need to set up a cluster manually.
  • Test environment:

    • Gateway runs outside the cluster as part of Go tests
    • Caddy runs outside the cluster
    • Mock Client and Controller run outside the cluster
  • Running:

    • From the project's root directory, run sudo caddy run to start the Caddy reverse proxy using the configuration in Caddyfile. Make sure to update the /etc/hosts file (see Installation section above).
    • Run make test-integration to run integration tests.

End-to-end (E2E) testing

  • Goal: Test the full end-to-end flow from user tools (kubectl) to the protected resource (a KinD cluster) via a Gateway within the cluster. The Gateway is packaged as a Docker image and deployed in the KinD cluster as a Helm chart. E2E tests cover both Docker image and Helm chart.

  • Prerequisites:

    • Caddy
    • kubectl CLI
    • kind CLI
      • Note that like integration tests, KinD clusters are auto-created. However, the tests need kind CLI to load the Docker image into the cluster.
  • Test environment:

    • Gateway runs within the cluster as a Helm chart
    • Caddy runs outside the cluster
    • Mock Client and Controller run outside the cluster
  • Running:

    • From the project's root directory, run sudo caddy run to start the Caddy reverse proxy using the configuration in Caddyfile. Make sure to update the /etc/hosts file (see Installation section above).
    • Run make build to build the Docker image.
    • Run make test-e2e to run E2E tests.

Helm testing

  • Run make test-helm to test changes to the Helm chart.
  • If the test snapshot changes are expected, run make test-helm-and-update-snapshots to update the snapshots.

Debugging

You can debug the Gateway locally using Minikube or other Kubernetes environments. The following guide assumes you already have a Connector and a Gateway deployed in your cluster.

Debugging with Minikube

  1. Point Docker to Minikube's Docker Daemon

    This lets you build images directly in the Minikube environment:

    eval $(minikube docker-env)
  2. Build the Debug Image

    Build the debug image using the provided Makefile target. Make sure you have goreleaser installed before running this command.

    make build

    It will create the twingate/kubernetes-access-gateway image with the following tags:

    • <version>-local-<hash>-linux-arm64
    • <version>-local-<hash>-linux-amd64
    • <version>-local-<hash>-linux-amd64-debug
    • <version>-local-<hash>-linux-arm64-debug
  3. Update the Gateway Deployment

    Load the image you want to run into Minikube:

    minikube image load <the image:tag from the previous step>

    Upgrade (or install) the Gateway deployment to use your local debug image and enable diagnostic mode (Delve debugger):

    helm upgrade <release-name> ./deploy/gateway/ --install -f <values.yaml> \
      --set image.tag="<one of the tags from the previous step>" \
      --set livenessProbe.timeoutSeconds=3600 \
      --set readinessProbe.timeoutSeconds=3600

    Note: Replace <release-name> and <values.yaml> with your actual release name and values file.

  4. Port Forward to the Debugger

    Forward port 2345 from the Gateway pod to your local machine:

    kubectl port-forward pod/<gateway-pod> 2345:2345
  5. Connect Your Debugger

    Use your Go debugger (e.g., GoLand, VS Code, or Delve CLI) to connect to 127.0.0.1:2345.

What Happens When Diagnostic Mode Is Enabled?

  • The Gateway container will start with the Delve debugger in headless mode, listening on port 2345.
  • You can set breakpoints and debug the Go process remotely.

Troubleshooting

  • If you have trouble connecting, ensure the pod is running and port 2345 is not already in use locally.
  • If you see connection errors, double-check that diagnostic mode is enabled and the correct image is deployed.

Releasing

We use tags to release. Makefile has shortcut commands to release development or production releases. Semantic Release is used to determine the version (see go tool svu next).

  • make cut-release - release a dev release (ex: v0.2.1-dev+7a5384c)
  • make cut-release-prod - release a production release (ex: v0.2.2)
Clone this wiki locally