vmware / govmomi

Go library for the VMware vSphere API
Apache License 2.0
2.29k stars 907 forks source link

Can't set ftcpt.ftEncryptionMode or migrate.encryptionMode in extra config #3493

Open jhg03a opened 2 months ago

jhg03a commented 2 months ago

Describe the bug When attempting to set ftcpt.ftEncryptionMode or migrate.encryptionMode in VM extra config on vSphere 8.0U3, the modify task says it completed successfully, but those properties are missing if you query the extra config immediately afterwards. Other made up properties can be set fine.

To Reproduce Steps to reproduce the behavior:

  1. govc vm.change -vm=/'DC West'/vm/vm.test.net -e ftcpt.ftEncryptionMode="ftEncryptionRequired" -e migrate.encryptionMode="required" -e foo="bar"
  2. govc vm.info -e /'DC West'/vm/vm.test.net

Expected behavior I expect to either have those configs set ideally or an error thrown if it's not possible to set them

Affected version govc installed via brew on osx at latest available (0.38.0)

Screenshots/Debug Output

| => govc vm.change -debug=true -trace=true -verbose=true -dump=true -json=true -vm=/'DC West'/vm/vm.test.net -e ftcpt.ftEncryptionMode="ftEncryptionRequired" -e migrate.encryptionMode="required" -e foo="bar"
<snipped>
types.ReconfigVM_Task{
    This: types.ManagedObjectReference{Type:"VirtualMachine", Value:"vm-9039", ServerGUID:""},
    Spec: types.VirtualMachineConfigSpec{
        ChangeVersion:         "",
        Name:                  "",
        Version:               "",
        CreateDate:            (*time.Time)(nil),
        Uuid:                  "",
        InstanceUuid:          "",
        NpivNodeWorldWideName: nil,
        NpivPortWorldWideName: nil,
        NpivWorldWideNameType: "",
        NpivDesiredNodeWwns:   0,
        NpivDesiredPortWwns:   0,
        NpivTemporaryDisabled: (*bool)(nil),
        NpivOnNonRdmDisks:     (*bool)(nil),
        NpivWorldWideNameOp:   "",
        LocationId:            "",
        GuestId:               "",
        AlternateGuestName:    "",
        Annotation:            "",
        Files:                 (*types.VirtualMachineFileInfo)(nil),
        Tools:                 (*types.ToolsConfigInfo)(nil),
        Flags:                 (*types.VirtualMachineFlagInfo)(nil),
        ConsolePreferences:    (*types.VirtualMachineConsolePreferences)(nil),
        PowerOpInfo:           (*types.VirtualMachineDefaultPowerOpInfo)(nil),
        RebootPowerOff:        (*bool)(nil),
        NumCPUs:               0,
        VcpuConfig:            nil,
        NumCoresPerSocket:     0,
        MemoryMB:              0,
        MemoryHotAddEnabled:   (*bool)(nil),
        CpuHotAddEnabled:      (*bool)(nil),
        CpuHotRemoveEnabled:   (*bool)(nil),
        VirtualICH7MPresent:   (*bool)(nil),
        VirtualSMCPresent:     (*bool)(nil),
        DeviceChange:          nil,
        CpuAllocation:         (*types.ResourceAllocationInfo)(nil),
        MemoryAllocation:      (*types.ResourceAllocationInfo)(nil),
        LatencySensitivity:    (*types.LatencySensitivity)(nil),
        CpuAffinity:           (*types.VirtualMachineAffinityInfo)(nil),
        MemoryAffinity:        (*types.VirtualMachineAffinityInfo)(nil),
        NetworkShaper:         (*types.VirtualMachineNetworkShaperInfo)(nil),
        CpuFeatureMask:        nil,
        ExtraConfig:           []types.BaseOptionValue{
            &types.OptionValue{
                Key:   "ftcpt.ftEncryptionMode",
                Value: "ftEncryptionRequired",
            },
            &types.OptionValue{
                Key:   "migrate.encryptionMode",
                Value: "required",
            },
            &types.OptionValue{
                Key:   "foo",
                Value: "bar",
            },
        },
        SwapPlacement:                "",
        BootOptions:                  (*types.VirtualMachineBootOptions)(nil),
        VAppConfig:                   nil,
        FtInfo:                       nil,
        RepConfig:                    (*types.ReplicationConfigSpec)(nil),
        VAppConfigRemoved:            (*bool)(nil),
        VAssertsEnabled:              (*bool)(nil),
        ChangeTrackingEnabled:        (*bool)(nil),
        Firmware:                     "",
        MaxMksConnections:            0,
        GuestAutoLockEnabled:         (*bool)(nil),
        ManagedBy:                    (*types.ManagedByInfo)(nil),
        MemoryReservationLockedToMax: (*bool)(nil),
        NestedHVEnabled:              (*bool)(nil),
        VPMCEnabled:                  (*bool)(nil),
        ScheduledHardwareUpgradeInfo: (*types.ScheduledHardwareUpgradeInfo)(nil),
        VmProfile:                    nil,
        MessageBusTunnelEnabled:      (*bool)(nil),
        Crypto:                       nil,
        MigrateEncryption:            "",
        SgxInfo:                      (*types.VirtualMachineSgxInfo)(nil),
        FtEncryptionMode:             "",
        GuestMonitoringModeInfo:      (*types.VirtualMachineGuestMonitoringModeInfo)(nil),
        SevEnabled:                   (*bool)(nil),
        VirtualNuma:                  (*types.VirtualMachineVirtualNuma)(nil),
        MotherboardLayout:            "",
        PmemFailoverEnabled:          (*bool)(nil),
        VmxStatsCollectionEnabled:    (*bool)(nil),
        VmOpNotificationToAppEnabled: (*bool)(nil),
        VmOpNotificationTimeout:      0,
        DeviceSwap:                   (*types.VirtualMachineVirtualDeviceSwap)(nil),
        SimultaneousThreads:          0,
        Pmem:                         (*types.VirtualMachineVirtualPMem)(nil),
        DeviceGroups:                 (*types.VirtualMachineVirtualDeviceGroups)(nil),
        FixedPassthruHotPlugEnabled:  (*bool)(nil),
    },
}
types.ReconfigVM_TaskResponse{
    Returnval: types.ManagedObjectReference{Type:"Task", Value:"task-19320", ServerGUID:""},
}
types.CreatePropertyCollector{
    This: types.ManagedObjectReference{Type:"PropertyCollector", Value:"propertyCollector", ServerGUID:""},
}
types.CreatePropertyCollectorResponse{
    Returnval: types.ManagedObjectReference{Type:"PropertyCollector", Value:"session[<session_guid>]52cc6f78-add9-3432-e23f-f828e84ecab0", ServerGUID:""},
}
types.CreateFilter{
    This: types.ManagedObjectReference{Type:"PropertyCollector", Value:"session[<session_guid>]52cc6f78-add9-3432-e23f-f828e84ecab0", ServerGUID:""},
    Spec: types.PropertyFilterSpec{
        PropSet: []types.PropertySpec{
            {
                Type:    "Task",
                All:     (*bool)(nil),
                PathSet: []string{"info"},
            },
        },
        ObjectSet: []types.ObjectSpec{
            {
                Obj:       types.ManagedObjectReference{Type:"Task", Value:"task-19320", ServerGUID:""},
                Skip:      (*bool)(nil),
                SelectSet: nil,
            },
        },
        ReportMissingObjectsInResults: (*bool)(nil),
    },
    PartialUpdates: false,
}
types.CreateFilterResponse{
    Returnval: types.ManagedObjectReference{Type:"PropertyFilter", Value:"session[<session_guid>]5209d3b6-68cd-103c-b743-9382dd57d25a", ServerGUID:""},
}
types.WaitForUpdatesEx{
    This:    types.ManagedObjectReference{Type:"PropertyCollector", Value:"session[<session_guid>]52cc6f78-add9-3432-e23f-f828e84ecab0", ServerGUID:""},
    Version: "",
    Options: (*types.WaitOptions)(nil),
}
types.WaitForUpdatesExResponse{
    Returnval: &types.UpdateSet{
        Version:   "1",
        FilterSet: []types.PropertyFilterUpdate{
            {
                Filter:    types.ManagedObjectReference{Type:"PropertyFilter", Value:"session[<session_guid>]5209d3b6-68cd-103c-b743-9382dd57d25a", ServerGUID:""},
                ObjectSet: []types.ObjectUpdate{
                    {
                        Kind:      "enter",
                        Obj:       types.ManagedObjectReference{Type:"Task", Value:"task-19320", ServerGUID:""},
                        ChangeSet: []types.PropertyChange{
                            {
                                Name: "info",
                                Op:   "assign",
                                Val:  types.TaskInfo{
                                    Key:             "task-19320",
                                    Task:            types.ManagedObjectReference{Type:"Task", Value:"task-19320", ServerGUID:""},
                                    Description:     (*types.LocalizableMessage)(nil),
                                    Name:            "ReconfigVM_Task",
                                    DescriptionId:   "VirtualMachine.reconfigure",
                                    Entity:          &types.ManagedObjectReference{Type:"VirtualMachine", Value:"vm-9039", ServerGUID:""},
                                    EntityName:      "vm.test.net",
                                    Locked:          nil,
                                    State:           "success",
                                    Cancelled:       false,
                                    Cancelable:      false,
                                    Error:           (*types.LocalizedMethodFault)(nil),
                                    Result:          nil,
                                    Progress:        0,
                                    ProgressDetails: nil,
                                    Reason:          &types.TaskReasonUser{
                                        TaskReason: types.TaskReason{},
                                        UserName:   "VSPHERE.LOCAL\\Administrator",
                                    },
                                    QueueTime:     time.Now(),
                                    StartTime:     types.NewTime(time.Now()),
                                    CompleteTime:  types.NewTime(time.Now()),
                                    EventChainId:  1157403,
                                    ChangeTag:     "",
                                    ParentTaskKey: "",
                                    RootTaskKey:   "",
                                    ActivationId:  "",
                                },
                            },
                        },
                        MissingSet: nil,
                    },
                },
                MissingSet: nil,
            },
        },
        Truncated: (*bool)(nil),
    },
}
types.DestroyPropertyFilter{
    This: types.ManagedObjectReference{Type:"PropertyFilter", Value:"session[<session_guid>]5209d3b6-68cd-103c-b743-9382dd57d25a", ServerGUID:""},
}
types.DestroyPropertyFilterResponse{}
types.DestroyPropertyCollector{
    This: types.ManagedObjectReference{Type:"PropertyCollector", Value:"session[<session_guid>]52cc6f78-add9-3432-e23f-f828e84ecab0", ServerGUID:""},
}
types.DestroyPropertyCollectorResponse{}

| => govc vm.info -e /'DC West'/vm/vm.test.net
Name:           vm.test.net
  Path:         /DC West/vm/vm.test.net
  UUID:         4205fb31-48e8-190a-dc2a-52ffb4428b68
  Guest name:   Rocky Linux (64-bit)
  Memory:       8092MB
  CPU:          4 vCPU(s)
  Power state:  poweredOff
  Boot time:    <nil>
  IP address:
  Host:         vmhost.test.net
  ExtraConfig:
    nvram:                                     vm.test.net.nvram
    svga.present:                              TRUE
    pciBridge0.present:                        TRUE
    pciBridge4.present:                        TRUE
    pciBridge4.virtualDev:                     pcieRootPort
    pciBridge4.functions:                      8
    pciBridge5.present:                        TRUE
    pciBridge5.virtualDev:                     pcieRootPort
    pciBridge5.functions:                      8
    pciBridge6.present:                        TRUE
    pciBridge6.virtualDev:                     pcieRootPort
    pciBridge6.functions:                      8
    pciBridge7.present:                        TRUE
    pciBridge7.virtualDev:                     pcieRootPort
    pciBridge7.functions:                      8
    hpet0.present:                             TRUE
    isolation.tools.vmxDnDVersionGet.disable:  TRUE
    RemoteDisplay.maxConnections:              1
    log.rotateSize:                            2048000
    mks.enable3d:                              FALSE
    isolation.tools.copy.disable:              TRUE
    isolation.tools.setGUIOptions.enable:      FALSE
    isolation.device.connectable.disable:      TRUE
    isolation.tools.paste.disable:             TRUE
    isolation.tools.dnd.disable:               TRUE
    viv.moid:                                  <redacted>
    vmware.tools.internalversion:              2147483647
    vmware.tools.requiredversion:              12448
    migrate.hostLogState:                      none
    migrate.migrationId:                       0
    migrate.hostLog:                           vm.test.net-544fa868.hlog
    guestinfo.metadata:                        <redacted>
    guestinfo.metadata.encoding:               gzip+base64
    guestinfo.userdata:                        <redacted>
    guestinfo.userdata.encoding:               gzip+base64
    guestinfo.vendordata:                      <redacted>
    guestinfo.vendordata.encoding:             gzip+base64
    foo:                                       bar

Additional context These properties are settable via PowerCLI as follows:

$VMview = $TargetVM | Get-View 
$ConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
$ConfigSpec.FtEncryptionMode = New-object VMware.Vim.VirtualMachineConfigSpecEncryptedFtModes
$ConfigSpec.FtEncryptionMode = "ftEncryptionRequired"
$ConfigSpec.MigrateEncryption = New-Object VMware.Vim.VirtualMachineConfigSpecEncryptedVMotionModes
$ConfigSpec.MigrateEncryption = "required"
$VMview.ReconfigVM_Task($ConfigSpec)

Separately I also noticed that it seems govc cannot deploy and OVF with these properties set as well which would have been ideal.

github-actions[bot] commented 2 months ago

Howdy 🖐   jhg03a ! Thank you for your interest in this project. We value your feedback and will respond soon.

If you want to contribute to this project, please make yourself familiar with the CONTRIBUTION guidelines.

dougm commented 1 month ago

Hmm, is there a doc that says you can use extraConfig to set these? I think we need to flags to set in the spec like so:

govc vm.change -vm $vm -ft-encryption-mode ftEncryptionRequired -migrate-encryption required

Can open a PR later, but patch below if you want to try it out.

diff --git a/govc/vm/change.go b/govc/vm/change.go
index a5a73b53..9bccb3fc 100644
--- a/govc/vm/change.go
+++ b/govc/vm/change.go
@@ -174,6 +174,9 @@ func (cmd *change) Register(ctx context.Context, f *flag.FlagSet) {
        f.Var(flags.NewOptionalBool(&cmd.Flags.VvtdEnabled), "iommu-enabled", "Enable IOMMU")

        f.StringVar(&cmd.hwUpgradePolicy, "scheduled-hw-upgrade-policy", "", fmt.Sprintf("Schedule hardware upgrade policy (%s)", strings.Join(hwUpgradePolicies, "|")))
+
+       f.StringVar(&cmd.FtEncryptionMode, "ft-encryption-mode", "", "Encrypted fault tolerance mode")
+       f.StringVar(&cmd.MigrateEncryption, "migrate-encryption", "", "Encrypted vMotion mode")
 }

 func (cmd *change) Description() string {
jhg03a commented 1 month ago

It's when you set them via extraconfig as you should be able to do, that there's no change but also a success message. You can see in the example above I also set a Foo key in the same transaction and it's fine.

prziborowski commented 2 weeks ago

I'm new to the govmomi project, but unless the go bindings are trying to go way beyond what the normal vSphere SOAP bindings do, "extraConfig" isn't where you set anything that has formal properties.

The documentation states: "Configuration keys that would conflict with parameters that are explicitly configurable through other fields in the ConfigSpec object are silently ignored."