github.com/1aal/kubeblocks@v0.0.0-20231107070852-e1c03e598921/pkg/cli/testing/factory.go (about)

     1  /*
     2  Copyright (C) 2022-2023 ApeCloud Co., Ltd
     3  
     4  This file is part of KubeBlocks project
     5  
     6  This program is free software: you can redistribute it and/or modify
     7  it under the terms of the GNU Affero General Public License as published by
     8  the Free Software Foundation, either version 3 of the License, or
     9  (at your option) any later version.
    10  
    11  This program is distributed in the hope that it will be useful
    12  but WITHOUT ANY WARRANTY; without even the implied warranty of
    13  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    14  GNU Affero General Public License for more details.
    15  
    16  You should have received a copy of the GNU Affero General Public License
    17  along with this program.  If not, see <http://www.gnu.org/licenses/>.
    18  */
    19  
    20  package testing
    21  
    22  import (
    23  	"bytes"
    24  	"fmt"
    25  	"os"
    26  
    27  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    28  	"k8s.io/cli-runtime/pkg/genericclioptions"
    29  	"k8s.io/client-go/restmapper"
    30  	"k8s.io/client-go/tools/clientcmd"
    31  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    32  	cmdtesting "k8s.io/kubectl/pkg/cmd/testing"
    33  	cmdutil "k8s.io/kubectl/pkg/cmd/util"
    34  )
    35  
    36  // NewTestFactory is like cmdtesting.NewTestFactory, registers KubeBlocks custom objects
    37  func NewTestFactory(namespace string) *cmdtesting.TestFactory {
    38  	tf := cmdtesting.NewTestFactory()
    39  	mapper := restmapper.NewDiscoveryRESTMapper(testDynamicResources())
    40  	clientConfig := testClientConfig()
    41  	cf := genericclioptions.NewTestConfigFlags().WithRESTMapper(mapper).
    42  		WithClientConfig(clientConfig).WithNamespace(namespace)
    43  	tf.Factory = cmdutil.NewFactory(cf)
    44  
    45  	restConfig, err := clientConfig.ClientConfig()
    46  	if err != nil {
    47  		panic(fmt.Sprintf("unable to create a fake restclient config: %v", err))
    48  	}
    49  	tf.ClientConfigVal = restConfig
    50  
    51  	return tf.WithClientConfig(clientConfig).WithNamespace(namespace)
    52  }
    53  
    54  func testClientConfig() clientcmd.ClientConfig {
    55  	tmpFile, err := os.CreateTemp(os.TempDir(), "cmdtests_temp")
    56  	if err != nil {
    57  		panic(fmt.Sprintf("unable to create a fake client config: %v", err))
    58  	}
    59  
    60  	loadingRules := &clientcmd.ClientConfigLoadingRules{
    61  		Precedence:     []string{tmpFile.Name()},
    62  		MigrationRules: map[string]string{},
    63  	}
    64  
    65  	overrides := &clientcmd.ConfigOverrides{ClusterDefaults: clientcmdapi.Cluster{Server: "http://localhost:8080"}}
    66  	fallbackReader := bytes.NewBuffer([]byte{})
    67  	return clientcmd.NewInteractiveDeferredLoadingClientConfig(loadingRules, overrides, fallbackReader)
    68  }
    69  
    70  func testDynamicResources() []*restmapper.APIGroupResources {
    71  	return []*restmapper.APIGroupResources{
    72  		{
    73  			Group: metav1.APIGroup{
    74  				Versions: []metav1.GroupVersionForDiscovery{
    75  					{Version: "v1"},
    76  				},
    77  				PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
    78  			},
    79  			VersionedResources: map[string][]metav1.APIResource{
    80  				"v1": {
    81  					{Name: "pods", Namespaced: true, Kind: "Pod"},
    82  					{Name: "services", Namespaced: true, Kind: "Service"},
    83  					{Name: "nodes", Namespaced: false, Kind: "Node"},
    84  					{Name: "secrets", Namespaced: true, Kind: "Secret"},
    85  					{Name: "configmaps", Namespaced: true, Kind: "ConfigMap"},
    86  					{Name: "namespaces", Namespaced: false, Kind: "Namespace"},
    87  					{Name: "serviceaccounts", Namespaced: true, Kind: "ServiceAccount"},
    88  				},
    89  			},
    90  		},
    91  		{
    92  			Group: metav1.APIGroup{
    93  				Name: "apps",
    94  				Versions: []metav1.GroupVersionForDiscovery{
    95  					{Version: "v1"},
    96  				},
    97  				PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
    98  			},
    99  			VersionedResources: map[string][]metav1.APIResource{
   100  				"v1": {
   101  					{Name: "deployments", Namespaced: true, Kind: "Deployment"},
   102  					{Name: "statefulsets", Namespaced: true, Kind: "StatefulSet"},
   103  				},
   104  			},
   105  		},
   106  		{
   107  			Group: metav1.APIGroup{
   108  				Name: "rbac.authorization.k8s.io",
   109  				Versions: []metav1.GroupVersionForDiscovery{
   110  					{Version: "v1"},
   111  				},
   112  				PreferredVersion: metav1.GroupVersionForDiscovery{Version: "v1"},
   113  			},
   114  			VersionedResources: map[string][]metav1.APIResource{
   115  				"v1": {
   116  					{Name: "roles", Namespaced: true, Kind: "Role"},
   117  					{Name: "rolebindings", Namespaced: true, Kind: "RoleBinding"},
   118  				},
   119  			},
   120  		},
   121  		// KubeBlocks objects
   122  		{
   123  			Group: metav1.APIGroup{
   124  				Name: "apps.kubeblocks.io",
   125  				Versions: []metav1.GroupVersionForDiscovery{
   126  					{GroupVersion: "apps.kubeblocks.io/v1alpha1", Version: "v1alpha1"},
   127  				},
   128  				PreferredVersion: metav1.GroupVersionForDiscovery{
   129  					GroupVersion: "apps.kubeblocks.io/v1alpha1",
   130  					Version:      "v1alpha1"},
   131  			},
   132  			VersionedResources: map[string][]metav1.APIResource{
   133  				"v1alpha1": {
   134  					{Name: "clusters", Namespaced: true, Kind: "Cluster"},
   135  					{Name: "clusterdefinitions", Namespaced: false, Kind: "clusterdefinition"},
   136  					{Name: "clusterversions", Namespaced: false, Kind: "clusterversion"},
   137  					{Name: "opsrequests", Namespaced: true, Kind: "OpsRequest"},
   138  				},
   139  			},
   140  		},
   141  		{
   142  			Group: metav1.APIGroup{
   143  				Name: "chaos-mesh.org",
   144  				Versions: []metav1.GroupVersionForDiscovery{
   145  					{GroupVersion: "chaos-mesh.org/v1alpha1", Version: "v1alpha1"},
   146  				},
   147  				PreferredVersion: metav1.GroupVersionForDiscovery{
   148  					GroupVersion: "chaos-mesh.org/v1alpha1",
   149  					Version:      "v1alpha1"},
   150  			},
   151  			VersionedResources: map[string][]metav1.APIResource{
   152  				"v1alpha1": {
   153  					{Name: "podchaoses", Namespaced: true, Kind: "PodChaos"},
   154  					{Name: "networkchaoses", Namespaced: true, Kind: "NetworkChaos"},
   155  					{Name: "httpchaoses", Namespaced: true, Kind: "HTTPChaos"},
   156  				},
   157  			},
   158  		},
   159  	}
   160  }