github.com/jenkins-x/jx/v2@v2.1.155/pkg/cmd/clients/fake/fake_factory.go (about)

     1  package fake
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  
     7  	"github.com/jenkins-x/jx/v2/pkg/kustomize"
     8  	"k8s.io/client-go/dynamic"
     9  
    10  	"github.com/jenkins-x/jx/v2/pkg/cmd/clients"
    11  	"github.com/jenkins-x/jx/v2/pkg/util"
    12  
    13  	v1fake "github.com/jenkins-x/jx-api/pkg/client/clientset/versioned/fake"
    14  	"github.com/jenkins-x/jx/v2/pkg/builds"
    15  	apifake "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset/fake"
    16  	"k8s.io/client-go/kubernetes/fake"
    17  	kservefake "knative.dev/serving/pkg/client/clientset/versioned/fake"
    18  
    19  	gojenkins "github.com/jenkins-x/golang-jenkins"
    20  	"github.com/jenkins-x/jx/v2/pkg/io/secrets"
    21  	"github.com/jenkins-x/jx/v2/pkg/vault"
    22  	certmngclient "github.com/jetstack/cert-manager/pkg/client/clientset/versioned"
    23  	fake_certmngclient "github.com/jetstack/cert-manager/pkg/client/clientset/versioned/fake"
    24  
    25  	vaultoperatorclient "github.com/banzaicloud/bank-vaults/operator/pkg/client/clientset/versioned"
    26  	fake_vaultoperatorclient "github.com/banzaicloud/bank-vaults/operator/pkg/client/clientset/versioned/fake"
    27  	"github.com/heptio/sonobuoy/pkg/client"
    28  	sonoboy_dynamic "github.com/heptio/sonobuoy/pkg/dynamic"
    29  	"github.com/jenkins-x/jx-api/pkg/client/clientset/versioned"
    30  	"github.com/jenkins-x/jx/v2/pkg/auth"
    31  	"github.com/jenkins-x/jx/v2/pkg/gits"
    32  	"github.com/jenkins-x/jx/v2/pkg/helm"
    33  	"github.com/jenkins-x/jx/v2/pkg/kube"
    34  	"github.com/jenkins-x/jx/v2/pkg/table"
    35  	fake_vault "github.com/jenkins-x/jx/v2/pkg/vault/fake"
    36  	"github.com/pkg/errors"
    37  	tektonclient "github.com/tektoncd/pipeline/pkg/client/clientset/versioned"
    38  	tektonfake "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/fake"
    39  	resourceclient "github.com/tektoncd/pipeline/pkg/client/resource/clientset/versioned"
    40  	resourcefake "github.com/tektoncd/pipeline/pkg/client/resource/clientset/versioned/fake"
    41  	apiextensionsclientset "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset"
    42  	"k8s.io/client-go/kubernetes"
    43  	"k8s.io/client-go/rest"
    44  	metricsclient "k8s.io/metrics/pkg/client/clientset/versioned"
    45  	fake_metricsclient "k8s.io/metrics/pkg/client/clientset/versioned/fake"
    46  	prowjobclient "k8s.io/test-infra/prow/client/clientset/versioned"
    47  	fake_prowjobclient "k8s.io/test-infra/prow/client/clientset/versioned/fake"
    48  	kserve "knative.dev/serving/pkg/client/clientset/versioned"
    49  )
    50  
    51  // FakeFactory points to a fake factory implementation
    52  type FakeFactory struct {
    53  	Batch bool
    54  
    55  	delegate        clients.Factory
    56  	namespace       string
    57  	kubeConfig      kube.Kuber
    58  	impersonateUser string
    59  	bearerToken     string
    60  	secretLocation  secrets.SecretLocation
    61  	offline         bool
    62  
    63  	// cached fake clients
    64  	apiClient      apiextensionsclientset.Interface
    65  	jxClient       versioned.Interface
    66  	kubeClient     kubernetes.Interface
    67  	kserveClient   kserve.Interface
    68  	tektonClient   tektonclient.Interface
    69  	resourceClient resourceclient.Interface
    70  	prowJobClient  prowjobclient.Interface
    71  	dyncClient     dynamic.Interface
    72  }
    73  
    74  var _ clients.Factory = (*FakeFactory)(nil)
    75  
    76  // NewFakeFactory creates a fake factory which uses fake k8s clients for testing
    77  func NewFakeFactory() clients.Factory {
    78  	f := &FakeFactory{
    79  		namespace: "jx",
    80  	}
    81  	f.kubeConfig = kube.NewKubeConfig()
    82  	return f
    83  }
    84  
    85  // NewFakeFactoryFromClients creates a fake factory which uses fake k8s clients for testing
    86  func NewFakeFactoryFromClients(apiClient apiextensionsclientset.Interface,
    87  	jxClient versioned.Interface,
    88  	kubeClient kubernetes.Interface,
    89  	tektonClient tektonclient.Interface,
    90  	dyncClient dynamic.Interface) *FakeFactory {
    91  	f := &FakeFactory{
    92  		namespace:    "jx",
    93  		apiClient:    apiClient,
    94  		jxClient:     jxClient,
    95  		kubeClient:   kubeClient,
    96  		tektonClient: tektonClient,
    97  		dyncClient:   dyncClient,
    98  	}
    99  	f.kubeConfig = kube.NewKubeConfig()
   100  	return f
   101  }
   102  
   103  // SetDelegateFactory sets the delegate factory
   104  func (f *FakeFactory) SetDelegateFactory(factory clients.Factory) {
   105  	f.delegate = factory
   106  }
   107  
   108  // GetDelegateFactory returns the delegate factory
   109  func (f *FakeFactory) GetDelegateFactory() clients.Factory {
   110  	if f.delegate == nil {
   111  		f.delegate = clients.NewFactory()
   112  	}
   113  	return f.delegate
   114  }
   115  
   116  // SetNamespace sets the default namespace
   117  func (f *FakeFactory) SetNamespace(ns string) {
   118  	f.namespace = ns
   119  }
   120  
   121  // SetBatch sets batch
   122  func (f *FakeFactory) SetBatch(batch bool) {
   123  	f.Batch = batch
   124  }
   125  
   126  // SetOffline sets offline
   127  func (f *FakeFactory) SetOffline(offline bool) {
   128  	f.offline = offline
   129  }
   130  
   131  // ImpersonateUser returns a new factory impersonating the given user
   132  func (f *FakeFactory) ImpersonateUser(user string) clients.Factory {
   133  	copy := *f
   134  	copy.impersonateUser = user
   135  	return &copy
   136  }
   137  
   138  // WithBearerToken returns a new factory with bearer token
   139  func (f *FakeFactory) WithBearerToken(token string) clients.Factory {
   140  	copy := *f
   141  	copy.bearerToken = token
   142  	return &copy
   143  }
   144  
   145  // CreateJenkinsClient creates a new Jenkins client
   146  func (f *FakeFactory) CreateJenkinsClient(kubeClient kubernetes.Interface, ns string, handles util.IOFileHandles) (gojenkins.JenkinsClient, error) {
   147  	return f.GetDelegateFactory().CreateJenkinsClient(kubeClient, ns, handles)
   148  }
   149  
   150  // CreateCustomJenkinsClient creates a new Jenkins client for the given custom Jenkins App
   151  func (f *FakeFactory) CreateCustomJenkinsClient(kubeClient kubernetes.Interface, ns string, jenkinsServiceName string, handles util.IOFileHandles) (gojenkins.JenkinsClient, error) {
   152  	return f.GetDelegateFactory().CreateCustomJenkinsClient(kubeClient, ns, jenkinsServiceName, handles)
   153  }
   154  
   155  // GetJenkinsURL gets the Jenkins URL for the given namespace
   156  func (f *FakeFactory) GetJenkinsURL(kubeClient kubernetes.Interface, ns string) (string, error) {
   157  	return f.GetDelegateFactory().GetJenkinsURL(kubeClient, ns)
   158  }
   159  
   160  // GetCustomJenkinsURL gets a custom jenkins App service URL
   161  func (f *FakeFactory) GetCustomJenkinsURL(kubeClient kubernetes.Interface, ns string, jenkinsServiceName string) (string, error) {
   162  	return f.GetDelegateFactory().GetCustomJenkinsURL(kubeClient, ns, jenkinsServiceName)
   163  }
   164  
   165  // CreateJenkinsAuthConfigService creates a new Jenkins authentication configuration service
   166  func (f *FakeFactory) CreateJenkinsAuthConfigService(namespace string, jenkinsServiceName string) (auth.ConfigService, error) {
   167  	return f.CreateAuthConfigService(auth.JenkinsAuthConfigFile, namespace, kube.ValueKindJenkins, "")
   168  }
   169  
   170  // CreateChartmuseumAuthConfigService creates a new Chartmuseum authentication configuration service
   171  func (f *FakeFactory) CreateChartmuseumAuthConfigService(namespace string, serviceKind string) (auth.ConfigService, error) {
   172  	return f.CreateAuthConfigService(auth.ChartmuseumAuthConfigFile, namespace, kube.ValueKindChartmuseum, serviceKind)
   173  }
   174  
   175  // CreateIssueTrackerAuthConfigService creates a new issuer tracker configuration service
   176  func (f *FakeFactory) CreateIssueTrackerAuthConfigService(namespace string, serviceKind string) (auth.ConfigService, error) {
   177  	return f.CreateAuthConfigService(auth.IssuesAuthConfigFile, namespace, kube.ValueKindIssue, serviceKind)
   178  }
   179  
   180  // CreateChatAuthConfigService creates a new chat configuration service
   181  func (f *FakeFactory) CreateChatAuthConfigService(namespace string, serviceKind string) (auth.ConfigService, error) {
   182  	return f.CreateAuthConfigService(auth.ChatAuthConfigFile, namespace, kube.ValueKindChat, serviceKind)
   183  }
   184  
   185  // CreateAddonAuthConfigService creates a new addon auth configuration service
   186  func (f *FakeFactory) CreateAddonAuthConfigService(namespace string, serviceKind string) (auth.ConfigService, error) {
   187  	return f.CreateAuthConfigService(auth.AddonAuthConfigFile, namespace, kube.ValueKindAddon, serviceKind)
   188  }
   189  
   190  // CreateGitAuthConfigService creates a new git  auth configuration service
   191  func (f *FakeFactory) CreateGitAuthConfigService(namespace string, serviceKind string) (auth.ConfigService, error) {
   192  	return f.CreateAuthConfigService(auth.GitAuthConfigFile, namespace, kube.ValueKindGit, serviceKind)
   193  }
   194  
   195  // CreateAuthConfigService creates a new service which loads/saves the auth config from/to different sources depending
   196  // on the current secrets location and cluster context. The sources can be vault, kubernetes secrets or local file.
   197  func (f *FakeFactory) CreateAuthConfigService(fileName string, namespace string,
   198  	serverKind string, serviceKind string) (auth.ConfigService, error) {
   199  	configService := auth.NewMemoryAuthConfigService()
   200  	username := "fake-username"
   201  	url := "https://fake-server.org"
   202  	kind := serviceKind
   203  	if serverKind == kube.ValueKindGit {
   204  		kind = gits.KindGitFake
   205  	}
   206  	config := &auth.AuthConfig{
   207  		Servers: []*auth.AuthServer{
   208  			{
   209  				URL: url,
   210  				Users: []*auth.UserAuth{
   211  					{
   212  						Username: username,
   213  						ApiToken: "fake-token",
   214  					},
   215  				},
   216  				Kind:        kind,
   217  				Name:        serviceKind,
   218  				CurrentUser: username,
   219  			},
   220  		},
   221  		CurrentServer:    url,
   222  		PipeLineUsername: username,
   223  		PipeLineServer:   url,
   224  	}
   225  	configService.SetConfig(config)
   226  	return configService, nil
   227  }
   228  
   229  // SecretsLocation indicates the location where the secrets are stored
   230  func (f *FakeFactory) SecretsLocation() secrets.SecretsLocationKind {
   231  	return secrets.FileSystemLocationKind
   232  }
   233  
   234  // SetSecretsLocation configures the secrets location. It will persist the value in a config map
   235  // if the persist flag is set.
   236  func (f *FakeFactory) SetSecretsLocation(location secrets.SecretsLocationKind, persist bool) error {
   237  	return nil
   238  }
   239  
   240  // ResetSecretsLocation resets the location of the secrets stored in memory
   241  func (f *FakeFactory) ResetSecretsLocation() {
   242  	f.secretLocation = nil
   243  }
   244  
   245  // CreateSystemVaultClient gets the system vault client for managing the secrets
   246  func (f *FakeFactory) CreateSystemVaultClient(namespace string) (vault.Client, error) {
   247  	return fake_vault.NewFakeVaultClient(), nil
   248  }
   249  
   250  // CreateInternalVaultClient returns the given vault client for managing secrets
   251  // Will use default values for name and namespace if nil values are applied
   252  func (f *FakeFactory) CreateInternalVaultClient(name string, namespace string) (vault.Client, error) {
   253  	return fake_vault.NewFakeVaultClient(), nil
   254  }
   255  
   256  func (f *FakeFactory) CreateExternalVaultClient(vaultConfig vault.Vault, kubeClient kubernetes.Interface) (vault.Client, error) {
   257  	return fake_vault.NewFakeVaultClient(), nil
   258  }
   259  
   260  // CreateKubeClient creates a new Kubernetes client
   261  func (f *FakeFactory) CreateKubeClient() (kubernetes.Interface, string, error) {
   262  	if f.kubeClient == nil {
   263  		f.kubeClient = fake.NewSimpleClientset()
   264  	}
   265  	return f.kubeClient, f.namespace, nil
   266  }
   267  
   268  // CreateJXClient creates a new Kubernetes client for Jenkins X CRDs
   269  func (f *FakeFactory) CreateJXClient() (versioned.Interface, string, error) {
   270  	if f.jxClient == nil {
   271  		f.jxClient = v1fake.NewSimpleClientset()
   272  	}
   273  	return f.jxClient, f.namespace, nil
   274  }
   275  
   276  // CreateApiExtensionsClient creates a new Kubernetes ApiExtensions client
   277  func (f *FakeFactory) CreateApiExtensionsClient() (apiextensionsclientset.Interface, error) {
   278  	if f.apiClient == nil {
   279  		f.apiClient = apifake.NewSimpleClientset()
   280  	}
   281  	return f.apiClient, nil
   282  }
   283  
   284  // CreateProwJobClient creates a new Kubernetes client for ProwJob resources
   285  func (f *FakeFactory) CreateProwJobClient() (prowjobclient.Interface, string, error) {
   286  	if f.prowJobClient == nil {
   287  		f.prowJobClient = fake_prowjobclient.NewSimpleClientset()
   288  	}
   289  	return f.prowJobClient, f.namespace, nil
   290  }
   291  
   292  // CreateKnativeServeClient create a new Kubernetes client for Knative serve resources
   293  func (f *FakeFactory) CreateKnativeServeClient() (kserve.Interface, string, error) {
   294  	if f.kserveClient == nil {
   295  		f.kserveClient = kservefake.NewSimpleClientset()
   296  	}
   297  	return f.kserveClient, f.namespace, nil
   298  }
   299  
   300  // CreateTektonClient create a new Kubernetes client for Tekton resources
   301  func (f *FakeFactory) CreateTektonClient() (tektonclient.Interface, string, error) {
   302  	if f.tektonClient == nil {
   303  		f.tektonClient = tektonfake.NewSimpleClientset()
   304  	}
   305  	return f.tektonClient, f.namespace, nil
   306  }
   307  
   308  // CreateTektonPipelineResourceClient create a new Kubernetes client for Tekton PipelineResource resources
   309  func (f *FakeFactory) CreateTektonPipelineResourceClient() (resourceclient.Interface, string, error) {
   310  	if f.resourceClient == nil {
   311  		f.resourceClient = resourcefake.NewSimpleClientset()
   312  	}
   313  	return f.resourceClient, f.namespace, nil
   314  }
   315  
   316  // CreateDynamicClient creates a new Kubernetes Dynamic client
   317  func (f *FakeFactory) CreateDynamicClient() (dynamic.Interface, string, error) {
   318  	if f.dyncClient == nil {
   319  		config, err := f.CreateKubeConfig()
   320  		if err != nil {
   321  			return nil, "", err
   322  		}
   323  		kubeConfig, _, err := f.kubeConfig.LoadConfig()
   324  		if err != nil {
   325  			return nil, "", err
   326  		}
   327  		ns := kube.CurrentNamespace(kubeConfig)
   328  		f.dyncClient, err = dynamic.NewForConfig(config)
   329  		if err != nil {
   330  			return nil, ns, err
   331  		}
   332  		return f.dyncClient, ns, err
   333  	}
   334  	return f.dyncClient, f.namespace, nil
   335  }
   336  
   337  // CreateMetricsClient creates a new Kubernetes metrics client
   338  func (f *FakeFactory) CreateMetricsClient() (metricsclient.Interface, error) {
   339  	return fake_metricsclient.NewSimpleClientset(), nil
   340  }
   341  
   342  // CreateGitProvider creates a new Git provider
   343  func (f *FakeFactory) CreateGitProvider(gitURL string, message string, authConfigSvc auth.ConfigService,
   344  	gitKind string, ghOwner string, batchMode bool, gitter gits.Gitter, handles util.IOFileHandles) (gits.GitProvider, error) {
   345  	return f.GetDelegateFactory().CreateGitProvider(gitURL, message, authConfigSvc, gitKind, ghOwner, batchMode, gitter, handles)
   346  }
   347  
   348  // CreateKubeConfig creates the kubernetes configuration
   349  func (f *FakeFactory) CreateKubeConfig() (*rest.Config, error) {
   350  	return f.GetDelegateFactory().CreateKubeConfig()
   351  }
   352  
   353  // CreateTable creates a new table
   354  func (f *FakeFactory) CreateTable(out io.Writer) table.Table {
   355  	return table.CreateTable(out)
   356  }
   357  
   358  // IsInCDPipeline we should only load the git / issue tracker API tokens if the current pod
   359  // is in a pipeline and running as the Jenkins service account
   360  func (f *FakeFactory) IsInCDPipeline() bool {
   361  	// TODO should we let RBAC decide if we can see the Secrets in the dev namespace?
   362  	// or we should test if we are in the cluster and get the current ServiceAccount name?
   363  	buildNumber := builds.GetBuildNumber()
   364  	return buildNumber != "" || os.Getenv("PIPELINE_KIND") != ""
   365  }
   366  
   367  // function to tell if we are running incluster
   368  func (f *FakeFactory) IsInCluster() bool {
   369  	_, err := rest.InClusterConfig()
   370  	return err == nil
   371  }
   372  
   373  // CreateComplianceClient creates a new Sonobuoy compliance client
   374  func (f *FakeFactory) CreateComplianceClient() (*client.SonobuoyClient, error) {
   375  	config, err := f.CreateKubeConfig()
   376  	if err != nil {
   377  		return nil, errors.Wrap(err, "compliance client failed to load the Kubernetes configuration")
   378  	}
   379  	skc, err := sonoboy_dynamic.NewAPIHelperFromRESTConfig(config)
   380  	if err != nil {
   381  		return nil, errors.Wrap(err, "compliance dynamic client failed to be created")
   382  	}
   383  	return client.NewSonobuoyClient(config, skc)
   384  }
   385  
   386  // CreateVaultOperatorClient creates a new vault operator client
   387  func (f *FakeFactory) CreateVaultOperatorClient() (vaultoperatorclient.Interface, error) {
   388  	return fake_vaultoperatorclient.NewSimpleClientset(), nil
   389  }
   390  
   391  // CreateHelm creates a new Helm client
   392  func (f *FakeFactory) CreateHelm(verbose bool,
   393  	helmBinary string,
   394  	noTiller bool,
   395  	helmTemplate bool) helm.Helmer {
   396  
   397  	return f.GetDelegateFactory().CreateHelm(verbose,
   398  		helmBinary,
   399  		noTiller,
   400  		helmTemplate)
   401  }
   402  
   403  // CreateCertManagerClient creates a new Kuberntes client for cert-manager resources
   404  func (f *FakeFactory) CreateCertManagerClient() (certmngclient.Interface, error) {
   405  	return fake_certmngclient.NewSimpleClientset(), nil
   406  }
   407  
   408  // CreateLocalGitAuthConfigService creates a new service which loads/saves the auth config from/to a local file.
   409  func (f *FakeFactory) CreateLocalGitAuthConfigService() (auth.ConfigService, error) {
   410  	return f.GetDelegateFactory().CreateLocalGitAuthConfigService()
   411  }
   412  
   413  // CreateKustomizer creates a Kustomizer client
   414  func (f *FakeFactory) CreateKustomizer() kustomize.Kustomizer {
   415  	return f.GetDelegateFactory().CreateKustomizer()
   416  }