docs: def get_service_instance(host, username=None, password=None, protocol=None,
                           port=None, mechanism='userpass', principal=None,
                           domain=None):
      '''
      Authenticate with a vCenter server or ESX/ESXi host and return the service instance object.
  
      host
          The location of the vCenter server or ESX/ESXi host.
  
      username
          The username used to login to the vCenter server or ESX/ESXi host.
          Required if mechanism is ``userpass``
  
      password
          The password used to login to the vCenter server or ESX/ESXi host.
          Required if mechanism is ``userpass``
  
      protocol
          Optionally set to alternate protocol if the vCenter server or ESX/ESXi host is not
          using the default protocol. Default protocol is ``https``.
  
      port
          Optionally set to alternate port if the vCenter server or ESX/ESXi host is not
          using the default port. Default port is ``443``.
  
      mechanism
          pyVmomi connection mechanism. Can either be ``userpass`` or ``sspi``.
          Default mechanism is ``userpass``.
  
      principal
          Kerberos service principal. Required if mechanism is ``sspi``
  
      domain
          Kerberos user domain. Required if mechanism is ``sspi``
      '''
  
      if protocol is None:
          protocol = 'https'
      if port is None:
          port = 443
  
      service_instance = GetSi()
      if service_instance:
          stub = GetStub()
          if (salt.utils.platform.is_proxy() or
              (hasattr(stub, 'host') and
               stub.host != ':'.join([host, six.text_type(port)]))):
              # Proxies will fork and mess up the cached service instance.
              # If this is a proxy or we are connecting to a different host
              # invalidate the service instance to avoid a potential memory leak
              # and reconnect
              Disconnect(service_instance)
              service_instance = None
          else:
              return service_instance
  
      if not service_instance:
          service_instance = _get_service_instance(host,
                                                   username,
                                                   password,
                                                   protocol,
                                                   port,
                                                   mechanism,
                                                   principal,
                                                   domain)
  
      # Test if data can actually be retrieved or connection has gone stale
      log.trace('Checking connection is still authenticated')
      try:
          service_instance.CurrentTime()
      except vim.fault.NotAuthenticated:
          log.trace('Session no longer authenticating. Reconnecting')
          Disconnect(service_instance)
          service_instance = _get_service_instance(host,
                                                   username,
                                                   password,
                                                   protocol,
                                                   port,
                                                   mechanism,
                                                   principal,
                                                   domain)
      except vim.fault.NoPermission as exc:
          log.exception(exc)
          raise salt.exceptions.VMwareApiError(
              'Not enough permissions. Required privilege: '
              '{}'.format(exc.privilegeId))
      except vim.fault.VimFault as exc:
          log.exception(exc)
          raise salt.exceptions.VMwareApiError(exc.msg)
      except vmodl.RuntimeFault as exc:
          log.exception(exc)
          raise salt.exceptions.VMwareRuntimeError(exc.msg)
  
      return service_instance