Beispiel #1
0
def test_get_new_events_with_fallback(realtime_instance):
    realtime_instance['use_collect_events_fallback'] = True

    with patch('datadog_checks.vsphere.api.connect'):
        config = VSphereConfig(realtime_instance, MagicMock())
        api = VSphereAPI(config, MagicMock())

        event1 = vim.event.Event(key=1)
        event3 = vim.event.Event(key=3)
        event_collector = MagicMock()
        api._conn.content.eventManager.QueryEvents.side_effect = [
            SoapAdapter.ParserError("some parse error"),
            [event1],
            SoapAdapter.ParserError("event parse error"),
            [event3],
        ]
        api._conn.content.eventManager.CreateCollectorForEvents.return_value = event_collector

        event_collector.ReadNextEvents.side_effect = [
            [event1],
            SoapAdapter.ParserError("event parse error"),
            [event3],
            [],
        ]

        events = api.get_new_events(start_time=dt.datetime.now())
        assert events == [event1, event3]
Beispiel #2
0
 def _copyHostProfile(self, hostProfile):
     """Helper function that makes a copy of the host profile document.
   """
     # TBD: Is there a better way than serializing/deserializing?
     serializedProf = SoapAdapter.Serialize(
         hostProfile, version=newestVersions.get('vim'))
     deserializedProf = SoapAdapter.Deserialize(serializedProf)
     return deserializedProf
Beispiel #3
0
 def test_serialize_unicode(self):
     self.assertEqual(
         SoapAdapter.SerializeToUnicode('Ḃ'),
         u'<object xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:vim25" xsi:type="xsd:string">\u1e02</object>'
     )
     self.assertEqual(
         SoapAdapter.SerializeToUnicode(u'Ḃ'),
         u'<object xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:vim25" xsi:type="xsd:string">\u1e02</object>'
     )
     self.assertEqual(
         SoapAdapter.SerializeToUnicode(u'\u1e02'),
         u'<object xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns="urn:vim25" xsi:type="xsd:string">\u1e02</object>'
     )
Beispiel #4
0
    def InvokeMethod(self, mo, info, args):
        req = self.SerializeRequest(mo, info, args)
        scgireq = ScgiRequest(
            {
                'REQUEST_METHOD': 'POST',
                'HTTP_SOAPACTION': self.versionId[1:-1]
            },
            message=req)
        scgireq.Write(self.p.stdin)
        self.p.stdin.flush()

        try:
            outText = ReadNetString(self.p.stdout)
        except Scgi_EOF:
            errText = "Unexpected EOF reading from process, maybe process died"
            raise self.systemError(msg=errText, reason=errText)
        except Exception as e:
            errText = "Error parsing output from SCGI process: %s" % (e)
            raise self.systemError(msg=errText, reason=errText)

        (responseHeaders,
         responseBody) = SoapAdapter.ParseHttpResponse(outText)

        # Parse status code from response headers [Status: 200 OK]
        error = False
        obj = None
        statusmatch = re.search(r'Status:\s+(\d+)\s+(.+)', responseHeaders)
        if not statusmatch:
            errText = "Could not find SOAP status in SOAP headers (%s)" % (
                responseHeaders)
            raise self.systemError(msg=errText, reason=errText)
        elif statusmatch.group(1) != '200':
            errText = statusmatch.group(2).rstrip()
            error = True

        # SoapResponseDeserializer can only handle XML
        if 'text/xml' in responseHeaders:
            try:
                obj = SoapAdapter.SoapResponseDeserializer(self).Deserialize(
                    responseBody, info.result)
            except:
                errText = "Failure parsing SOAP response (%s)" % (outText)
                raise self.systemError(msg=errText, reason=errText)

        if not error:
            return obj
        elif obj is None:
            raise self.systemError(msg=errText, reason=responseBody)
        else:
            raise obj
Beispiel #5
0
 def __init__(self, cmd, version='vim.version.version9'):
     SoapAdapter.SoapStubAdapterBase.__init__(self, version=version)
     self.cmd = cmd
     self.systemError = SoapAdapter.GetVmodlType('vmodl.fault.SystemError')
     argv = self.cmd.split()
     self.p = subprocess.Popen(argv,
                               stdin=subprocess.PIPE,
                               stdout=subprocess.PIPE)
Beispiel #6
0
def deserialize(clazz, data):
    if clazz is None:
        return SoapAdapter.Deserialize(data) if data else None
    elif clazz is list:
        return [deserialize(*elem) for elem in data]
    #elif issubclass(clazz, (VsphereObject, VsphereData, dict)):
    else:
        return clazz(**{k: deserialize(*v) for k, v in data.items()})
Beispiel #7
0
def test_get_new_events_failure_without_fallback(realtime_instance):
    with patch('datadog_checks.vsphere.api.connect'):
        config = VSphereConfig(realtime_instance, MagicMock())
        api = VSphereAPI(config, MagicMock())

        api._conn.content.eventManager.QueryEvents.side_effect = SoapAdapter.ParserError("some parse error")

        with pytest.raises(SoapAdapter.ParserError):
            api.get_new_events(start_time=dt.datetime.now())
Beispiel #8
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()
Beispiel #9
0
 def __init__(self,
              version=newestVersions.get('vim'),
              printRequest=False,
              printResponse=False):
     SoapAdapter.SoapStubAdapter.__init__(self, version=version)
     self.ns = VmomiSupport.GetVersionNamespace(version)
     self.soapHandler = SoapHandler.SoapHandler()
     self.soapDeserializer = SoapAdapter.SoapResponseDeserializer(self)
     self.printRequest = printRequest
     self.printResponse = printResponse
     ImportTypesAndManagedObjects()
Beispiel #10
0
 def WriteXml(self, obj, file=None):
     file = file or self.wfile
     self.send_header('Content-type', 'text/xml')
     self.end_headers()
     xmlStr = SoapAdapter.Serialize(obj)
     tag = "MobData"
     xmlDoc = '<?xml version="1.0" encoding="UTF-8"?>' \
         '<%s xmlns:xsd="http://www.w3.org/2001/XMLSchema" ' \
         'xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">' \
         '%s</%s>' % (tag, xmlStr, tag)
     file.write(xmlDoc)
Beispiel #11
0
def serialize(obj):
    obj_cls = obj.__class__
    if obj_cls is dict:
        res = {k: serialize(v) for k, v in obj.items()}
    elif obj_cls is list:
        res = [serialize(val) for val in obj]
    elif issubclass(obj_cls, (VsphereObject, VsphereData)):
        res = {
            k: serialize(v)
            for k, v in obj.__dict__.items() if not k.startswith('_')
        }
    else:
        try:
            res = SoapAdapter.Serialize(obj)
        except UnicodeEncodeError:
            print("WARNING: Failed to serialize %s data" % type(obj))
            return None, None
        obj_cls = None
    return obj_cls, res
Beispiel #12
0
 def test_serialize_float(self):
     pc = vim.host.VsanInternalSystem.PolicyCost()
     pc.diskSpaceToAddressSpaceRatio = 1.0
     SoapAdapter.Serialize(pc, version='vim.version.version10')
Beispiel #13
0
 def test_serialize_integer(self):
     lp = vim.LongPolicy()
     lp.inherited = False
     lp.value = 100
     SoapAdapter.Serialize(lp, version='vim.version.version10')
Beispiel #14
0
 def test_serialize_object(self):
     val = vim.vm.device.VirtualDeviceSpec.FileOperation()
     # This line should not raise an exception, especially on Python 3.
     SoapAdapter.Serialize(val)
Beispiel #15
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)