add ability to store/create encrypted vcenter password
This commit is contained in:
80
internal/secrets/secrets.go
Normal file
80
internal/secrets/secrets.go
Normal file
@@ -0,0 +1,80 @@
|
||||
package secrets
|
||||
|
||||
import (
|
||||
"crypto/aes"
|
||||
"crypto/cipher"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"io"
|
||||
"log/slog"
|
||||
)
|
||||
|
||||
type Secrets struct {
|
||||
Logger *slog.Logger
|
||||
EncryptionKey []byte
|
||||
}
|
||||
|
||||
func New(logger *slog.Logger, key []byte) *Secrets {
|
||||
return &Secrets{
|
||||
Logger: logger,
|
||||
EncryptionKey: key,
|
||||
}
|
||||
}
|
||||
|
||||
// Encrypt function that encrypts data using AES256-GCM and returns base64 encoded ciphertext
|
||||
func (s *Secrets) Encrypt(plainText []byte) (string, error) {
|
||||
block, err := aes.NewCipher(s.EncryptionKey)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a new GCM cipher
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Create a nonce
|
||||
nonce := make([]byte, gcm.NonceSize())
|
||||
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
// Encrypt the plaintext using AES256-GCM
|
||||
cipherText := gcm.Seal(nonce, nonce, plainText, nil)
|
||||
|
||||
// Return the base64 encoded ciphertext
|
||||
return base64.StdEncoding.EncodeToString(cipherText), nil
|
||||
}
|
||||
|
||||
// Decrypt function that decrypts base64 encoded AES256-GCM ciphertext
|
||||
func (s *Secrets) Decrypt(base64CipherText string) ([]byte, error) {
|
||||
// Decode the base64 ciphertext
|
||||
cipherText, err := base64.StdEncoding.DecodeString(base64CipherText)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
block, err := aes.NewCipher(s.EncryptionKey)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Create a new GCM cipher
|
||||
gcm, err := cipher.NewGCM(block)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Extract the nonce from the ciphertext
|
||||
nonceSize := gcm.NonceSize()
|
||||
nonce, cipherText := cipherText[:nonceSize], cipherText[nonceSize:]
|
||||
|
||||
// Decrypt the ciphertext
|
||||
plainText, err := gcm.Open(nil, nonce, cipherText, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return plainText, nil
|
||||
}
|
@@ -11,17 +11,6 @@ import (
|
||||
// SettingsYML struct holds various runtime data that is too cumbersome to specify via command line, eg replacement properties
|
||||
type SettingsYML struct {
|
||||
Settings struct {
|
||||
/*
|
||||
Replacements []struct {
|
||||
Key string `yaml:"Key"`
|
||||
Value string `yaml:"Value"`
|
||||
} `yaml:"replacements"`
|
||||
|
||||
Omapi struct {
|
||||
KeyName string `yaml:"key_name"`
|
||||
KeySecret string `yaml:"key_secret"`
|
||||
} `yaml:"omapi"`
|
||||
*/
|
||||
TenantsToFilter []string `yaml:"tenants_to_filter"`
|
||||
NodeChargeClusters []string `yaml:"node_charge_clusters"`
|
||||
SrmActiveActiveVms []string `yaml:"srm_activeactive_vms"`
|
||||
|
@@ -5,21 +5,12 @@ import (
|
||||
"database/sql"
|
||||
"log/slog"
|
||||
"time"
|
||||
"vctp/db"
|
||||
"vctp/db/queries"
|
||||
"vctp/internal/settings"
|
||||
"vctp/internal/vcenter"
|
||||
|
||||
"github.com/vmware/govmomi/vim25/types"
|
||||
)
|
||||
|
||||
// Handler handles requests.
|
||||
type CronTask struct {
|
||||
Logger *slog.Logger
|
||||
Database db.Database
|
||||
Settings settings.SettingsYML
|
||||
}
|
||||
|
||||
// use gocron to check events in the Events table
|
||||
func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
|
||||
var (
|
||||
@@ -42,6 +33,8 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
|
||||
if err != nil {
|
||||
logger.Error("Unable to query for unprocessed events", "error", err)
|
||||
return nil // TODO - what to do with this error?
|
||||
} else {
|
||||
logger.Debug("Successfully queried for unprocessed events", "count", len(events))
|
||||
}
|
||||
|
||||
for _, evt := range events {
|
||||
@@ -51,7 +44,7 @@ func (c *CronTask) RunVmCheck(ctx context.Context, logger *slog.Logger) error {
|
||||
// to avoid doing unnecessary login/logout of vcenter
|
||||
|
||||
c.Logger.Debug("connecting to vcenter")
|
||||
vc := vcenter.New(c.Logger)
|
||||
vc := vcenter.New(c.Logger, c.VcCreds)
|
||||
vc.Login(evt.Source)
|
||||
|
||||
//datacenter = evt.DatacenterName.String
|
||||
|
16
internal/tasks/tasks.go
Normal file
16
internal/tasks/tasks.go
Normal file
@@ -0,0 +1,16 @@
|
||||
package tasks
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"vctp/db"
|
||||
"vctp/internal/settings"
|
||||
"vctp/internal/vcenter"
|
||||
)
|
||||
|
||||
// CronTask stores runtime information to be used by tasks
|
||||
type CronTask struct {
|
||||
Logger *slog.Logger
|
||||
Database db.Database
|
||||
Settings settings.SettingsYML
|
||||
VcCreds *vcenter.VcenterLogin
|
||||
}
|
@@ -19,9 +19,15 @@ import (
|
||||
)
|
||||
|
||||
type Vcenter struct {
|
||||
Logger *slog.Logger
|
||||
ctx context.Context
|
||||
client *govmomi.Client
|
||||
Logger *slog.Logger
|
||||
ctx context.Context
|
||||
client *govmomi.Client
|
||||
credentials *VcenterLogin
|
||||
}
|
||||
|
||||
type VcenterLogin struct {
|
||||
Username string
|
||||
Password string
|
||||
}
|
||||
|
||||
type VmProperties struct {
|
||||
@@ -30,23 +36,25 @@ type VmProperties struct {
|
||||
}
|
||||
|
||||
// New creates a new Vcenter with the given logger
|
||||
func New(logger *slog.Logger) *Vcenter {
|
||||
func New(logger *slog.Logger, creds *VcenterLogin) *Vcenter {
|
||||
|
||||
//ctx, cancel := context.WithCancel(context.Background())
|
||||
//defer cancel()
|
||||
|
||||
return &Vcenter{
|
||||
Logger: logger,
|
||||
ctx: context.Background(),
|
||||
Logger: logger,
|
||||
ctx: context.Background(),
|
||||
credentials: creds,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Vcenter) Login(vUrl string) error {
|
||||
var insecure bool
|
||||
|
||||
// TODO - fix this
|
||||
insecureString := os.Getenv("VCENTER_INSECURE")
|
||||
username := os.Getenv("VCENTER_USERNAME")
|
||||
password := os.Getenv("VCENTER_PASSWORD")
|
||||
//username := os.Getenv("VCENTER_USERNAME")
|
||||
//password := os.Getenv("VCENTER_PASSWORD")
|
||||
|
||||
// Connect to vCenter
|
||||
u, err := soap.ParseURL(vUrl)
|
||||
@@ -54,7 +62,7 @@ func (v *Vcenter) Login(vUrl string) error {
|
||||
log.Fatalf("Error parsing vCenter URL: %s", err)
|
||||
}
|
||||
|
||||
u.User = url.UserPassword(username, password)
|
||||
u.User = url.UserPassword(v.credentials.Username, v.credentials.Password)
|
||||
|
||||
/*
|
||||
c, err := govmomi.NewClient(ctx, u, insecure)
|
||||
@@ -77,7 +85,7 @@ func (v *Vcenter) Login(vUrl string) error {
|
||||
|
||||
v.client = c
|
||||
|
||||
v.Logger.Debug("successfully connected to vCenter", "url", vUrl, "username", username)
|
||||
v.Logger.Debug("successfully connected to vCenter", "url", vUrl, "username", v.credentials.Username)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
26
main.go
26
main.go
@@ -9,9 +9,11 @@ import (
|
||||
"runtime"
|
||||
"time"
|
||||
"vctp/db"
|
||||
"vctp/internal/secrets"
|
||||
"vctp/internal/settings"
|
||||
"vctp/internal/tasks"
|
||||
utils "vctp/internal/utils"
|
||||
"vctp/internal/vcenter"
|
||||
"vctp/log"
|
||||
"vctp/server"
|
||||
"vctp/server/router"
|
||||
@@ -26,6 +28,7 @@ var (
|
||||
buildTime string // when the executable was built
|
||||
cronFrequency time.Duration
|
||||
cronInvFrequency time.Duration
|
||||
encryptionKey = []byte("5L1l3B5KvwOCzUHMAlCgsgUTRAYMfSpa")
|
||||
)
|
||||
|
||||
func main() {
|
||||
@@ -112,6 +115,25 @@ func main() {
|
||||
utils.GenerateCerts(tlsCertFilename, tlsKeyFilename)
|
||||
}
|
||||
|
||||
// Load vcenter credentials from .env
|
||||
a := secrets.New(logger, encryptionKey)
|
||||
vcEp := os.Getenv("VCENTER_PASSWORD")
|
||||
if len(vcEp) == 0 {
|
||||
logger.Error("No vcenter password configured")
|
||||
os.Exit(1)
|
||||
}
|
||||
vcPass, err := a.Decrypt(vcEp)
|
||||
if err != nil {
|
||||
logger.Error("failed to decrypt vcenter credentials", "error", err)
|
||||
//os.Exit(1)
|
||||
}
|
||||
|
||||
creds := vcenter.VcenterLogin{
|
||||
//insecureString := os.Getenv("VCENTER_INSECURE")
|
||||
Username: os.Getenv("VCENTER_USERNAME"),
|
||||
Password: string(vcPass),
|
||||
}
|
||||
|
||||
// Prepare the task scheduler
|
||||
c, err := gocron.NewScheduler()
|
||||
if err != nil {
|
||||
@@ -124,6 +146,7 @@ func main() {
|
||||
Logger: logger,
|
||||
Database: database,
|
||||
Settings: s,
|
||||
VcCreds: &creds,
|
||||
}
|
||||
|
||||
cronFrequencyString := os.Getenv("VCENTER_EVENT_POLLING_SECONDS")
|
||||
@@ -184,12 +207,13 @@ func main() {
|
||||
c.Start()
|
||||
|
||||
// Start server
|
||||
r := router.New(logger, database, buildTime, sha1ver, runtime.Version(), &creds, a)
|
||||
svr := server.New(
|
||||
logger,
|
||||
c,
|
||||
cancel,
|
||||
bindAddress,
|
||||
server.WithRouter(router.New(logger, database, buildTime, sha1ver, runtime.Version())),
|
||||
server.WithRouter(r),
|
||||
server.SetTls(bindDisableTls),
|
||||
server.SetCertificate(tlsCertFilename),
|
||||
server.SetPrivateKey(tlsKeyFilename),
|
||||
|
61
server/handler/encryptData.go
Normal file
61
server/handler/encryptData.go
Normal file
@@ -0,0 +1,61 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func (h *Handler) EncryptData(w http.ResponseWriter, r *http.Request) {
|
||||
//ctx := context.Background()
|
||||
var cipherText string
|
||||
|
||||
reqBody, err := io.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
h.Logger.Error("Invalid data received", "error", err)
|
||||
fmt.Fprintf(w, "Invalid data received")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
} else {
|
||||
h.Logger.Debug("received input data", "length", len(reqBody))
|
||||
}
|
||||
|
||||
// get the json input
|
||||
var input map[string]string
|
||||
if err := json.Unmarshal(reqBody, &input); err != nil {
|
||||
h.Logger.Error("unable to unmarshal json", "error", err)
|
||||
prettyPrint(reqBody)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"status": "ERROR",
|
||||
"message": fmt.Sprintf("Unable to unmarshal JSON in request body: '%s'", err),
|
||||
})
|
||||
return
|
||||
} else {
|
||||
h.Logger.Debug("successfully decoded JSON")
|
||||
prettyPrint(input)
|
||||
}
|
||||
|
||||
//cipher, err := h.Secret.Encrypt()
|
||||
for k := range input {
|
||||
//h.Logger.Debug("foo", "key", k, "value", input[k])
|
||||
cipherText, err = h.Secret.Encrypt([]byte(input[k]))
|
||||
if err != nil {
|
||||
h.Logger.Error("Unable to encrypt", "error", err)
|
||||
} else {
|
||||
h.Logger.Debug("Encrypted plaintext", "length", len(input[k]), "ciphertext", cipherText)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"status": "OK",
|
||||
"message": cipherText,
|
||||
})
|
||||
return
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// return the result
|
||||
|
||||
}
|
@@ -5,6 +5,8 @@ import (
|
||||
"log/slog"
|
||||
"net/http"
|
||||
"vctp/db"
|
||||
"vctp/internal/secrets"
|
||||
"vctp/internal/vcenter"
|
||||
|
||||
"github.com/a-h/templ"
|
||||
)
|
||||
@@ -16,6 +18,8 @@ type Handler struct {
|
||||
BuildTime string
|
||||
SHA1Ver string
|
||||
GoVersion string
|
||||
VcCreds *vcenter.VcenterLogin
|
||||
Secret *secrets.Secrets
|
||||
}
|
||||
|
||||
func (h *Handler) html(ctx context.Context, w http.ResponseWriter, status int, t templ.Component) {
|
||||
|
@@ -244,7 +244,7 @@ func (h *Handler) calculateNewDiskSize(event models.CloudEventReceived) float64
|
||||
var diskSize float64
|
||||
var totalDiskBytes int64
|
||||
h.Logger.Debug("connecting to vcenter")
|
||||
vc := vcenter.New(h.Logger)
|
||||
vc := vcenter.New(h.Logger, h.VcCreds)
|
||||
vc.Login(event.CloudEvent.Source)
|
||||
|
||||
vmObject, err := vc.FindVMByIDWithDatacenter(event.CloudEvent.Data.VM.VM.Value, event.CloudEvent.Data.Datacenter.Datacenter.Value)
|
||||
|
@@ -94,13 +94,22 @@ func (h *Handler) VmMoveEvent(w http.ResponseWriter, r *http.Request) {
|
||||
result, err := h.Database.Queries().CreateUpdate(ctx, params)
|
||||
if err != nil {
|
||||
h.Logger.Error("unable to perform database insert", "error", err)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
fmt.Fprintf(w, "Error : %v\n", err)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"status": "ERROR",
|
||||
"message": fmt.Sprintf("Unable to insert move event into database: '%s'", err),
|
||||
})
|
||||
return
|
||||
|
||||
} else {
|
||||
h.Logger.Debug("created database record", "insert_result", result)
|
||||
w.WriteHeader(http.StatusOK)
|
||||
fmt.Fprintf(w, "Processed update event: %v\n", result)
|
||||
//fmt.Fprintf(w, "Processed update event: %v\n", result)
|
||||
json.NewEncoder(w).Encode(map[string]string{
|
||||
"status": "OK",
|
||||
"message": fmt.Sprintf("Successfully processed move event"),
|
||||
})
|
||||
return
|
||||
}
|
||||
}
|
||||
|
@@ -5,17 +5,21 @@ import (
|
||||
"net/http"
|
||||
"vctp/db"
|
||||
"vctp/dist"
|
||||
"vctp/internal/secrets"
|
||||
"vctp/internal/vcenter"
|
||||
"vctp/server/handler"
|
||||
"vctp/server/middleware"
|
||||
)
|
||||
|
||||
func New(logger *slog.Logger, database db.Database, buildTime string, sha1ver string, goVersion string) http.Handler {
|
||||
func New(logger *slog.Logger, database db.Database, buildTime string, sha1ver string, goVersion string, creds *vcenter.VcenterLogin, secret *secrets.Secrets) http.Handler {
|
||||
h := &handler.Handler{
|
||||
Logger: logger,
|
||||
Database: database,
|
||||
BuildTime: buildTime,
|
||||
SHA1Ver: sha1ver,
|
||||
GoVersion: goVersion,
|
||||
VcCreds: creds,
|
||||
Secret: secret,
|
||||
}
|
||||
|
||||
mux := http.NewServeMux()
|
||||
@@ -35,5 +39,8 @@ func New(logger *slog.Logger, database db.Database, buildTime string, sha1ver st
|
||||
mux.HandleFunc("/api/report/inventory", h.InventoryReportDownload)
|
||||
mux.HandleFunc("/api/report/updates", h.UpdateReportDownload)
|
||||
|
||||
// endpoint for encrypting vcenter credential
|
||||
mux.HandleFunc("/api/encrypt", h.EncryptData)
|
||||
|
||||
return middleware.NewLoggingMiddleware(logger, mux)
|
||||
}
|
||||
|
@@ -21,6 +21,7 @@ type Server struct {
|
||||
disableTls bool
|
||||
tlsCertFilename string
|
||||
tlsKeyFilename string
|
||||
encryptionKey string
|
||||
}
|
||||
|
||||
// New creates a new server with the given logger, address and options.
|
||||
@@ -88,6 +89,13 @@ func WithRouter(handler http.Handler) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// SetKey sets the encryption key we use when generating secrets
|
||||
func SetKey(key string) Option {
|
||||
return func(s *Server) {
|
||||
s.encryptionKey = key
|
||||
}
|
||||
}
|
||||
|
||||
// SetTls sets the disable tls value
|
||||
func SetTls(disableTls bool) Option {
|
||||
return func(s *Server) {
|
||||
|
736
vm.json
736
vm.json
@@ -1,736 +0,0 @@
|
||||
{
|
||||
"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": ""
|
||||
}
|
Reference in New Issue
Block a user