vmware / govmomi

Go library for the VMware vSphere API
Apache License 2.0
2.27k stars 897 forks source link

api: move vim25.Client.UseServiceVersion to soap.Client #3406

Closed dougm closed 2 months ago

dougm commented 2 months ago

This method only changes fields in soap.Client Moving it allows UseServiceVersion to be called after NewServiceVersion.

divyenpatel commented 2 months ago

@dougm

CNS is creating task object using vim25 client, and we have only set service version for CNSClient's soap client, we are able to invoke a task to CNS API, task is created successfully, but we can not obtain a result.

divyenp@divyenp0LVDQ cns % go test -v
=== RUN   TestClient
    client_test.go:158: Creating volume using the spec: types.CnsVolumeCreateSpec{
            Name:       "pvc-901e87eb-c2bd-11e9-806f-005056a0c9a0",
            VolumeType: "BLOCK",
            Datastores: []types.ManagedObjectReference{
                {Type:"Datastore", Value:"datastore-48", ServerGUID:""},
            },
            Metadata: types.CnsVolumeMetadata{
                ContainerCluster: types.CnsContainerCluster{
                    ClusterType:         "KUBERNETES",
                    ClusterId:           "demo-cluster-id",
                    VSphereUser:         "Administrator@vsphere.local",
                    ClusterFlavor:       "VANILLA",
                    ClusterDistribution: "OpenShift",
                },
                EntityMetadata:        nil,
                ContainerClusterArray: nil,
            },
            BackingObjectDetails: &types.CnsBlockBackingDetails{
                CnsBackingObjectDetails: types.CnsBackingObjectDetails{
                    CapacityInMb: 5120,
                },
                BackingDiskId:                  "",
                BackingDiskUrlPath:             "",
                BackingDiskObjectId:            "",
                AggregatedSnapshotCapacityInMb: 0,
            },
            Profile:      nil,
            CreateSpec:   nil,
            VolumeSource: nil,
        }
--- FAIL: TestClient (1.93s)
panic: interface conversion: types.AnyType is types.DynamicData, not types.CnsVolumeOperationBatchResult [recovered]
        panic: interface conversion: types.AnyType is types.DynamicData, not types.CnsVolumeOperationBatchResult

goroutine 19 [running]:
testing.tRunner.func1.2({0x16160c0, 0xc00038b8c0})
        /usr/local/go/src/testing/testing.go:1545 +0x238
testing.tRunner.func1()
        /usr/local/go/src/testing/testing.go:1548 +0x397
panic({0x16160c0?, 0xc00038b8c0?})
        /usr/local/go/src/runtime/panic.go:914 +0x21f
github.com/vmware/govmomi/cns.GetTaskResult({0x18f50a8?, 0x1ccf600?}, 0x1ccf600?)
        /Users/divyenp/go/src/github.com/dougm/govmomi/cns/cns_util.go:66 +0x105
github.com/vmware/govmomi/cns.TestClient(0xc000103040)
        /Users/divyenp/go/src/github.com/dougm/govmomi/cns/client_test.go:169 +0xd45
testing.tRunner(0xc000103040, 0x184f308)
        /usr/local/go/src/testing/testing.go:1595 +0xff
created by testing.(*T).Run in goroutine 1
        /usr/local/go/src/testing/testing.go:1648 +0x3ad
exit status 2
FAIL    github.com/vmware/govmomi/cns   2.220s
<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope
    xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
    xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/"
    xmlns:xsd="http://www.w3.org/2001/XMLSchema"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <soapenv:Body>
        <WaitForUpdatesExResponse
            xmlns="urn:vim25">
            <returnval>
                <version>3</version>
                <filterSet>
                    <filter type="PropertyFilter">session[52affb41-050e-3129-bb6f-7572e9617abc]524787ee-140a-07be-a11e-0aefe1b1a45a</filter>
                    <objectSet>
                        <kind>modify</kind>
                        <obj type="Task">task-35111</obj>
                        <changeSet>
                            <name>info</name>
                            <op>assign</op>
                            <val xsi:type="TaskInfo">
                                <key>task-35111</key>
                                <task type="Task">task-35111</task>
                                <descriptionId>com.vmware.cns.tasks.createvolume</descriptionId>
                                <entity type="Folder">group-d1</entity>
                                <entityName>Datacenters</entityName>
                                <state>success</state>
                                <cancelled>false</cancelled>
                                <cancelable>false</cancelable>
                                <result xsi:type="DynamicData"></result>
                                <reason xsi:type="TaskReasonUser">
                                    <userName>com.vmware.cns</userName>
                                </reason>
                                <queueTime>2024-04-10T18:25:04.928345Z</queueTime>
                                <startTime>2024-04-10T18:25:04.937814Z</startTime>
                                <completeTime>2024-04-10T18:25:06.628613Z</completeTime>
                                <eventChainId>179991</eventChainId>
                                <activationId>a5f9915f</activationId>
                            </val>
                        </changeSet>
                    </objectSet>
                </filterSet>
            </returnval>
        </WaitForUpdatesExResponse>
    </soapenv:Body>
</soapenv:Envelope>

After we set service version for vim25 client using which task object is created then issue is getting resolved.

<?xml version="1.0" encoding="UTF-8"?>
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
   <soapenv:Body>
      <WaitForUpdatesExResponse xmlns="urn:vsan">
         <returnval xmlns:vim25="urn:vim25">
            <vim25:version>3</vim25:version>
            <vim25:filterSet>
               <vim25:filter type="PropertyFilter">session[52e74dc2-c44e-740d-305e-cd36a59a3ba8]52cac0c4-bb0d-04ca-6a27-2478936bd86a</vim25:filter>
               <vim25:objectSet>
                  <vim25:kind>modify</vim25:kind>
                  <vim25:obj type="Task">task-35206</vim25:obj>
                  <vim25:changeSet>
                     <vim25:name>info</vim25:name>
                     <vim25:op>assign</vim25:op>
                     <vim25:val xsi:type="vim25:TaskInfo">
                        <vim25:key>task-35206</vim25:key>
                        <vim25:task type="Task">task-35206</vim25:task>
                        <vim25:descriptionId>com.vmware.cns.tasks.createvolume</vim25:descriptionId>
                        <vim25:entity type="Folder">group-d1</vim25:entity>
                        <vim25:entityName>Datacenters</vim25:entityName>
                        <vim25:state>success</vim25:state>
                        <vim25:cancelled>false</vim25:cancelled>
                        <vim25:cancelable>false</vim25:cancelable>
                        <vim25:result xsi:type="CnsVolumeOperationBatchResult">
                           <volumeResults xsi:type="CnsVolumeCreateResult">
                              <volumeId>
                                 <id>0dce2e38-440b-4fc7-b49e-7c2b10805984</id>
                              </volumeId>
                              <name>pvc-901e87eb-c2bd-11e9-806f-005056a0c9a0</name>
                              <placementResults>
                                 <datastore type="Datastore">datastore-48</datastore>
                              </placementResults>
                           </volumeResults>
                        </vim25:result>
                        <vim25:reason xsi:type="vim25:TaskReasonUser">
                           <vim25:userName>com.vmware.cns</vim25:userName>
                        </vim25:reason>
                        <vim25:queueTime>2024-04-10T18:50:53.778796Z</vim25:queueTime>
                        <vim25:startTime>2024-04-10T18:50:53.787083Z</vim25:startTime>
                        <vim25:completeTime>2024-04-10T18:50:55.374962Z</vim25:completeTime>
                        <vim25:eventChainId>180196</vim25:eventChainId>
                        <vim25:activationId>a5f99649</vim25:activationId>
                     </vim25:val>
                  </vim25:changeSet>
               </vim25:objectSet>
            </vim25:filterSet>
         </returnval>
      </WaitForUpdatesExResponse>
   </soapenv:Body>
</soapenv:Envelope>

so this still requires creating new vim25 client for obtaining task result.

dougm commented 2 months ago

The Client's Namespace + Version are used to compose the SOAPAction http header here: https://github.com/vmware/govmomi/blob/367c55fe2058e9b456d9bb530a10e5481f862267/vim25/soap/client.go#L735-L739

It is possible to override the value of SOAPAction using the following, with whatever "$namespace/$version" you need:

    action := soap.Header{Action: "vim25/8.0.2"}
    err = task.Wait(c.WithHeader(ctx, action))

Would that work for you?

divyenpatel commented 2 months ago

Yes it worked.

// GetTaskInfo gets the task info given a task
func GetTaskInfo(ctx context.Context, task *object.Task) (*vim25types.TaskInfo, error) {
    action := soap.Header{Action: "vsan/8.0.3"}
    task.Wait(task.Client().WithHeader(ctx, action))
    taskInfo, err := task.WaitForResult(ctx, nil)
    if err != nil {
        return nil, err
    }
    return taskInfo, nil
}
divyenpatel commented 2 months ago

I just noticed I did have c.vim25Client.UseServiceVersion("vsan") in the code while i was testing changes with changing soap header.

task.WaitForResult(task.Client().WithHeader(ctx, action), nil) is not helping.

sorry for confusion.

Is there a way to create new task object with this soap header while we are creating task using object.NewTask(c.vim25Client, res.Returnval)

if we do so then i guess issue will get resolved for us.