Пример #1
0
 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()
Пример #2
0
   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)