pkg/kube/mock_client.go (216 lines of code) (raw):

// Copyright Istio Authors // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. // You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software // distributed under the License is distributed on an "AS IS" BASIS, // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. // See the License for the specific language governing permissions and // limitations under the License. package kube import ( "context" "fmt" "net/http" ) import ( "google.golang.org/grpc/credentials" istioclient "istio.io/client-go/pkg/clientset/versioned" istioinformer "istio.io/client-go/pkg/informers/externalversions" "istio.io/pkg/version" v1 "k8s.io/api/core/v1" "k8s.io/apiextensions-apiserver/pkg/client/clientset/clientset" kubeExtInformers "k8s.io/apiextensions-apiserver/pkg/client/informers/externalversions" kubeVersion "k8s.io/apimachinery/pkg/version" "k8s.io/cli-runtime/pkg/resource" "k8s.io/client-go/dynamic" "k8s.io/client-go/dynamic/dynamicinformer" "k8s.io/client-go/informers" "k8s.io/client-go/kubernetes" "k8s.io/client-go/metadata" "k8s.io/client-go/metadata/metadatainformer" "k8s.io/client-go/rest" "k8s.io/client-go/rest/fake" cmdtesting "k8s.io/kubectl/pkg/cmd/testing" "k8s.io/kubectl/pkg/cmd/util" serviceapisclient "sigs.k8s.io/gateway-api/pkg/client/clientset/versioned" serviceapisinformer "sigs.k8s.io/gateway-api/pkg/client/informers/externalversions" mcsapisclient "sigs.k8s.io/mcs-api/pkg/client/clientset/versioned" mcsapisinformer "sigs.k8s.io/mcs-api/pkg/client/informers/externalversions" ) var _ ExtendedClient = MockClient{} type MockPortForwarder struct{} func (m MockPortForwarder) Start() error { return nil } func (m MockPortForwarder) Address() string { return "localhost:3456" } func (m MockPortForwarder) Close() { } func (m MockPortForwarder) WaitForStop() { } var _ PortForwarder = MockPortForwarder{} // MockClient for tests that rely on kube.Client. type MockClient struct { kubernetes.Interface RestClient *rest.RESTClient // Results is a map of podName to the results of the expected test on the pod Results map[string][]byte DiscoverablePods map[string]map[string]*v1.PodList RevisionValue string ConfigValue *rest.Config IstioVersions *version.MeshInfo KubernetesVersion uint IstiodVersion string } func (c MockClient) ExtInformer() kubeExtInformers.SharedInformerFactory { panic("not used in mock") } func (c MockClient) Istio() istioclient.Interface { panic("not used in mock") } func (c MockClient) GatewayAPI() serviceapisclient.Interface { panic("not used in mock") } func (c MockClient) MCSApis() mcsapisclient.Interface { panic("not used in mock") } func (c MockClient) IstioInformer() istioinformer.SharedInformerFactory { panic("not used in mock") } func (c MockClient) GatewayAPIInformer() serviceapisinformer.SharedInformerFactory { panic("not used in mock") } func (c MockClient) MCSApisInformer() mcsapisinformer.SharedInformerFactory { panic("not used in mock") } func (c MockClient) Metadata() metadata.Interface { panic("not used in mock") } func (c MockClient) KubeInformer() informers.SharedInformerFactory { panic("not used in mock") } func (c MockClient) DynamicInformer() dynamicinformer.DynamicSharedInformerFactory { panic("not used in mock") } func (c MockClient) MetadataInformer() metadatainformer.SharedInformerFactory { panic("not used in mock") } func (c MockClient) RunAndWait(stop <-chan struct{}) { panic("not used in mock") } func (c MockClient) Kube() kubernetes.Interface { return c.Interface } func (c MockClient) DynamicClient() dynamic.Interface { panic("not used in mock") } func (c MockClient) MetadataClient() metadata.Interface { panic("not used in mock") } func (c MockClient) AllDiscoveryDo(_ context.Context, _, _ string) (map[string][]byte, error) { return c.Results, nil } func (c MockClient) EnvoyDo(ctx context.Context, podName, podNamespace, method, path string) ([]byte, error) { results, ok := c.Results[podName] if !ok { return nil, fmt.Errorf("unable to retrieve Pod: pods %q not found", podName) } return results, nil } func (c MockClient) EnvoyDoWithPort(ctx context.Context, podName, podNamespace, method, path string, port int) ([]byte, error) { results, ok := c.Results[podName] if !ok { return nil, fmt.Errorf("unable to retrieve Pod: pods %q not found", podName) } return results, nil } func (c MockClient) RESTConfig() *rest.Config { return c.ConfigValue } func (c MockClient) GetIstioVersions(_ context.Context, _ string) (*version.MeshInfo, error) { if c.IstiodVersion != "" { server := version.BuildInfo{} setServerInfoWithIstiodVersionInfo(&server, c.IstiodVersion) return &version.MeshInfo{ { Info: server, }, }, nil } return c.IstioVersions, nil } func (c MockClient) PodsForSelector(_ context.Context, namespace string, labelSelectors ...string) (*v1.PodList, error) { podsForNamespace, ok := c.DiscoverablePods[namespace] if !ok { return &v1.PodList{}, nil } var allPods v1.PodList for _, selector := range labelSelectors { pods, ok := podsForNamespace[selector] if !ok { return &v1.PodList{}, nil } allPods.TypeMeta = pods.TypeMeta allPods.ListMeta = pods.ListMeta allPods.Items = append(allPods.Items, pods.Items...) } return &allPods, nil } func (c MockClient) Revision() string { return c.RevisionValue } func (c MockClient) REST() rest.Interface { panic("not implemented by mock") } func (c MockClient) ApplyYAMLFiles(string, ...string) error { return nil } func (c MockClient) ApplyYAMLFilesDryRun(string, ...string) error { panic("not implemented by mock") } // CreatePerRPCCredentials -- when implemented -- mocks per-RPC credentials (bearer token) func (c MockClient) CreatePerRPCCredentials(ctx context.Context, tokenNamespace, tokenServiceAccount string, audiences []string, expirationSeconds int64) (credentials.PerRPCCredentials, error) { panic("not implemented by mock") } func (c MockClient) DeleteYAMLFiles(string, ...string) error { panic("not implemented by mock") } func (c MockClient) DeleteYAMLFilesDryRun(string, ...string) error { panic("not implemented by mock") } func (c MockClient) Ext() clientset.Interface { panic("not implemented by mock") } func (c MockClient) Dynamic() dynamic.Interface { panic("not implemented by mock") } func (c MockClient) GetKubernetesVersion() (*kubeVersion.Info, error) { minor := fmt.Sprint(c.KubernetesVersion) if c.KubernetesVersion == 0 { minor = "16" } return &kubeVersion.Info{ Major: "1", Minor: minor, }, nil } func (c MockClient) GetIstioPods(_ context.Context, _ string, _ map[string]string) ([]v1.Pod, error) { return nil, fmt.Errorf("TODO MockClient doesn't implement IstioPods") } func (c MockClient) PodExecCommands(podName, podNamespace, container string, commands []string) (stdout string, stderr string, err error) { return "", "", fmt.Errorf("TODO MockClient doesn't implement exec") } func (c MockClient) PodExec(_, _, _ string, _ string) (string, string, error) { return "", "", fmt.Errorf("TODO MockClient doesn't implement exec") } func (c MockClient) PodLogs(_ context.Context, _ string, _ string, _ string, _ bool) (string, error) { return "", fmt.Errorf("TODO MockClient doesn't implement logs") } func (c MockClient) NewPortForwarder(_, _, _ string, _, _ int) (PortForwarder, error) { return MockPortForwarder{}, nil } // UtilFactory mock's kubectl's utility factory. This code sets up a fake factory, // similar to the one in https://github.com/kubernetes/kubectl/blob/master/pkg/cmd/describe/describe_test.go func (c MockClient) UtilFactory() util.Factory { tf := cmdtesting.NewTestFactory() _, _, codec := cmdtesting.NewExternalScheme() tf.UnstructuredClient = &fake.RESTClient{ NegotiatedSerializer: resource.UnstructuredPlusDefaultContentConfig().NegotiatedSerializer, Resp: &http.Response{ StatusCode: http.StatusOK, Header: cmdtesting.DefaultHeader(), Body: cmdtesting.ObjBody(codec, cmdtesting.NewInternalType("", "", "foo")), }, } return tf }