diff --git a/pyVim/connect.py b/pyVim/connect.py index 9586992..926c3d2 100644 --- a/pyVim/connect.py +++ b/pyVim/connect.py @@ -238,18 +238,19 @@ def Connect(host='localhost', port=443, user='root', pwd='', assert(version is None) version = versionMap[namespace] elif not version: - version="vim.version.version6" + version = "vim.version.version6" si, stub = None, None if mechanism == 'userpass': - si, stub = __Login(host, port, user, pwd, service, adapter, version, path, - keyFile, certFile, thumbprint, sslContext) + si, stub = __Login(host, port, user, pwd, service, adapter, version, path, + keyFile, certFile, thumbprint, sslContext) elif mechanism == 'sspi': - si, stub = __LoginBySSPI(host, port, service, adapter, version, path, - keyFile, certFile, thumbprint, sslContext, b64token) + si, stub = __LoginBySSPI(host, port, service, adapter, version, path, + keyFile, certFile, thumbprint, sslContext, b64token) else: - raise Exception( 'The provided connection mechanism is not available, the supported mechanisms are userpass or sspi' ) - + raise Exception('''The provided connection mechanism is not available, the + supported mechanisms are userpass or sspi''') + SetSi(si) return si @@ -317,7 +318,7 @@ def __Login(host, port, user, pwd, service, adapter, version, path, """ content, si, stub = __RetrieveContent(host, port, adapter, version, path, - keyFile, certFile, thumbprint, sslContext) + keyFile, certFile, thumbprint, sslContext) # Get a ticket if we're connecting to localhost and password is not specified if host == 'localhost' and not pwd: @@ -336,11 +337,12 @@ def __Login(host, port, user, pwd, service, adapter, version, path, raise return si, stub -## Private method that performs the actual Connect and returns a +## Private method that performs LoginBySSPI and returns a ## connected service instance object. +## Copyright (c) 2015 Morgan Stanley. All rights reserved. def __LoginBySSPI(host, port, service, adapter, version, path, - keyFile, certFile, thumbprint, sslContext, b64token): + keyFile, certFile, thumbprint, sslContext, b64token): """ Private method that performs the actual Connect and returns a connected service instance object. @@ -360,7 +362,7 @@ def __LoginBySSPI(host, port, service, adapter, version, path, @param keyFile: ssl key file path @type keyFile: string @param certFile: ssl cert file path - @type certFile: string + @type certFile: string @param thumbprint: host cert thumbprint @type thumbprint: string @param sslContext: SSL Context describing the various SSL options. It is only @@ -371,10 +373,10 @@ def __LoginBySSPI(host, port, service, adapter, version, path, """ content, si, stub = __RetrieveContent(host, port, adapter, version, path, - keyFile, certFile, thumbprint, sslContext) + keyFile, certFile, thumbprint, sslContext) if b64token is None: - raise Exception( 'Token is not defined for sspi login' ) + raise Exception('Token is not defined for sspi login') # Login try: @@ -449,7 +451,7 @@ def __RetrieveContent(host, port, adapter, version, path, keyFile, certFile, reraise(vim.fault.HostConnectFault, fault, traceback) else: raise vim.fault.HostConnectFault(msg=str(e)) - + return content, si, stub @@ -798,6 +800,6 @@ def OpenPathWithStub(path, stub): url = '%s://%s%s' % (protocol, hostPort, path) headers = {} if stub.cookie: - headers["Cookie"] = stub.cookie + headers["Cookie"] = stub.cookie return requests.get(url, headers=headers, verify=False) diff --git a/tests/fixtures/sspi_connection.yaml b/tests/fixtures/sspi_connection.yaml new file mode 100644 index 0000000..ef268de --- /dev/null +++ b/tests/fixtures/sspi_connection.yaml @@ -0,0 +1,258 @@ +interactions: +- request: + body: ' + + + + <_this type="ServiceInstance">ServiceInstance + + ' + headers: + Accept-Encoding: ['gzip, deflate'] + Content-Type: [text/xml; charset=UTF-8] + Cookie: [''] + SOAPAction: ['"urn:vim25/4.1"'] + method: POST + uri: https://vcsa/sdk + response: + body: {string: !!python/unicode "\n\ + \n\ngroup-d1propertyCollectorViewManagerVMware\ + \ vCenter ServerVMware vCenter Server 6.0.0 build-3018523VMware,\ + \ Inc.6.0.03018523INTL000linux-x64vpxVirtualCenter6.06cbd40cc-1416-4b2d-ba7c-ae53a166d00aVMware\ + \ VirtualCenter Server6.0VpxSettingsUserDirectorySessionManagerAuthorizationManagerPerfMgrScheduledTaskManagerAlarmManagerEventManagerTaskManagerExtensionManagerCustomizationSpecManagerCustomFieldsManagerDiagMgrLicenseManagerSearchIndexFileManagervirtualDiskManagerSnmpSystemProvCheckerCompatCheckerOvfManagerIpPoolManagerDVSManagerHostProfileManagerClusterProfileManagerMoComplianceManagerLocalizationManagerStorageResourceManager\n\ + \n"} + headers: + cache-control: [no-cache] + connection: [Keep-Alive] + content-length: ['3320'] + content-type: [text/xml; charset=utf-8] + date: ['Mon, 12 Oct 2015 16:20:20 GMT'] + status: {code: 200, message: OK} +- request: + body: ' + + + + <_this type="SessionManager">SessionManagermy_base64token + + ' + headers: + Accept-Encoding: ['gzip, deflate'] + Content-Type: [text/xml; charset=UTF-8] + Cookie: [''] + SOAPAction: ['"urn:vim25/4.1"'] + method: POST + uri: https://vcsa/sdk + response: + body: {string: !!python/unicode "\n\ + \n\n52b5395a-85c2-9902-7835-13a9b77e1fecmy_usermy_user2015-10-12T16:20:20.388804Z2015-10-12T16:20:20.388804Zenen\n\ + \n"} + headers: + cache-control: [no-cache] + connection: [Keep-Alive] + content-length: ['704'] + content-type: [text/xml; charset=utf-8] + date: ['Mon, 12 Oct 2015 16:20:20 GMT'] + set-cookie: [vmware_soap_session="57e9ef0e1210352a3cf607db32a20792334f5b81"; + Path=/; HttpOnly; Secure;] + status: {code: 200, message: OK} +- request: + body: ' + + + + <_this type="ServiceInstance">ServiceInstance + + ' + headers: + Accept-Encoding: ['gzip, deflate'] + Content-Type: [text/xml; charset=UTF-8] + Cookie: [vmware_soap_session="57e9ef0e1210352a3cf607db32a20792334f5b81"; Path=/; + HttpOnly; Secure;] + SOAPAction: ['"urn:vim25/4.1"'] + method: POST + uri: https://vcsa/sdk + response: + body: {string: !!python/unicode "\n\ + \n\ngroup-d1propertyCollectorViewManagerVMware\ + \ vCenter ServerVMware vCenter Server 6.0.0 build-3018523VMware,\ + \ Inc.6.0.03018523INTL000linux-x64vpxVirtualCenter6.06cbd40cc-1416-4b2d-ba7c-ae53a166d00aVMware\ + \ VirtualCenter Server6.0VpxSettingsUserDirectorySessionManagerAuthorizationManagerPerfMgrScheduledTaskManagerAlarmManagerEventManagerTaskManagerExtensionManagerCustomizationSpecManagerCustomFieldsManagerDiagMgrLicenseManagerSearchIndexFileManagervirtualDiskManagerSnmpSystemProvCheckerCompatCheckerOvfManagerIpPoolManagerDVSManagerHostProfileManagerClusterProfileManagerMoComplianceManagerLocalizationManagerStorageResourceManager\n\ + \n"} + headers: + cache-control: [no-cache] + connection: [Keep-Alive] + content-length: ['3320'] + content-type: [text/xml; charset=utf-8] + date: ['Mon, 12 Oct 2015 16:20:20 GMT'] + status: {code: 200, message: OK} +- request: + body: ' + + + + <_this type="PropertyCollector">propertyCollectorServiceInstancefalsecontentServiceInstancefalse1 + + ' + headers: + Accept-Encoding: ['gzip, deflate'] + Content-Type: [text/xml; charset=UTF-8] + Cookie: [vmware_soap_session="57e9ef0e1210352a3cf607db32a20792334f5b81"; Path=/; + HttpOnly; Secure;] + SOAPAction: ['"urn:vim25/4.1"'] + method: POST + uri: https://vcsa/sdk + response: + body: {string: !!python/unicode "\n\ + \n\nServiceInstancecontentgroup-d1propertyCollectorViewManagerVMware vCenter\ + \ ServerVMware vCenter Server 6.0.0 build-3018523VMware,\ + \ Inc.6.0.03018523INTL000linux-x64vpxVirtualCenter6.06cbd40cc-1416-4b2d-ba7c-ae53a166d00aVMware\ + \ VirtualCenter Server6.0VpxSettingsUserDirectorySessionManagerAuthorizationManagerPerfMgrScheduledTaskManagerAlarmManagerEventManagerTaskManagerExtensionManagerCustomizationSpecManagerCustomFieldsManagerDiagMgrLicenseManagerSearchIndexFileManagervirtualDiskManagerSnmpSystemProvCheckerCompatCheckerOvfManagerIpPoolManagerDVSManagerHostProfileManagerClusterProfileManagerMoComplianceManagerLocalizationManagerStorageResourceManager\n\ + \n"} + headers: + cache-control: [no-cache] + connection: [Keep-Alive] + content-length: ['3460'] + content-type: [text/xml; charset=utf-8] + date: ['Mon, 12 Oct 2015 16:20:20 GMT'] + status: {code: 200, message: OK} +- request: + body: ' + + + + <_this type="PropertyCollector">propertyCollectorSessionManagerfalsecurrentSessionSessionManagerfalse1 + + ' + headers: + Accept-Encoding: ['gzip, deflate'] + Content-Type: [text/xml; charset=UTF-8] + Cookie: [vmware_soap_session="57e9ef0e1210352a3cf607db32a20792334f5b81"; Path=/; + HttpOnly; Secure;] + SOAPAction: ['"urn:vim25/4.1"'] + method: POST + uri: https://vcsa/sdk + response: + body: {string: !!python/unicode "\n\ + \n\nSessionManagercurrentSession52b5395a-85c2-9902-7835-13a9b77e1fecmy_usermy_user2015-10-12T16:20:20.388804Z2015-10-12T16:20:20.400795Zenen\n\ + \n"} + headers: + cache-control: [no-cache] + connection: [Keep-Alive] + content-length: ['880'] + content-type: [text/xml; charset=utf-8] + date: ['Mon, 12 Oct 2015 16:20:20 GMT'] + status: {code: 200, message: OK} +version: 1 diff --git a/tests/test_connect.py b/tests/test_connect.py index 308e831..c8c35c7 100644 --- a/tests/test_connect.py +++ b/tests/test_connect.py @@ -40,6 +40,23 @@ class ConnectionTests(tests.VCRTestBase): self.assertTrue(session_id is not None) self.assertEqual('52b5395a-85c2-9902-7835-13a9b77e1fec', session_id) + @vcr.use_cassette('sspi_connection.yaml', + cassette_library_dir=tests.fixtures_path, + record_mode='none') + def test_sspi_connection(self): + # see: http://python3porting.com/noconv.html + si = connect.Connect(host='vcsa', + mechanism='sspi', + b64token='my_base64token') + cookie = si._stub.cookie + session_id = si.content.sessionManager.currentSession.key + # NOTE (hartsock): The cookie value should never change during + # a connected session. That should be verifiable in these tests. + self.assertEqual(cookie, si._stub.cookie) + # NOTE (hartsock): assertIsNotNone does not work in Python 2.6 + self.assertTrue(session_id is not None) + self.assertEqual('52b5395a-85c2-9902-7835-13a9b77e1fec', session_id) + @vcr.use_cassette('basic_connection_bad_password.yaml', cassette_library_dir=tests.fixtures_path, record_mode='none')