pyvmomi
pyvmomi copied to clipboard
Connection to vCenter using HTTP forward proxy results in TypeErrors
Describe the bug
44d7b9f0c201a92018bac8324542c0adf96aa148 changed the underlying structure of proxy based Connections, which is resulting in a TypeError when any request is issued, such as the initial login request in SmartConnect:
---------------------------------------------------------------------------
TypeError Traceback (most recent call last)
File /pyVim/connect.py:493, in __Login(host, port, user, pwd, service, adapter, version, path, keyFile, certFile, httpProxyHost, httpProxyPort, thumbprint, sslContext, httpConnectionTimeout, connectionPoolTimeout, token, tokenType, customHeaders, sessionId)
492 try:
--> 493 content = si.RetrieveContent()
494 except vmodl.MethodFault:
File /pyVmomi/VmomiSupport.py:614, in Curry.__get__.<locals>.<lambda>(*args, **kwargs)
611 if obj:
612 # curried methods will receive 'self' *after* any fixed arguments
613 return lambda *args, **kwargs: \
--> 614 self.f(*(self.args + (obj,) + args), **kwargs)
615 return self
File /pyVmomi/VmomiSupport.py:387, in ManagedObject._InvokeMethod(info, self, *posargs, **kwargs)
386 list(map(CheckField, info.params, args))
--> 387 return self._stub.InvokeMethod(self, info, args)
File /pyVmomi/SoapAdapter.py:1420, in SoapStubAdapter.InvokeMethod(self, mo, info, args, outerStub)
1419 req = modifier(req)
-> 1420 conn = self.GetConnection()
1421 try:
File /pyVmomi/SoapAdapter.py:1506, in SoapStubAdapter.GetConnection(self)
1505 self.lock.release()
-> 1506 result = self.scheme(self.host, **self.schemeArgs)
1508 _VerifyThumbprint(self.thumbprint, result)
TypeError: HTTPProxyConnection.__call__() missing 2 required positional arguments: 'port' and 'timeout'
During handling of the above exception, another exception occurred:
vim.fault.HostConnectFault Traceback (most recent call last)
Cell In[3], line 1
----> 1 session = SmartConnect(
2 user=user,
3 pwd=pwd,
4 httpProxyHost=httpProxyHost,
5 httpProxyPort=httpProxyPort,
6 host=host,
7 port=port,
8 sslContext=ssl_context,
9 )
File /pyVim/connect.py:995, in SmartConnect(protocol, host, port, user, pwd, service, path, preferredApiVersions, keyFile, certFile, httpProxyHost, httpProxyPort, thumbprint, sslContext, httpConnectionTimeout, connectionPoolTimeout, token, tokenType, disableSslCertValidation, customHeaders, sessionId, b64token, mechanism)
990 raise Exception("{0}:{1} is down or is not a VIM server"
991 .format(host, port))
993 portNumber = protocol == "http" and -int(port) or int(port)
--> 995 return Connect(host=host,
996 port=portNumber,
997 user=user,
998 pwd=pwd,
999 service=service,
1000 adapter='SOAP',
1001 version=supportedVersion,
1002 path=path,
1003 keyFile=keyFile,
1004 certFile=certFile,
1005 httpProxyHost=httpProxyHost,
1006 httpProxyPort=httpProxyPort,
1007 thumbprint=thumbprint,
1008 sslContext=sslContext,
1009 httpConnectionTimeout=httpConnectionTimeout,
1010 connectionPoolTimeout=connectionPoolTimeout,
1011 token=token,
1012 tokenType=tokenType,
1013 disableSslCertValidation=disableSslCertValidation,
1014 customHeaders=customHeaders,
1015 sessionId=sessionId,
1016 b64token=b64token,
1017 mechanism=mechanism)
File /pyVim/connect.py:314, in Connect(host, port, user, pwd, service, adapter, namespace, path, version, keyFile, certFile, httpProxyHost, httpProxyPort, thumbprint, sslContext, httpConnectionTimeout, connectionPoolTimeout, token, tokenType, disableSslCertValidation, customHeaders, sessionId, b64token, mechanism)
311 elif mechanism != "userpass":
312 raise Exception("Not supported mechanism. " + msg)
--> 314 si, stub = __Login(host,
315 port,
316 user,
317 pwd,
318 service,
319 adapter,
320 version,
321 path,
322 keyFile,
323 certFile,
324 httpProxyHost,
325 httpProxyPort,
326 thumbprint,
327 sslContext,
328 httpConnectionTimeout,
329 connectionPoolTimeout,
330 token=token,
331 tokenType=tokenType,
332 customHeaders=customHeaders,
333 sessionId=sessionId)
334 SetSi(si)
336 return si
File /pyVim/connect.py:505, in __Login(host, port, user, pwd, service, adapter, version, path, keyFile, certFile, httpProxyHost, httpProxyPort, thumbprint, sslContext, httpConnectionTimeout, connectionPoolTimeout, token, tokenType, customHeaders, sessionId)
503 fault = vim.fault.HostConnectFault(msg=str(e))
504 if traceback:
--> 505 reraise(vim.fault.HostConnectFault, fault, traceback)
506 else:
507 raise fault
File /mnt/xarfuse/uid-212573/855c880f-seed-nspid4026531836_cgpid63561554-ns-4026531841/six.py:718, in reraise(tp, value, tb)
716 value = tp()
717 if value.__traceback__ is not tb:
--> 718 raise value.with_traceback(tb)
719 raise value
720 finally:
File /pyVim/connect.py:493, in __Login(host, port, user, pwd, service, adapter, version, path, keyFile, certFile, httpProxyHost, httpProxyPort, thumbprint, sslContext, httpConnectionTimeout, connectionPoolTimeout, token, tokenType, customHeaders, sessionId)
491 content = None
492 try:
--> 493 content = si.RetrieveContent()
494 except vmodl.MethodFault:
495 raise
File /pyVmomi/VmomiSupport.py:614, in Curry.__get__.<locals>.<lambda>(*args, **kwargs)
610 def __get__(self, obj, type):
611 if obj:
612 # curried methods will receive 'self' *after* any fixed arguments
613 return lambda *args, **kwargs: \
--> 614 self.f(*(self.args + (obj,) + args), **kwargs)
615 return self
File /pyVmomi/VmomiSupport.py:387, in ManagedObject._InvokeMethod(info, self, *posargs, **kwargs)
385 args[idx] = v
386 list(map(CheckField, info.params, args))
--> 387 return self._stub.InvokeMethod(self, info, args)
File /pyVmomi/SoapAdapter.py:1420, in SoapStubAdapter.InvokeMethod(self, mo, info, args, outerStub)
1418 for modifier in self.requestModifierList:
1419 req = modifier(req)
-> 1420 conn = self.GetConnection()
1421 try:
1422 conn.request('POST', self.path, req, headers)
File /pyVmomi/SoapAdapter.py:1506, in SoapStubAdapter.GetConnection(self)
1504 else:
1505 self.lock.release()
-> 1506 result = self.scheme(self.host, **self.schemeArgs)
1508 _VerifyThumbprint(self.thumbprint, result)
1510 return result
vim.fault.HostConnectFault: (vim.fault.HostConnectFault) {
dynamicType = <unset>,
dynamicProperty = (vmodl.DynamicProperty) [],
msg = "HTTPProxyConnection.__call__() missing 2 required positional arguments: 'port' and 'timeout'",
faultCause = <unset>,
faultMessage = (vmodl.LocalizableMessage) []
}
Reproduction steps
- Connect to any vCenter with
httpProxyHost
andhttpProxyPort
specified as a HTTP forward proxy:
#!/usr/bin/env python3
from ssl import SSLContext, PROTOCOL_TLS
from pyVim.connect import SmartConnect
session = SmartConnect(
user="[email protected]",
pwd="***",
httpProxyHost="127.0.0.1",
httpProxyPort=8080,
host="vcenter.example.site",
port=443,
sslContext=SSLContext(PROTOCOL_TLS),
)
Expected behavior
A connection is established and a ServiceInstance is returned using the provided HTTP forward proxy.
Additional context
This is likely caused by the timeout
key on schemeArgs
only being set when a httpProxyTimeout
is provided: https://github.com/vmware/pyvmomi/blob/master/pyVmomi/SoapAdapter.py#L1351
As well as not setting the port
key to the httpProxyPort
provided.