def setUp(self): self.version = newestVersions.get('vim') self.versionUri = VmomiSupport.GetVersionNamespace(self.version) self.futureVersionUri = "vim25/foo" self.badVersionUri = "notvim/foo" self.stub = SoapAdapter.SoapStubAdapter(version=self.version) self.deserializer = SoapAdapter.SoapResponseDeserializer(self.stub) self.soapHeaderBegin = \ """<?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>""" self.soapHeaderEnd = \ """</soapenv:Body> </soapenv:Envelope>""" ImportTypesAndManagedObjects()
def Login(self): """ Session login """ if self._stub: return host = self.options.server protocol = self.options.protocol try: port = int(self.options.portnumber) except ValueError: message = "Invalid port number %s" % self.options.portnumber raise SessionArgumentException(message) path = self.options.servicepath user = self.options.username password = self.options.password url = self.options.url sessionFile = self.options.sessionfile saveSessionFile = self.options.savesessionfile if self.options.encoding: encoding = self._VerifyEncoding(self.options.encoding) if encoding: self.options.encoding = encoding else: message = "Unknown encoding %s" % self.options.encoding raise SessionArgumentException(message) # Using version8 to connect since LoginByToken was introduced then version = 'vim.version.version9' passthroughAuth = self.options.passthroughauth passthroughAuthPackage = self.options.passthroughauthpackage credStorePath = self.options.credstore try: if credStorePath is None or len(credStorePath.strip()) == 0: # Will throw if HOME not set credStorePath = GetViSdkCredPlatformPath(sys.platform) except KeyError: pass credStore = self._GetCredstoreFromPath(credStorePath) # Url override if url: host, port, protocol, path = self._ParseURL(url=url) # Session file override cookie = None if sessionFile: host, cookie = self._GetCookieFromFile(host, sessionFile) # Lookup Service URL psc = self.options.psc lsUrl = None if psc: lsUrl = "https://" + psc + "/lookupservice/sdk" # If not in visor, then host should already be set or --psc specified. if not host and not lsUrl: if IsInVisor(): host = "localhost" else: message = "Must specify a server name" raise SessionArgumentException(message) # Local host useLocalLogin = False if IsInVisor() and host in ("localhost", "127.0.0.1", "::1") and \ password is None: # Use local login for VMkernel useLocalLogin = True # Do not use SSL protocol = "http" port = 80 cacertsFile = self.options.cacertsfile thumbprint = None if not useLocalLogin and not cacertsFile: # We need a thumbprint. thumbprint = self.options.thumbprint if not thumbprint and credStore: thumbprint = credStore.GetThumbprint(host) if not thumbprint: # Not found on command line or credstore. # Make up one, so that the check fails. Collision is impossible due to # the symbol K, which will never appear in a server thumbprint. thumbprint = "FA:KE:FA:KE:FA:KE:FA:KE:FA:KE:FA:KE:FA:KE:FA:KE:FA:KE:FA:KE" stsUrl = None stsThumbprint = None vcThumbprint = None # Check protocol # Negative port indicate http if protocol == "http": if port > 0: port = -port elif protocol == "https": if port < 0: port = -port else: message = "Unsupported protocol %s" % protocol raise SessionArgumentException(message) MAX_RETRY_SECONDS = 100 connectStartTime = time.time() connected = False while not connected: localTicket = None try: # Look up VC URL only if none of --server and --url options are set. if not stsUrl and lsUrl and not host and not url: # TODO: In the future we may prompt the user to make a choice # if more than one VCs are registered with Lookup Service. # Until then we use the first VC URL that we find. url, vcThumbprint = self._GetVcUrlFromLookupService( lsUrl, cacertsFile=cacertsFile, thumbprint=thumbprint) logging.info("Got VC URL from PSC: " + url) host, port, protocol, path = self._ParseURL(url=url) # TODO: In the future we may prompt the user to make a choice if # more than one SSO servers are registered with Lookup Service. # Until then we use the first STS URL that we find. stsUrl, stsThumbprint = self._GetStsUrlFromLookupService( lsUrl, cacertsFile=cacertsFile, thumbprint=thumbprint) logging.info("Got STS URL from PSC: " + stsUrl) # We'll verify vCenter Server certificate by vcThumbprint # and SSO server certificate by stsThumbprint, so we don't need # cacertsFile any more. thumbprint = vcThumbprint cacertsFile = None # Create Soap stub reqLogin = True context = CreateSslContext(cacertsFile, thumbprint) stub = SoapAdapter.SoapStubAdapter(host=host, port=port, version=version, path=path, thumbprint=thumbprint, sslContext=context) if sessionFile: # Use session file if cookie: stub.cookie = cookie.name + "=" + cookie.value + ";" + \ " Path=" + cookie.path + ";" reqLogin = False elif passthroughAuth: # Do authentication below pass elif useLocalLogin: if not user: user = GetSessionUserName() elif password is None and credStore: # Try to use credential store if no password is given. # If user is not specified and there is only 1 user in cred store, # then take the user and password from credstore if not user: try: users = credStore.GetUserNames(host) except Exception as err: errMsg = "Credential store file %s is corrupted" % credStorePath logging.error(errMsg) error = err raise IOError(errMsg) if len(users) == 1: logging.info("Using user: %s" % users[0]) user = users[0] if not user: user = userInput("Enter username: "******"Credential store file %s is corrupted" % credStorePath logging.error(errMsg) error = err raise IOError(errMsg) logging.info("Connecting to " + host + "@" + str(port)) content = self._GetServiceContent(stub) sessionMgr = content.sessionManager if reqLogin: # Ask for user / password if not given if not passthroughAuth: if not user: user = userInput("Enter username: "******"Enter password: "******"" try: localTicketPasswd = open(localTicket.passwordFilePath).read() except IOError as err: LogException(err) logging.error("Failed to read local ticket") error = err userSession = sessionMgr.Login(localTicket.userName, localTicketPasswd) else: userSession = sessionMgr.Login(user, password, None) if not userSession: raise SessionException("Invalid login") # Do we need to logout? reqLogout = reqLogin if saveSessionFile: reqLogout = False logging.info("Connected") connected = True self._host = host self._stub = stub self._content = content self._sessionMgr = sessionMgr self._reqLogout = reqLogout except vim.fault.InvalidLogin as err: exitMessage = "Invalid login: {0}".format(err.msg) timeDelta = time.time() - connectStartTime if localTicket is not None and timeDelta < MAX_RETRY_SECONDS: # The local ticket may have expired due to its short life time # of 10 seconds. Try again. # SessionManager.login() API has a dealy of ~4 sec. logging.error(exitMessage) logging.error("Will retry login in 1 second") error = None continue LogException(err) raise SessionLoginException(err, message=exitMessage) except vmodl.MethodFault as err: exitMessage = "Error: {0}.".format(err.msg) LogException(err) raise SessionLoginException(err, message=exitMessage) except ssl.CertificateError as err: exitMessage = "Certificate error: {0}".format(err) LogException(err) raise SessionLoginException(err, message=exitMessage) except ssl.SSLError as err: # Special handling for SSL error. Need to put before IOError, as # ssl.SSLError subclass IOError exitMessage = "SSL error 0x{0:x}".format(err.errno) LogException(err) raise SessionLoginException(err, message=exitMessage) except IOError as err: exitMessage = "IO error: {0}".format(str(err)) LogException(err) raise SessionLoginException(err, message=exitMessage) except ThumbprintMismatchException as err: expected = ':'.join(re.findall(r'(..)', err.expected.upper())) actual = ':'.join(re.findall(r'(..)', err.actual.upper())) exitMessage = "Certificate error. Server SHA-1 thumbprint: {0}".format( actual) if expected.find('FA:KE') == -1: exitMessage = "{0} (expected: {1})".format(exitMessage, expected) else: exitMessage = "{0} (not trusted)".format(exitMessage) # Don't log the fake thumbprint. exitMessage is fine. LogException(err) raise SessionLoginException(err, message=exitMessage) except SessionException as err: LogException(err) raise except Exception as err: exitMessage = "Connection failed" LogException(err) raise SessionLoginException(err, message=exitMessage)