...

Source file src/k8s.io/client-go/tools/auth/exec/exec_test.go

Documentation: k8s.io/client-go/tools/auth/exec

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package exec
    18  
    19  import (
    20  	"strings"
    21  	"testing"
    22  
    23  	"github.com/google/go-cmp/cmp"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/runtime"
    26  	"k8s.io/apimachinery/pkg/runtime/schema"
    27  	clientauthenticationv1 "k8s.io/client-go/pkg/apis/clientauthentication/v1"
    28  	clientauthenticationv1beta1 "k8s.io/client-go/pkg/apis/clientauthentication/v1beta1"
    29  	"k8s.io/client-go/rest"
    30  )
    31  
    32  // restInfo holds the rest.Client fields that we care about for test assertions.
    33  type restInfo struct {
    34  	host            string
    35  	tlsClientConfig rest.TLSClientConfig
    36  	proxyURL        string
    37  }
    38  
    39  func TestLoadExecCredential(t *testing.T) {
    40  	t.Parallel()
    41  
    42  	tests := []struct {
    43  		name               string
    44  		data               []byte
    45  		wantExecCredential runtime.Object
    46  		wantRESTInfo       restInfo
    47  		wantErrorPrefix    string
    48  	}{
    49  		{
    50  			name: "v1 happy path",
    51  			data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{
    52  				Spec: clientauthenticationv1.ExecCredentialSpec{
    53  					Cluster: &clientauthenticationv1.Cluster{
    54  						Server:                   "https://some-server/some/path",
    55  						TLSServerName:            "some-server-name",
    56  						InsecureSkipTLSVerify:    true,
    57  						CertificateAuthorityData: []byte("some-ca-data"),
    58  						ProxyURL:                 "https://some-proxy-url:12345",
    59  						Config: runtime.RawExtension{
    60  							Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
    61  						},
    62  					},
    63  				},
    64  			}),
    65  			wantExecCredential: &clientauthenticationv1.ExecCredential{
    66  				TypeMeta: metav1.TypeMeta{
    67  					Kind:       "ExecCredential",
    68  					APIVersion: clientauthenticationv1.SchemeGroupVersion.String(),
    69  				},
    70  				Spec: clientauthenticationv1.ExecCredentialSpec{
    71  					Cluster: &clientauthenticationv1.Cluster{
    72  						Server:                   "https://some-server/some/path",
    73  						TLSServerName:            "some-server-name",
    74  						InsecureSkipTLSVerify:    true,
    75  						CertificateAuthorityData: []byte("some-ca-data"),
    76  						ProxyURL:                 "https://some-proxy-url:12345",
    77  						Config: runtime.RawExtension{
    78  							Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
    79  						},
    80  					},
    81  				},
    82  			},
    83  			wantRESTInfo: restInfo{
    84  				host: "https://some-server/some/path",
    85  				tlsClientConfig: rest.TLSClientConfig{
    86  					Insecure:   true,
    87  					ServerName: "some-server-name",
    88  					CAData:     []byte("some-ca-data"),
    89  				},
    90  				proxyURL: "https://some-proxy-url:12345",
    91  			},
    92  		},
    93  		{
    94  			name: "v1beta1 happy path",
    95  			data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{
    96  				Spec: clientauthenticationv1beta1.ExecCredentialSpec{
    97  					Cluster: &clientauthenticationv1beta1.Cluster{
    98  						Server:                   "https://some-server/some/path",
    99  						TLSServerName:            "some-server-name",
   100  						InsecureSkipTLSVerify:    true,
   101  						CertificateAuthorityData: []byte("some-ca-data"),
   102  						ProxyURL:                 "https://some-proxy-url:12345",
   103  						Config: runtime.RawExtension{
   104  							Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
   105  						},
   106  					},
   107  				},
   108  			}),
   109  			wantExecCredential: &clientauthenticationv1beta1.ExecCredential{
   110  				TypeMeta: metav1.TypeMeta{
   111  					Kind:       "ExecCredential",
   112  					APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(),
   113  				},
   114  				Spec: clientauthenticationv1beta1.ExecCredentialSpec{
   115  					Cluster: &clientauthenticationv1beta1.Cluster{
   116  						Server:                   "https://some-server/some/path",
   117  						TLSServerName:            "some-server-name",
   118  						InsecureSkipTLSVerify:    true,
   119  						CertificateAuthorityData: []byte("some-ca-data"),
   120  						ProxyURL:                 "https://some-proxy-url:12345",
   121  						Config: runtime.RawExtension{
   122  							Raw: []byte(`{"apiVersion":"group/v1","kind":"PluginConfig","spec":{"names":["marshmallow","zelda"]}}`),
   123  						},
   124  					},
   125  				},
   126  			},
   127  			wantRESTInfo: restInfo{
   128  				host: "https://some-server/some/path",
   129  				tlsClientConfig: rest.TLSClientConfig{
   130  					Insecure:   true,
   131  					ServerName: "some-server-name",
   132  					CAData:     []byte("some-ca-data"),
   133  				},
   134  				proxyURL: "https://some-proxy-url:12345",
   135  			},
   136  		},
   137  		{
   138  			name: "v1 nil config",
   139  			data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{
   140  				Spec: clientauthenticationv1.ExecCredentialSpec{
   141  					Cluster: &clientauthenticationv1.Cluster{
   142  						Server:                   "https://some-server/some/path",
   143  						TLSServerName:            "some-server-name",
   144  						InsecureSkipTLSVerify:    true,
   145  						CertificateAuthorityData: []byte("some-ca-data"),
   146  						ProxyURL:                 "https://some-proxy-url:12345",
   147  					},
   148  				},
   149  			}),
   150  			wantExecCredential: &clientauthenticationv1.ExecCredential{
   151  				TypeMeta: metav1.TypeMeta{
   152  					Kind:       "ExecCredential",
   153  					APIVersion: clientauthenticationv1.SchemeGroupVersion.String(),
   154  				},
   155  				Spec: clientauthenticationv1.ExecCredentialSpec{
   156  					Cluster: &clientauthenticationv1.Cluster{
   157  						Server:                   "https://some-server/some/path",
   158  						TLSServerName:            "some-server-name",
   159  						InsecureSkipTLSVerify:    true,
   160  						CertificateAuthorityData: []byte("some-ca-data"),
   161  						ProxyURL:                 "https://some-proxy-url:12345",
   162  					},
   163  				},
   164  			},
   165  			wantRESTInfo: restInfo{
   166  				host: "https://some-server/some/path",
   167  				tlsClientConfig: rest.TLSClientConfig{
   168  					Insecure:   true,
   169  					ServerName: "some-server-name",
   170  					CAData:     []byte("some-ca-data"),
   171  				},
   172  				proxyURL: "https://some-proxy-url:12345",
   173  			},
   174  		},
   175  		{
   176  			name: "v1beta1 nil config",
   177  			data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{
   178  				Spec: clientauthenticationv1beta1.ExecCredentialSpec{
   179  					Cluster: &clientauthenticationv1beta1.Cluster{
   180  						Server:                   "https://some-server/some/path",
   181  						TLSServerName:            "some-server-name",
   182  						InsecureSkipTLSVerify:    true,
   183  						CertificateAuthorityData: []byte("some-ca-data"),
   184  						ProxyURL:                 "https://some-proxy-url:12345",
   185  					},
   186  				},
   187  			}),
   188  			wantExecCredential: &clientauthenticationv1beta1.ExecCredential{
   189  				TypeMeta: metav1.TypeMeta{
   190  					Kind:       "ExecCredential",
   191  					APIVersion: clientauthenticationv1beta1.SchemeGroupVersion.String(),
   192  				},
   193  				Spec: clientauthenticationv1beta1.ExecCredentialSpec{
   194  					Cluster: &clientauthenticationv1beta1.Cluster{
   195  						Server:                   "https://some-server/some/path",
   196  						TLSServerName:            "some-server-name",
   197  						InsecureSkipTLSVerify:    true,
   198  						CertificateAuthorityData: []byte("some-ca-data"),
   199  						ProxyURL:                 "https://some-proxy-url:12345",
   200  					},
   201  				},
   202  			},
   203  			wantRESTInfo: restInfo{
   204  				host: "https://some-server/some/path",
   205  				tlsClientConfig: rest.TLSClientConfig{
   206  					Insecure:   true,
   207  					ServerName: "some-server-name",
   208  					CAData:     []byte("some-ca-data"),
   209  				},
   210  				proxyURL: "https://some-proxy-url:12345",
   211  			},
   212  		},
   213  		{
   214  			name: "v1 invalid cluster",
   215  			data: marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{
   216  				Spec: clientauthenticationv1.ExecCredentialSpec{
   217  					Cluster: &clientauthenticationv1.Cluster{
   218  						ProxyURL: "invalid- url\n",
   219  					},
   220  				},
   221  			}),
   222  			wantErrorPrefix: "cannot create rest.Config",
   223  		},
   224  		{
   225  			name: "v1beta1 invalid cluster",
   226  			data: marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{
   227  				Spec: clientauthenticationv1beta1.ExecCredentialSpec{
   228  					Cluster: &clientauthenticationv1beta1.Cluster{
   229  						ProxyURL: "invalid- url\n",
   230  					},
   231  				},
   232  			}),
   233  			wantErrorPrefix: "cannot create rest.Config",
   234  		},
   235  		{
   236  			name:            "v1 nil cluster",
   237  			data:            marshal(t, clientauthenticationv1.SchemeGroupVersion, &clientauthenticationv1.ExecCredential{}),
   238  			wantErrorPrefix: "ExecCredential does not contain cluster information",
   239  		},
   240  		{
   241  			name:            "v1beta1 nil cluster",
   242  			data:            marshal(t, clientauthenticationv1beta1.SchemeGroupVersion, &clientauthenticationv1beta1.ExecCredential{}),
   243  			wantErrorPrefix: "ExecCredential does not contain cluster information",
   244  		},
   245  		{
   246  			name:            "invalid object kind",
   247  			data:            marshal(t, metav1.SchemeGroupVersion, &metav1.Status{}),
   248  			wantErrorPrefix: "invalid group/kind: wanted ExecCredential.client.authentication.k8s.io, got Status",
   249  		},
   250  		{
   251  			name:            "bad data",
   252  			data:            []byte("bad data"),
   253  			wantErrorPrefix: "decode: ",
   254  		},
   255  	}
   256  	for _, test := range tests {
   257  		test := test
   258  		t.Run(test.name, func(t *testing.T) {
   259  			t.Parallel()
   260  
   261  			execCredential, restConfig, err := LoadExecCredential(test.data)
   262  			if test.wantErrorPrefix != "" {
   263  				if err == nil {
   264  					t.Error("wanted error, got success")
   265  				} else if !strings.HasPrefix(err.Error(), test.wantErrorPrefix) {
   266  					t.Errorf("wanted '%s', got '%s'", test.wantErrorPrefix, err.Error())
   267  				}
   268  			} else if err != nil {
   269  				t.Error(err)
   270  			} else {
   271  				if diff := cmp.Diff(test.wantExecCredential, execCredential); diff != "" {
   272  					t.Error(diff)
   273  				}
   274  
   275  				if diff := cmp.Diff(test.wantRESTInfo.host, restConfig.Host); diff != "" {
   276  					t.Error(diff)
   277  				}
   278  				if diff := cmp.Diff(test.wantRESTInfo.tlsClientConfig, restConfig.TLSClientConfig); diff != "" {
   279  					t.Error(diff)
   280  				}
   281  
   282  				proxyURL, err := restConfig.Proxy(nil)
   283  				if err != nil {
   284  					t.Fatal(err)
   285  				}
   286  				if diff := cmp.Diff(test.wantRESTInfo.proxyURL, proxyURL.String()); diff != "" {
   287  					t.Error(diff)
   288  				}
   289  			}
   290  		})
   291  	}
   292  }
   293  
   294  func marshal(t *testing.T, gv schema.GroupVersion, obj runtime.Object) []byte {
   295  	t.Helper()
   296  
   297  	data, err := runtime.Encode(codecs.LegacyCodec(gv), obj)
   298  	if err != nil {
   299  		t.Fatal(err)
   300  	}
   301  
   302  	return data
   303  }
   304  

View as plain text