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 }