VirtualMachine: Implement virtual machines using KubeVirt

Auto adds new VM into given user's Tailscale network

Change-Id: I16847a0b9eacc17b0e794d3b4913eb1d80a93f0a
diff --git a/core/installer/derived_test.go b/core/installer/derived_test.go
new file mode 100644
index 0000000..7a34154
--- /dev/null
+++ b/core/installer/derived_test.go
@@ -0,0 +1,34 @@
+package installer
+
+import (
+	"testing"
+)
+
+type testKeyGen struct{}
+
+func (g testKeyGen) Generate(username string) (string, error) {
+	return username, nil
+}
+
+func TestDeriveVPNAuthKey(t *testing.T) {
+	schema := structSchema{
+		"input",
+		[]Field{
+			Field{"username", basicSchema{"username", KindString, false, nil}},
+			Field{"authKey", basicSchema{"authKey", KindVPNAuthKey, false, map[string]string{
+				"usernameField": "username",
+			}}},
+		},
+		false,
+	}
+	input := map[string]any{
+		"username": "foo",
+	}
+	v, err := deriveValues(input, input, schema, nil, testKeyGen{})
+	if err != nil {
+		t.Fatal(err)
+	}
+	if key, ok := v["authKey"].(string); !ok || key != "foo" {
+		t.Fatal(v)
+	}
+}