func (s *hcloudK8sSetup) PrepareTestEnv(ctx context.Context, additionalSSHKeys []*hcloud.SSHKey, useNetworks bool) (string, error) {
	const op = "hcloudK8sSetup/PrepareTestEnv"
	s.testLabels = map[string]string{"K8sDistribution": string(s.K8sDistribution), "K8sVersion": strings.ReplaceAll(s.K8sVersion, "+", ""), "test": s.TestIdentifier}
	err := s.getSSHKey(ctx)
	if err != nil {
		return "", fmt.Errorf("%s getSSHKey: %s", op, err)
	}
	err = s.getNetwork(ctx)
	if err != nil {
		return "", fmt.Errorf("%s getNetwork: %s", op, err)
	}
	userData, err := s.getCloudInitConfig(true)
	if err != nil {
		fmt.Printf("[cluster-node] %s getCloudInitConfig: %s", op, err)
		return "", err
	}
	srv, err := s.createServer(ctx, "cluster-node", instanceType, additionalSSHKeys, userData)
	if err != nil {
		return "", fmt.Errorf("%s: create cluster node: %v", op, err)
	}
	s.ClusterNode = srv
	s.waitUntilSSHable(srv)
	err = s.waitForCloudInit(srv)
	if err != nil {
		return "", err
	}
	joinCmd, err := s.getJoinCmd()
	if err != nil {
		return "", err
	}
	s.clusterJoinCMD = joinCmd
	err = s.transferDockerImage(s.ClusterNode)
	if err != nil {
		return "", fmt.Errorf("%s: %s", op, err)
	}
	fmt.Printf("[%s] %s: Load Image:\n", s.ClusterNode.Name, op)
	err = RunCommandOnServer(s.privKey, s.ClusterNode, "ctr -n=k8s.io image import ci-hcloud-ccm.tar")
	if err != nil {
		return "", fmt.Errorf("%s: Load image %s", op, err)
	}
	kubeconfigPath, err := s.PrepareK8s(useNetworks)
	if err != nil {
		return "", fmt.Errorf("%s: %s", op, err)
	}
	var workers = 1  
	var wg sync.WaitGroup
	for worker := 1; worker <= workers; worker++ {
		wg.Add(1)
		go s.createClusterWorker(ctx, additionalSSHKeys, &wg, worker)
	}
	wg.Wait()
	srv, err = s.createServer(ctx, "ext-server", instanceType, additionalSSHKeys, "")
	if err != nil {
		return "", fmt.Errorf("%s: create ext server: %v", op, err)
	}
	s.ExtServer = srv
	s.waitUntilSSHable(srv)
	return kubeconfigPath, nil
}
PrepareTestEnv setups a test environment for the Cloud Controller Manager
This includes the creation of a Network, SSH Key and Server.
The server will be created with a Cloud Init UserData
The template can be found under e2etests/templates/cloudinit_<k8s-distribution>.ixt.tpl
package e2etests
import (
	"bytes"
	"context"
	"crypto/rand"
	"crypto/rsa"
	"crypto/x509"
	"encoding/pem"
	"fmt"
	"html/template"
	"io"
	"io/ioutil"
	"net"
	"os"
	"os/exec"
	"strings"
	"sync"
	"time"
	"github.com/hetznercloud/hcloud-go/hcloud"
	"golang.org/x/crypto/ssh"
)
type K8sDistribution string
const (
	K8sDistributionK8s K8sDistribution = "k8s"
	K8sDistributionK3s K8sDistribution = "k3s"
)
var instanceType = "cpx21"
type hcloudK8sSetup struct {
	Hcloud          *hcloud.Client
	HcloudToken     string
	K8sVersion      string
	K8sDistribution K8sDistribution
	TestIdentifier  string
	ImageName       string
	KeepOnFailure   bool
	ClusterNode     *hcloud.Server
	ExtServer       *hcloud.Server
	privKey         string
	sshKey          *hcloud.SSHKey
	network         *hcloud.Network
	clusterJoinCMD  string
	WorkerNodes     []*hcloud.Server
	testLabels      map[string]string
}
type cloudInitTmpl struct {
	K8sVersion      string
	HcloudToken     string
	HcloudNetwork   string
	IsClusterServer bool
	JoinCMD         string
}