diff --git a/.gitignore b/.gitignore index bbdc572..eb54e97 100644 --- a/.gitignore +++ b/.gitignore @@ -33,7 +33,7 @@ go.work # Google App Engine generated folder appengine-generated/ -/components/*/*.go +#/components/*/*.go /components/*/*.txt .idea *.iml diff --git a/components/core/html_templ.go b/components/core/html_templ.go new file mode 100644 index 0000000..3e4d22e --- /dev/null +++ b/components/core/html_templ.go @@ -0,0 +1,137 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package core + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +import "vctp/version" + +func HTML(title string, content templ.Component) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = head(title).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = body(content).Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func head(title string) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var2 := templ.GetChildren(ctx) + if templ_7745c5c3_Var2 == nil { + templ_7745c5c3_Var2 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + var templ_7745c5c3_Var3 string + templ_7745c5c3_Var3, templ_7745c5c3_Err = templ.JoinStringErrs(title) + if templ_7745c5c3_Err != nil { + return templ.Error{Err: templ_7745c5c3_Err, FileName: `core/html.templ`, Line: 18, Col: 16} + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString(templ.EscapeString(templ_7745c5c3_Var3)) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +func body(content templ.Component) templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var5 := templ.GetChildren(ctx) + if templ_7745c5c3_Var5 == nil { + templ_7745c5c3_Var5 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + templ_7745c5c3_Err = content.Render(ctx, templ_7745c5c3_Buffer) + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("
") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/components/home/home_templ.go b/components/home/home_templ.go new file mode 100644 index 0000000..6460656 --- /dev/null +++ b/components/home/home_templ.go @@ -0,0 +1,37 @@ +// Code generated by templ - DO NOT EDIT. + +// templ: version: v0.2.771 +package home + +//lint:file-ignore SA4006 This context is only used if a nested component is present. + +import "github.com/a-h/templ" +import templruntime "github.com/a-h/templ/runtime" + +func Home() templ.Component { + return templruntime.GeneratedTemplate(func(templ_7745c5c3_Input templruntime.GeneratedComponentInput) (templ_7745c5c3_Err error) { + templ_7745c5c3_W, ctx := templ_7745c5c3_Input.Writer, templ_7745c5c3_Input.Context + templ_7745c5c3_Buffer, templ_7745c5c3_IsBuffer := templruntime.GetBuffer(templ_7745c5c3_W) + if !templ_7745c5c3_IsBuffer { + defer func() { + templ_7745c5c3_BufErr := templruntime.ReleaseBuffer(templ_7745c5c3_Buffer) + if templ_7745c5c3_Err == nil { + templ_7745c5c3_Err = templ_7745c5c3_BufErr + } + }() + } + ctx = templ.InitializeContext(ctx) + templ_7745c5c3_Var1 := templ.GetChildren(ctx) + if templ_7745c5c3_Var1 == nil { + templ_7745c5c3_Var1 = templ.NopComponent + } + ctx = templ.ClearChildren(ctx) + _, templ_7745c5c3_Err = templ_7745c5c3_Buffer.WriteString("

Welcome!

This is a simple home screen.

") + if templ_7745c5c3_Err != nil { + return templ_7745c5c3_Err + } + return templ_7745c5c3_Err + }) +} + +var _ = templruntime.GeneratedTemplate diff --git a/e2e/e2e_test.go b/e2e/e2e_test.go.txt similarity index 100% rename from e2e/e2e_test.go rename to e2e/e2e_test.go.txt diff --git a/e2e/home_test.go b/e2e/home_test.go.txt similarity index 100% rename from e2e/home_test.go rename to e2e/home_test.go.txt diff --git a/go.mod b/go.mod index 99ae867..3dd56a3 100644 --- a/go.mod +++ b/go.mod @@ -6,35 +6,24 @@ require ( github.com/a-h/templ v0.2.778 github.com/jmoiron/sqlx v1.4.0 github.com/joho/godotenv v1.5.1 - github.com/playwright-community/playwright-go v0.4201.1 github.com/pressly/goose/v3 v3.22.0 - github.com/stretchr/testify v1.9.0 - github.com/tursodatabase/libsql-client-go v0.0.0-20240902231107-85af5b9d094d github.com/vmware/govmomi v0.43.0 modernc.org/sqlite v1.33.0 ) require ( - github.com/antlr4-go/antlr/v4 v4.13.1 // indirect - github.com/coder/websocket v1.8.12 // indirect - github.com/davecgh/go-spew v1.1.1 // indirect - github.com/deckarep/golang-set/v2 v2.6.0 // indirect github.com/dustin/go-humanize v1.0.1 // indirect - github.com/go-jose/go-jose/v3 v3.0.1 // indirect - github.com/go-stack/stack v1.8.1 // indirect github.com/google/uuid v1.6.0 // indirect github.com/hashicorp/golang-lru/v2 v2.0.7 // indirect github.com/mattn/go-isatty v0.0.20 // indirect github.com/mfridman/interpolate v0.0.2 // indirect github.com/ncruces/go-strftime v0.1.9 // indirect - github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec // indirect github.com/sethvargo/go-retry v0.3.0 // indirect go.uber.org/multierr v1.11.0 // indirect - golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 // indirect golang.org/x/sync v0.8.0 // indirect golang.org/x/sys v0.25.0 // indirect - gopkg.in/yaml.v3 v3.0.1 // indirect + golang.org/x/tools v0.25.0 // indirect modernc.org/gc/v3 v3.0.0-20240801135723-a856999a2e4a // indirect modernc.org/mathutil v1.6.0 // indirect modernc.org/memory v1.8.0 // indirect diff --git a/go.sum b/go.sum index cd55cf4..2592025 100644 --- a/go.sum +++ b/go.sum @@ -2,24 +2,12 @@ filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA= filippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4= github.com/a-h/templ v0.2.778 h1:VzhOuvWECrwOec4790lcLlZpP4Iptt5Q4K9aFxQmtaM= github.com/a-h/templ v0.2.778/go.mod h1:lq48JXoUvuQrU0VThrK31yFwdRjTCnIE5bcPCM9IP1w= -github.com/antlr4-go/antlr/v4 v4.13.1 h1:SqQKkuVZ+zWkMMNkjy5FZe5mr5WURWnlpmOuzYWrPrQ= -github.com/antlr4-go/antlr/v4 v4.13.1/go.mod h1:GKmUxMtwp6ZgGwZSva4eWPC5mS6vUAmOABFgjdkM7Nw= -github.com/coder/websocket v1.8.12 h1:5bUXkEPPIbewrnkU8LTCLVaxi4N4J8ahufH2vlo4NAo= -github.com/coder/websocket v1.8.12/go.mod h1:LNVeNrXQZfe5qhS9ALED3uA+l5pPqvwXg3CKoDBB2gs= -github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/deckarep/golang-set/v2 v2.6.0 h1:XfcQbWM1LlMB8BsJ8N9vW5ehnnPVIw0je80NsVHagjM= -github.com/deckarep/golang-set/v2 v2.6.0/go.mod h1:VAky9rY/yGXJOLEDv3OMci+7wtDpOF4IN+y82NBOac4= github.com/dustin/go-humanize v1.0.1 h1:GzkhY7T5VNhEkwH0PVJgjz+fX1rhBrR7pRT3mDkpeCY= github.com/dustin/go-humanize v1.0.1/go.mod h1:Mu1zIs6XwVuF/gI1OepvI0qD18qycQx+mFykh5fBlto= -github.com/go-jose/go-jose/v3 v3.0.1 h1:pWmKFVtt+Jl0vBZTIpz/eAKwsm6LkIxDVVbFHKkchhA= -github.com/go-jose/go-jose/v3 v3.0.1/go.mod h1:RNkWWRld676jZEYoV3+XK8L2ZnNSvIsxFMht0mSX+u8= github.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y= github.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg= -github.com/go-stack/stack v1.8.1 h1:ntEHSVwIt7PNXNpgPmVfMrNhLtgjlmnZha2kOpuRiDw= -github.com/go-stack/stack v1.8.1/go.mod h1:dcoOX6HbPZSZptuspn9bctJ+N/CnF5gGygcUP3XYfe4= -github.com/google/go-cmp v0.5.0/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI= github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/google/pprof v0.0.0-20240409012703-83162a5b38cd h1:gbpYu9NMq8jhDVbvlGkMFWCjLFlqqEZjEmObmhUy6Vo= @@ -32,10 +20,6 @@ github.com/jmoiron/sqlx v1.4.0 h1:1PLqN7S1UYp5t4SrVVnt4nUVNemrDAtxlulVe+Qgm3o= github.com/jmoiron/sqlx v1.4.0/go.mod h1:ZrZ7UsYB/weZdl2Bxg6jCRO9c3YHl8r3ahlKmRT4JLY= github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0= github.com/joho/godotenv v1.5.1/go.mod h1:f4LDr5Voq0i2e/R5DDNOoa2zzDfwtkZa6DnEwAbqwq4= -github.com/kr/pretty v0.3.1 h1:flRD4NNwYAUpkphVc1HcthR4KEIFJ65n8Mw5qdRn3LE= -github.com/kr/pretty v0.3.1/go.mod h1:hoEshYVHaxMs3cyo3Yncou5ZscifuDolrwPKZanG3xk= -github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= -github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw= github.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= @@ -44,54 +28,31 @@ github.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o github.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y= github.com/mfridman/interpolate v0.0.2 h1:pnuTK7MQIxxFz1Gr+rjSIx9u7qVjf5VOoM/u6BbAxPY= github.com/mfridman/interpolate v0.0.2/go.mod h1:p+7uk6oE07mpE/Ik1b8EckO0O4ZXiGAfshKBWLUM9Xg= -github.com/mitchellh/go-ps v1.0.0 h1:i6ampVEEF4wQFF+bkYfwYgY+F/uYJDktmvLPf7qIgjc= -github.com/mitchellh/go-ps v1.0.0/go.mod h1:J4lOc8z8yJs6vUwklHw2XEIiT4z4C40KtWVN3nvg8Pg= github.com/ncruces/go-strftime v0.1.9 h1:bY0MQC28UADQmHmaF5dgpLmImcShSi2kHU9XLdhx/f4= github.com/ncruces/go-strftime v0.1.9/go.mod h1:Fwc5htZGVVkseilnfgOVb9mKy6w1naJmn9CehxcKcls= -github.com/playwright-community/playwright-go v0.4201.1 h1:fFX/02r3wrL+8NB132RcduR0lWEofxRDJEKuln+9uMQ= -github.com/playwright-community/playwright-go v0.4201.1/go.mod h1:hpEOnUo/Kgb2lv5lEY29jbW5Xgn7HaBeiE+PowRad8k= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/pressly/goose/v3 v3.22.0 h1:wd/7kNiPTuNAztWun7iaB98DrhulbWPrzMAaw2DEZNw= github.com/pressly/goose/v3 v3.22.0/go.mod h1:yJM3qwSj2pp7aAaCvso096sguezamNb2OBgxCnh/EYg= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec h1:W09IVJc94icq4NjY3clb7Lk8O1qJ8BdBEF8z0ibU0rE= github.com/remyoudompheng/bigfft v0.0.0-20230129092748-24d4a6f8daec/go.mod h1:qqbHyh8v60DhA7CoWK5oRCqLrMHRGoxYCSS9EjAz6Eo= -github.com/rogpeppe/go-internal v1.11.0 h1:cWPaGQEPrBb5/AsnsZesgZZ9yb1OQ+GOISoDNXVBh4M= -github.com/rogpeppe/go-internal v1.11.0/go.mod h1:ddIwULY96R17DhadqLgMfk9H9tvdUzkipdSkR5nkCZA= github.com/sethvargo/go-retry v0.3.0 h1:EEt31A35QhrcRZtrYFDTBg91cqZVnFL2navjDrah2SE= github.com/sethvargo/go-retry v0.3.0/go.mod h1:mNX17F0C/HguQMyMyJxcnU471gOZGxCLyYaFyAZraas= -github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg= github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY= -github.com/tursodatabase/libsql-client-go v0.0.0-20240902231107-85af5b9d094d h1:dOMI4+zEbDI37KGb0TI44GUAwxHF9cMsIoDTJ7UmgfU= -github.com/tursodatabase/libsql-client-go v0.0.0-20240902231107-85af5b9d094d/go.mod h1:l8xTsYB90uaVdMHXMCxKKLSgw5wLYBwBKKefNIUnm9s= github.com/vmware/govmomi v0.43.0 h1:7Kg3Bkdly+TrE67BYXzRq7ZrDnn7xqpKX95uEh2f9Go= github.com/vmware/govmomi v0.43.0/go.mod h1:IOv5nTXCPqH9qVJAlRuAGffogaLsNs8aF+e7vLgsHJU= go.uber.org/multierr v1.11.0 h1:blXXJkSxSSfBVBlC76pxqeO+LN3aDfLQo+309xJstO0= go.uber.org/multierr v1.11.0/go.mod h1:20+QtiLqy0Nd6FdQB9TLXag12DsQkrbs3htMFfDN80Y= -golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190911031432-227b76d455e7/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0 h1:e66Fs6Z+fZTbFBAxKfP3PALWBtpfqks2bwGcexMxgtk= -golang.org/x/exp v0.0.0-20240909161429-701f63a606c0/go.mod h1:2TbTHSBQa924w8M6Xs1QcRcFwyucIwBGpK1p2f1YFFY= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY= -golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= -golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE= golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg= -golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk= -gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c/go.mod h1:JHkPIbrfpd72SG/EVd6muEfDQjcINNoR0C8j2r3qZ4Q= -gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= modernc.org/fileutil v1.3.0 h1:gQ5SIzK3H9kdfai/5x41oQiKValumqNTDXMvKo62HvE= diff --git a/internal/vcenter/vcenter.go b/internal/vcenter/vcenter.go index c50ff99..18eb3e4 100644 --- a/internal/vcenter/vcenter.go +++ b/internal/vcenter/vcenter.go @@ -9,9 +9,11 @@ import ( "os" "github.com/vmware/govmomi" + "github.com/vmware/govmomi/find" "github.com/vmware/govmomi/view" "github.com/vmware/govmomi/vim25/mo" "github.com/vmware/govmomi/vim25/soap" + "github.com/vmware/govmomi/vim25/types" ) type Vcenter struct { @@ -20,6 +22,11 @@ type Vcenter struct { client *govmomi.Client } +type VmProperties struct { + Vm mo.VirtualMachine + Datacenter string +} + // New creates a new Vcenter with the given logger func New(logger *slog.Logger) *Vcenter { @@ -104,3 +111,44 @@ func (v *Vcenter) FindVMByName(vmName string) ([]mo.VirtualMachine, error) { return result, nil } + +func (v *Vcenter) FindVMByID(vmID string) (*VmProperties, error) { + finder := find.NewFinder(v.client.Client, true) + + // List all datacenters + datacenters, err := finder.DatacenterList(v.ctx, "*") + if err != nil { + return nil, fmt.Errorf("failed to list datacenters: %w", err) + } + + for _, dc := range datacenters { + // Set the current datacenter + finder.SetDatacenter(dc) + + // Create a ManagedObjectReference for the VM + vmRef := types.ManagedObjectReference{ + Type: "VirtualMachine", + Value: vmID, + } + + // Try to find the VM by ID in the current datacenter + //vm, err := finder.ObjectReference(v.ctx, vmRef) + + var vm mo.VirtualMachine + err := v.client.RetrieveOne(v.ctx, vmRef, []string{"config", "name"}, &vm) + if err != nil { + // If the error is not a NotFoundError, return it + if err == err.(*find.NotFoundError) { + return nil, fmt.Errorf("failed to retrieve VM with ID %s in datacenter %s: %w", vmID, dc.Name(), err) + } + return nil, fmt.Errorf("failed to retrieve VM: %w", err) + } + + return &VmProperties{ + Datacenter: dc.Name(), + Vm: vm, + }, nil + } + + return nil, fmt.Errorf("VM with ID %s not found in any datacenter", vmID) +} diff --git a/server/handler/vmCreate.go b/server/handler/vmCreate.go index 5b0d1e4..7d03dea 100644 --- a/server/handler/vmCreate.go +++ b/server/handler/vmCreate.go @@ -7,6 +7,7 @@ import ( "fmt" "io" "net/http" + "runtime" "time" queries "vctp/db/queries" "vctp/internal/vcenter" @@ -15,7 +16,11 @@ import ( // VmCreate receives the CloudEvent for a VM creation func (h *Handler) VmCreate(w http.ResponseWriter, r *http.Request) { - var unixTimestamp int64 + var ( + unixTimestamp int64 + numVcpus int32 + numRam int32 + ) reqBody, err := io.ReadAll(r.Body) if err != nil { @@ -51,11 +56,17 @@ func (h *Handler) VmCreate(w http.ResponseWriter, r *http.Request) { // TODO - initiate govmomi query of source vcenter to discover related data vc := vcenter.New(h.Logger) vc.Login(vm.CloudEvent.Source) - vmObject, err := vc.FindVMByName(vm.CloudEvent.Data.VM.Name) + //vmObject, err := vc.FindVMByName(vm.CloudEvent.Data.VM.Name) + vmObject, err := vc.FindVMByID(vm.CloudEvent.Data.VM.VM.Value) if err != nil { - h.Logger.Error("Can't locate vm in vCenter", "vmName", vm.CloudEvent.Data.VM.Name, "error", err) + h.Logger.Error("Can't locate vm in vCenter", "vmID", vm.CloudEvent.Data.VM.VM.Value, "error", err) } else { - h.Logger.Debug("found VM", "object", vmObject) + //h.Logger.Debug("found VM", "object", vmObject) + //prettyPrint(vmObject) + + // calculate VM properties we want to store + numRam = vmObject.Vm.Config.Hardware.MemoryMB + numVcpus = vmObject.Vm.Config.Hardware.NumCPU * vmObject.Vm.Config.Hardware.NumCoresPerSocket } vc.Logout() @@ -64,7 +75,10 @@ func (h *Handler) VmCreate(w http.ResponseWriter, r *http.Request) { Name: vm.CloudEvent.Data.VM.Name, Vcenter: vm.CloudEvent.Source, VmId: sql.NullString{String: "VirtualMachine-" + vm.CloudEvent.Data.VM.VM.Value, Valid: vm.CloudEvent.Data.VM.VM.Value != ""}, + Datacenter: sql.NullString{String: vmObject.Datacenter, Valid: vmObject.Datacenter != ""}, CreationTime: sql.NullInt64{Int64: unixTimestamp, Valid: unixTimestamp > 0}, + InitialVcpus: sql.NullInt64{Int64: int64(numVcpus), Valid: numVcpus > 0}, + InitialRam: sql.NullInt64{Int64: int64(numRam), Valid: numRam > 0}, } h.Logger.Debug("database params", "vm", vm) @@ -82,3 +96,30 @@ func (h *Handler) VmCreate(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusOK) fmt.Fprintf(w, "Create Request : %v\n", result) } + +func prettyPrint(args ...interface{}) { + var caller string + + timeNow := time.Now().Format("01-02-2006 15:04:05") + prefix := fmt.Sprintf("[%s] %s -- ", "PrettyPrint", timeNow) + _, fileName, fileLine, ok := runtime.Caller(1) + + if ok { + caller = fmt.Sprintf("%s:%d", fileName, fileLine) + } else { + caller = "" + } + + fmt.Printf("\n%s%s\n", prefix, caller) + + if len(args) == 2 { + label := args[0] + value := args[1] + + s, _ := json.MarshalIndent(value, "", "\t") + fmt.Printf("%s%s: %s\n", prefix, label, string(s)) + } else { + s, _ := json.MarshalIndent(args, "", "\t") + fmt.Printf("%s%s\n", prefix, string(s)) + } +} diff --git a/vm.json b/vm.json new file mode 100644 index 0000000..6a4c97b --- /dev/null +++ b/vm.json @@ -0,0 +1,736 @@ +{ + "self": { + "type": "VirtualMachine", + "value": "vm-13671" + }, + "value": null, + "availableField": null, + "parent": null, + "customValue": null, + "overallStatus": "", + "configStatus": "", + "configIssue": null, + "effectiveRole": null, + "permission": null, + "name": "minecraft", + "disabledMethod": null, + "recentTask": null, + "declaredAlarmState": null, + "triggeredAlarmState": null, + "alarmActionsEnabled": null, + "tag": null, + "capability": { + "snapshotOperationsSupported": false, + "multipleSnapshotsSupported": false, + "snapshotConfigSupported": false, + "poweredOffSnapshotsSupported": false, + "memorySnapshotsSupported": false, + "revertToSnapshotSupported": false, + "quiescedSnapshotsSupported": false, + "disableSnapshotsSupported": false, + "lockSnapshotsSupported": false, + "consolePreferencesSupported": false, + "cpuFeatureMaskSupported": false, + "s1AcpiManagementSupported": false, + "settingScreenResolutionSupported": false, + "toolsAutoUpdateSupported": false, + "vmNpivWwnSupported": false, + "npivWwnOnNonRdmVmSupported": false, + "swapPlacementSupported": false, + "toolsSyncTimeSupported": false, + "virtualMmuUsageSupported": false, + "diskSharesSupported": false, + "bootOptionsSupported": false, + "settingVideoRamSizeSupported": false + }, + "config": { + "changeVersion": "2024-05-24T06:41:25.868508Z", + "modified": "1970-01-01T00:00:00Z", + "name": "minecraft", + "guestFullName": "Ubuntu Linux (32-bit)", + "version": "vmx-08", + "uuid": "422598c8-5ab7-63e7-ba34-8111936fea59", + "createDate": "1970-01-01T00:00:00Z", + "instanceUuid": "50251955-6d1b-8954-ae28-50284dd4b44e", + "npivTemporaryDisabled": true, + "locationId": "564d4d65-27af-07d1-d627-70d056c7f233", + "template": false, + "guestId": "ubuntuGuest", + "alternateGuestName": "", + "files": { + "vmPathName": "[freenas] minecraft/minecraft.vmx", + "snapshotDirectory": "[freenas] minecraft/", + "suspendDirectory": "[freenas] minecraft/", + "logDirectory": "[freenas] minecraft/" + }, + "tools": { + "toolsVersion": 10362, + "afterPowerOn": true, + "afterResume": true, + "beforeGuestStandby": true, + "beforeGuestShutdown": true, + "toolsUpgradePolicy": "upgradeAtPowerCycle", + "syncTimeWithHostAllowed": true, + "syncTimeWithHost": true, + "lastInstallInfo": { + "counter": 6 + } + }, + "flags": { + "enableLogging": true, + "useToe": false, + "runWithDebugInfo": false, + "monitorType": "release", + "htSharing": "any", + "snapshotDisabled": false, + "snapshotLocked": false, + "diskUuidEnabled": false, + "snapshotPowerOffBehavior": "powerOff", + "recordReplayEnabled": false, + "faultToleranceType": "unset", + "vvtdEnabled": false, + "vbsEnabled": false + }, + "defaultPowerOps": { + "powerOffType": "soft", + "suspendType": "hard", + "resetType": "soft", + "defaultPowerOffType": "soft", + "defaultSuspendType": "hard", + "defaultResetType": "soft", + "standbyAction": "checkpoint" + }, + "hardware": { + "numCPU": 1, + "numCoresPerSocket": 1, + "autoCoresPerSocket": false, + "memoryMB": 3072, + "virtualICH7MPresent": false, + "virtualSMCPresent": false, + "device": [ + { + "key": 100, + "deviceInfo": { + "label": "PCI controller 0", + "summary": "PCI controller 0" + }, + "busNumber": 0, + "device": [ + 500, + 12000, + 1000, + 4000 + ] + }, + { + "key": 200, + "deviceInfo": { + "label": "IDE 0", + "summary": "IDE 0" + }, + "busNumber": 0 + }, + { + "key": 201, + "deviceInfo": { + "label": "IDE 1", + "summary": "IDE 1" + }, + "busNumber": 1, + "device": [ + 3002 + ] + }, + { + "key": 300, + "deviceInfo": { + "label": "PS2 controller 0", + "summary": "PS2 controller 0" + }, + "busNumber": 0, + "device": [ + 600, + 700 + ] + }, + { + "key": 400, + "deviceInfo": { + "label": "SIO controller 0", + "summary": "SIO controller 0" + }, + "busNumber": 0, + "device": [ + 8000 + ] + }, + { + "key": 500, + "deviceInfo": { + "label": "Video card ", + "summary": "Video card" + }, + "controllerKey": 100, + "unitNumber": 0, + "videoRamSizeInKB": 4096, + "numDisplays": 1, + "useAutoDetect": false, + "enable3DSupport": false, + "use3dRenderer": "automatic", + "graphicsMemorySizeInKB": 262144 + }, + { + "key": 600, + "deviceInfo": { + "label": "Keyboard ", + "summary": "Keyboard" + }, + "controllerKey": 300, + "unitNumber": 0 + }, + { + "key": 700, + "deviceInfo": { + "label": "Pointing device", + "summary": "Pointing device; Device" + }, + "backing": { + "deviceName": "", + "useAutoDetect": false, + "hostPointingDevice": "autodetect" + }, + "controllerKey": 300, + "unitNumber": 1 + }, + { + "key": 1000, + "deviceInfo": { + "label": "SCSI controller 0", + "summary": "LSI Logic" + }, + "slotInfo": { + "pciSlotNumber": 16 + }, + "controllerKey": 100, + "unitNumber": 3, + "busNumber": 0, + "device": [ + 2000 + ], + "hotAddRemove": true, + "sharedBus": "noSharing", + "scsiCtlrUnitNumber": 7 + }, + { + "key": 2000, + "deviceInfo": { + "label": "Hard disk 1", + "summary": "62,914,560 KB" + }, + "backing": { + "fileName": "[freenas] minecraft/minecraft-000002.vmdk", + "datastore": { + "type": "Datastore", + "value": "datastore-6035" + }, + "diskMode": "persistent", + "split": false, + "writeThrough": false, + "thinProvisioned": true, + "eagerlyScrub": false, + "uuid": "6000C294-55e8-39b9-1852-00dcfd299398", + "contentId": "b739ed36bfc510b2f1c70000e628ed40", + "parent": { + "fileName": "[freenas] minecraft/minecraft-000001.vmdk", + "datastore": { + "type": "Datastore", + "value": "datastore-6035" + }, + "diskMode": "persistent", + "thinProvisioned": true, + "eagerlyScrub": false, + "uuid": "6000C294-55e8-39b9-1852-00dcfd299398", + "contentId": "45ff3b3b3935d631facb7eadbb916797", + "parent": { + "fileName": "[freenas] minecraft/minecraft.vmdk", + "datastore": { + "type": "Datastore", + "value": "datastore-6035" + }, + "diskMode": "persistent", + "thinProvisioned": true, + "eagerlyScrub": false, + "uuid": "6000C294-55e8-39b9-1852-00dcfd299398", + "contentId": "8e6ae3c31967c906303f7b3fe1b379f8", + "digestEnabled": false + }, + "deltaDiskFormat": "redoLogFormat", + "digestEnabled": false, + "deltaDiskFormatVariant": "vmfsSparseVariant" + }, + "deltaDiskFormat": "redoLogFormat", + "digestEnabled": false, + "deltaDiskFormatVariant": "vmfsSparseVariant", + "sharing": "sharingNone" + }, + "controllerKey": 1000, + "unitNumber": 0, + "capacityInKB": 62914560, + "capacityInBytes": 64424509440, + "shares": { + "shares": 1000, + "level": "normal" + }, + "storageIOAllocation": { + "limit": -1, + "shares": { + "shares": 1000, + "level": "normal" + }, + "reservation": 0 + }, + "diskObjectId": "271-2000", + "vDiskVersion": 1, + "nativeUnmanagedLinkedClone": false, + "guestReadOnly": false + }, + { + "key": 3002, + "deviceInfo": { + "label": "CD/DVD drive 1", + "summary": "ISO [] /usr/lib/vmware/isoimages/linux.iso" + }, + "backing": { + "fileName": "[] /usr/lib/vmware/isoimages/linux.iso" + }, + "connectable": { + "startConnected": false, + "allowGuestControl": true, + "connected": false, + "status": "untried" + }, + "controllerKey": 201, + "unitNumber": 0 + }, + { + "key": 4000, + "deviceInfo": { + "label": "Network adapter 1", + "summary": "DVSwitch: 50 02 bc 27 fa 1b 2c d1-0d 43 fb 29 46 60 c4 0b" + }, + "backing": { + "port": { + "switchUuid": "50 02 bc 27 fa 1b 2c d1-0d 43 fb 29 46 60 c4 0b", + "portgroupKey": "dvportgroup-4031", + "portKey": "102", + "connectionCookie": 209430599 + } + }, + "connectable": { + "migrateConnect": "unset", + "startConnected": true, + "allowGuestControl": true, + "connected": false, + "status": "untried" + }, + "slotInfo": { + "pciSlotNumber": 32 + }, + "controllerKey": 100, + "unitNumber": 7, + "addressType": "assigned", + "macAddress": "00:50:56:a5:16:29", + "wakeOnLanEnabled": true, + "resourceAllocation": { + "reservation": 0, + "share": { + "shares": 50, + "level": "normal" + }, + "limit": -1 + }, + "uptCompatibilityEnabled": false + }, + { + "key": 8000, + "deviceInfo": { + "label": "Floppy drive 1", + "summary": "Remote" + }, + "backing": { + "deviceName": "", + "useAutoDetect": false + }, + "connectable": { + "startConnected": false, + "allowGuestControl": true, + "connected": false, + "status": "untried" + }, + "controllerKey": 400, + "unitNumber": 0 + }, + { + "key": 12000, + "deviceInfo": { + "label": "VMCI device", + "summary": "Device on the virtual machine PCI bus that provides support for the virtual machine communication interface" + }, + "slotInfo": { + "pciSlotNumber": 33 + }, + "controllerKey": 100, + "unitNumber": 17, + "id": -1821382055, + "allowUnrestrictedCommunication": false, + "filterEnable": true + } + ], + "motherboardLayout": "i440bxHostBridge", + "simultaneousThreads": 1 + }, + "cpuAllocation": { + "reservation": 0, + "expandableReservation": false, + "limit": -1, + "shares": { + "shares": 1000, + "level": "normal" + } + }, + "memoryAllocation": { + "reservation": 0, + "expandableReservation": false, + "limit": -1, + "shares": { + "shares": 30720, + "level": "normal" + } + }, + "latencySensitivity": { + "level": "normal" + }, + "memoryHotAddEnabled": false, + "cpuHotAddEnabled": false, + "cpuHotRemoveEnabled": false, + "extraConfig": [ + { + "key": "svga.present", + "value": "TRUE" + }, + { + "key": "vmci.filter.enable", + "value": "TRUE" + }, + { + "key": "tools.guest.desktop.autolock", + "value": "FALSE" + }, + { + "key": "pciBridge0.present", + "value": "true" + }, + { + "key": "pciBridge4.present", + "value": "true" + }, + { + "key": "pciBridge4.virtualDev", + "value": "pcieRootPort" + }, + { + "key": "pciBridge4.functions", + "value": "8" + }, + { + "key": "pciBridge5.present", + "value": "true" + }, + { + "key": "pciBridge5.virtualDev", + "value": "pcieRootPort" + }, + { + "key": "pciBridge5.functions", + "value": "8" + }, + { + "key": "pciBridge6.present", + "value": "true" + }, + { + "key": "pciBridge6.virtualDev", + "value": "pcieRootPort" + }, + { + "key": "pciBridge6.functions", + "value": "8" + }, + { + "key": "pciBridge7.present", + "value": "true" + }, + { + "key": "pciBridge7.virtualDev", + "value": "pcieRootPort" + }, + { + "key": "pciBridge7.functions", + "value": "8" + }, + { + "key": "hpet0.present", + "value": "TRUE" + }, + { + "key": "nvram", + "value": "minecraft.nvram" + }, + { + "key": "virtualHW.productCompatibility", + "value": "hosted" + }, + { + "key": "scsi0.pciSlotNumber", + "value": "16" + }, + { + "key": "ethernet0.pciSlotNumber", + "value": "32" + }, + { + "key": "vmci0.pciSlotNumber", + "value": "33" + }, + { + "key": "snapshot.action", + "value": "keep" + }, + { + "key": "sched.cpu.latencySensitivity", + "value": "normal" + }, + { + "key": "replay.supported", + "value": "false" + }, + { + "key": "pciBridge0.pciSlotNumber", + "value": "17" + }, + { + "key": "pciBridge4.pciSlotNumber", + "value": "21" + }, + { + "key": "pciBridge5.pciSlotNumber", + "value": "22" + }, + { + "key": "pciBridge6.pciSlotNumber", + "value": "23" + }, + { + "key": "pciBridge7.pciSlotNumber", + "value": "24" + }, + { + "key": "tools.remindInstall", + "value": "FALSE" + }, + { + "key": "hostCPUID.0", + "value": "00000016756e65476c65746e49656e69" + }, + { + "key": "hostCPUID.1", + "value": "000906ea001008007ffafbffbfebfbff" + }, + { + "key": "hostCPUID.80000001", + "value": "0000000000000000000001212c100800" + }, + { + "key": "guestCPUID.0", + "value": "0000000d756e65476c65746e49656e69" + }, + { + "key": "guestCPUID.1", + "value": "000406f00001080096d832030f8bfbff" + }, + { + "key": "guestCPUID.80000001", + "value": "00000000000000000000010128100800" + }, + { + "key": "userCPUID.0", + "value": "0000000d756e65476c65746e49656e69" + }, + { + "key": "userCPUID.1", + "value": "000406f00001080096d832030f8bfbff" + }, + { + "key": "userCPUID.80000001", + "value": "00000000000000000000010128100800" + }, + { + "key": "evcCompatibilityMode", + "value": "TRUE" + }, + { + "key": "vmotion.checkpointFBSize", + "value": "4194304" + }, + { + "key": "softPowerOff", + "value": "TRUE" + }, + { + "key": "toolsInstallManager.updateCounter", + "value": "6" + }, + { + "key": "toolsInstallManager.lastInstallError", + "value": "0" + }, + { + "key": "numa.autosize.vcpu.maxPerVirtualNode", + "value": "1" + }, + { + "key": "numa.autosize.cookie", + "value": "10001" + }, + { + "key": "sched.swap.derivedName", + "value": "/vmfs/volumes/a79e4951-d31e6955/minecraft/minecraft-4bfd4f1d.vswp" + }, + { + "key": "scsi0:0.redo", + "value": "" + }, + { + "key": "monitor.phys_bits_used", + "value": "40" + }, + { + "key": "viv.moid", + "value": "91a88fc3-5936-4bfb-a6f8-018e073fcefb:vm-13671:XMmrS0IZV2SrrGL4GiADh//vraEEXaRMaC4vxsNBPOI=" + }, + { + "key": "vmxstats.filename", + "value": "minecraft.scoreboard" + }, + { + "key": "tools.capability.verifiedSamlToken", + "value": "TRUE" + }, + { + "key": "vmware.tools.internalversion", + "value": "10362" + }, + { + "key": "vmware.tools.requiredversion", + "value": "12389" + }, + { + "key": "migrate.hostLogState", + "value": "none" + }, + { + "key": "migrate.migrationId", + "value": "0" + }, + { + "key": "migrate.hostLog", + "value": "minecraft-662da845.hlog" + } + ], + "datastoreUrl": [ + { + "name": "freenas", + "url": "/vmfs/volumes/a79e4951-d31e6955" + } + ], + "swapPlacement": "inherit", + "bootOptions": { + "enterBIOSSetup": false, + "efiSecureBootEnabled": false, + "bootRetryEnabled": false, + "bootRetryDelay": 10000, + "networkBootProtocol": "ipv4" + }, + "changeTrackingEnabled": false, + "firmware": "bios", + "maxMksConnections": 40, + "guestAutoLockEnabled": false, + "memoryReservationLockedToMax": false, + "nestedHVEnabled": false, + "vPMCEnabled": false, + "scheduledHardwareUpgradeInfo": { + "upgradePolicy": "never", + "scheduledHardwareUpgradeStatus": "none" + }, + "messageBusTunnelEnabled": false, + "guestIntegrityInfo": { + "enabled": false + }, + "migrateEncryption": "opportunistic", + "sgxInfo": { + "epcSize": 0, + "flcMode": "unlocked", + "requireAttestation": false + }, + "ftEncryptionMode": "ftEncryptionOpportunistic", + "guestMonitoringModeInfo": {}, + "sevEnabled": false, + "numaInfo": { + "coresPerNumaNode": 0, + "autoCoresPerNumaNode": true + }, + "vmOpNotificationToAppEnabled": false, + "vmOpNotificationTimeout": -1, + "deviceGroups": {}, + "fixedPassthruHotPlugEnabled": false + }, + "layout": null, + "layoutEx": null, + "storage": null, + "environmentBrowser": { + "type": "", + "value": "" + }, + "resourcePool": null, + "parentVApp": null, + "resourceConfig": null, + "runtime": { + "connectionState": "", + "powerState": "", + "toolsInstallerMounted": false, + "numMksConnections": 0 + }, + "guest": null, + "summary": { + "runtime": { + "connectionState": "", + "powerState": "", + "toolsInstallerMounted": false, + "numMksConnections": 0 + }, + "config": { + "name": "", + "template": false, + "vmPathName": "" + }, + "quickStats": { + "guestHeartbeatStatus": "" + }, + "overallStatus": "" + }, + "datastore": null, + "network": null, + "snapshot": null, + "rootSnapshot": null, + "guestHeartbeatStatus": "" +} \ No newline at end of file