Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Connection to vCenter using HTTP forward proxy results in TypeErrors #1085

Open
adammillerio opened this issue Jul 22, 2024 · 1 comment
Open
Labels

Comments

@adammillerio
Copy link

Describe the bug

44d7b9f 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

  1. Connect to any vCenter with httpProxyHost and httpProxyPort 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.

@DanielDraganov
Copy link
Collaborator

Hello,
9a8956f adds support for pinned certificates and refactors the connection generation. The issue should be fixed now.
A maintenance patch can be published no sooner that two weeks from now.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants