@@ -20,14 +20,18 @@ import (
2020 "context"
2121 "errors"
2222 "fmt"
23+ "io"
24+ "net/http"
2325 "net/url"
26+ "strings"
2427 "sync"
2528 "time"
2629
2730 "github.com/vmware/govmomi/vapi/rest"
2831 "github.com/vmware/govmomi/vapi/tags"
2932 "github.com/vmware/govmomi/vim25/mo"
3033 "github.com/vmware/govmomi/vim25/types"
34+ "github.com/vmware/govmomi/vim25/xml"
3135
3236 "github.com/google/uuid"
3337 "github.com/vmware/govmomi"
@@ -57,6 +61,88 @@ type Session struct {
5761 sessionKey string
5862}
5963
64+ // #### Start: This section was added by cursor
65+
66+ // SOAPResponse represents the structure of SOAP responses
67+ type SOAPResponse struct {
68+ XMLName xml.Name `xml:"Envelope"`
69+ Body struct {
70+ XMLName xml.Name `xml:"Body"`
71+ Fault * struct {
72+ XMLName xml.Name `xml:"Fault"`
73+ Code struct {
74+ XMLName xml.Name `xml:"faultcode"`
75+ Value string `xml:",chardata"`
76+ } `xml:"faultcode"`
77+ Reason struct {
78+ XMLName xml.Name `xml:"faultstring"`
79+ Value string `xml:",chardata"`
80+ } `xml:"faultstring"`
81+ Detail struct {
82+ XMLName xml.Name `xml:"detail"`
83+ Content string `xml:",chardata"`
84+ } `xml:"detail"`
85+ } `xml:"Fault,omitempty"`
86+ } `xml:"Body"`
87+ }
88+
89+ // CustomTransport wraps the default transport to intercept SOAP responses
90+ type CustomTransport struct {
91+ http.RoundTripper
92+ }
93+
94+ func (t * CustomTransport ) RoundTrip (req * http.Request ) (* http.Response , error ) {
95+ // Call the original transport
96+ resp , err := t .RoundTripper .RoundTrip (req )
97+ if err != nil {
98+ return resp , err
99+ }
100+
101+ // Read the response body
102+ body , err := io .ReadAll (resp .Body )
103+ if err != nil {
104+ return resp , err
105+ }
106+ resp .Body .Close ()
107+
108+ // Check if it's a SOAP response
109+ if strings .Contains (string (body ), "<?xml" ) && strings .Contains (string (body ), "Envelope" ) {
110+ // Parse SOAP response for privilege errors
111+ var soapResp SOAPResponse
112+ if err := xml .Unmarshal (body , & soapResp ); err == nil {
113+ if soapResp .Body .Fault != nil {
114+ klog .Error ("=== PRIVILEGE ERROR DETECTED ===" )
115+ klog .Errorf ("Fault Code: %s\n " , soapResp .Body .Fault .Code .Value )
116+ klog .Errorf ("Fault Reason: %s\n " , soapResp .Body .Fault .Reason .Value )
117+ klog .Errorf ("Fault Detail: %s\n " , soapResp .Body .Fault .Detail .Content )
118+ klog .Error ("================================\n " )
119+ }
120+ }
121+
122+ // Check for privilege-related error messages in the response
123+ bodyStr := string (body )
124+ privilegeKeywords := []string {
125+ "privilege" , "permission" , "access denied" , "unauthorized" , "forbidden" ,
126+ "NoPermission" , "InvalidLogin" , "InvalidPrivilege" ,
127+ }
128+ for _ , keyword := range privilegeKeywords {
129+ if strings .Contains (strings .ToLower (bodyStr ), strings .ToLower (keyword )) {
130+ klog .Errorf ("=== POTENTIAL PRIVILEGE ISSUE DETECTED (keyword: %s) ===\n " , keyword )
131+ klog .Error ("Response contains privilege-related content\n " )
132+ klog .Error ("==================================================" )
133+ break
134+ }
135+ }
136+ fmt .Println ("=== End SOAP Response ===\n " )
137+ }
138+
139+ // Create a new response with the body
140+ resp .Body = io .NopCloser (strings .NewReader (string (body )))
141+ return resp , nil
142+ }
143+
144+ // #### End: This section was added by cursor
145+
60146func newClientWithTimeout (ctx context.Context , u * url.URL , insecure bool , timeout time.Duration ) (* govmomi.Client , error ) {
61147 clientCreateCtx , clientCreateCtxCancel := context .WithTimeout (ctx , timeout )
62148 defer clientCreateCtxCancel ()
@@ -65,6 +151,14 @@ func newClientWithTimeout(ctx context.Context, u *url.URL, insecure bool, timeou
65151 if err != nil {
66152 return nil , err
67153 }
154+
155+ customTransport := & CustomTransport {
156+ RoundTripper : http .DefaultTransport ,
157+ }
158+
159+ // Create SOAP client with custom transport
160+ client .Transport = customTransport
161+
68162 client .Timeout = timeout
69163 return client , nil
70164}
0 commit comments