code: func BuildWithConfig(source string, p ClientGenerator, cfg *Config) (Source, error) {
  	switch source {
  	case "service":
  		client, err := p.KubeClient()
  		if err != nil {
  			return nil, err
  		}
  		return NewServiceSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.Compatibility, cfg.PublishInternal, cfg.PublishHostIP, cfg.ServiceTypeFilter, cfg.IgnoreHostnameAnnotation)
  	case "ingress":
  		client, err := p.KubeClient()
  		if err != nil {
  			return nil, err
  		}
  		return NewIngressSource(client, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
  	case "istio-gateway":
  		kubernetesClient, err := p.KubeClient()
  		if err != nil {
  			return nil, err
  		}
  		istioClient, err := p.IstioClient()
  		if err != nil {
  			return nil, err
  		}
  		return NewIstioGatewaySource(kubernetesClient, istioClient, cfg.IstioIngressGatewayServices, cfg.Namespace, cfg.AnnotationFilter, cfg.FQDNTemplate, cfg.CombineFQDNAndAnnotation, cfg.IgnoreHostnameAnnotation)
  	case "fake":
  		return NewFakeSource(cfg.FQDNTemplate)
  	case "connector":
  		return NewConnectorSource(cfg.ConnectorServer)
  	case "crd":
  		client, err := p.KubeClient()
  		if err != nil {
  			return nil, err
  		}
  		crdClient, scheme, err := NewCRDClientForAPIVersionKind(client, cfg.KubeConfig, cfg.KubeMaster, cfg.CRDSourceAPIVersion, cfg.CRDSourceKind)
  		if err != nil {
  			return nil, err
  		}
  		return NewCRDSource(crdClient, cfg.Namespace, cfg.CRDSourceKind, scheme)
  	}
  	return nil, ErrSourceNotFound
  }
docs: // BuildWithConfig allows to generate a Source implementation from the shared config