github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/driver/kubernetes/context/endpoint_test.go (about)

     1  package context
     2  
     3  import (
     4  	"os"
     5  	"testing"
     6  
     7  	"github.com/docker/cli/cli/context"
     8  	"github.com/docker/cli/cli/context/store"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  	"k8s.io/client-go/tools/clientcmd"
    12  	clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
    13  )
    14  
    15  func testEndpoint(server, defaultNamespace string, ca, cert, key []byte, skipTLSVerify bool, proxyURL string) Endpoint {
    16  	var tlsData *context.TLSData
    17  	if ca != nil || cert != nil || key != nil {
    18  		tlsData = &context.TLSData{
    19  			CA:   ca,
    20  			Cert: cert,
    21  			Key:  key,
    22  		}
    23  	}
    24  	return Endpoint{
    25  		EndpointMeta: EndpointMeta{
    26  			EndpointMetaBase: context.EndpointMetaBase{
    27  				Host:          server,
    28  				SkipTLSVerify: skipTLSVerify,
    29  			},
    30  			DefaultNamespace: defaultNamespace,
    31  			ProxyURL:         proxyURL,
    32  		},
    33  		TLSData: tlsData,
    34  	}
    35  }
    36  
    37  var testStoreCfg = store.NewConfig(
    38  	func() interface{} {
    39  		return &map[string]interface{}{}
    40  	},
    41  	store.EndpointTypeGetter(KubernetesEndpoint, func() interface{} { return &EndpointMeta{} }),
    42  )
    43  
    44  func TestSaveLoadContexts(t *testing.T) {
    45  	storeDir, err := os.MkdirTemp("", "test-load-save-k8-context")
    46  	require.NoError(t, err)
    47  	defer os.RemoveAll(storeDir)
    48  	store := store.New(storeDir, testStoreCfg)
    49  	require.NoError(t, save(store, testEndpoint("https://test", "test", nil, nil, nil, false, ""), "raw-notls"))
    50  	require.NoError(t, save(store, testEndpoint("https://test", "test", nil, nil, nil, true, ""), "raw-notls-skip"))
    51  	require.NoError(t, save(store, testEndpoint("https://test", "test", []byte("ca"), []byte("cert"), []byte("key"), true, ""), "raw-tls"))
    52  	require.NoError(t, save(store, testEndpoint("https://test", "test", []byte("ca"), []byte("cert"), []byte("key"), false, "http://testProxy"), "proxy-url"))
    53  
    54  	kcFile, err := os.CreateTemp(os.TempDir(), "test-load-save-k8-context")
    55  	require.NoError(t, err)
    56  	defer os.Remove(kcFile.Name())
    57  	defer kcFile.Close()
    58  	cfg := clientcmdapi.NewConfig()
    59  	cfg.AuthInfos["user"] = clientcmdapi.NewAuthInfo()
    60  	cfg.Contexts["context1"] = clientcmdapi.NewContext()
    61  	cfg.Clusters["cluster1"] = clientcmdapi.NewCluster()
    62  	cfg.Contexts["context2"] = clientcmdapi.NewContext()
    63  	cfg.Clusters["cluster2"] = clientcmdapi.NewCluster()
    64  	cfg.Contexts["context3"] = clientcmdapi.NewContext()
    65  	cfg.Clusters["cluster3"] = clientcmdapi.NewCluster()
    66  	cfg.AuthInfos["user"].ClientCertificateData = []byte("cert")
    67  	cfg.AuthInfos["user"].ClientKeyData = []byte("key")
    68  	cfg.Clusters["cluster1"].Server = "https://server1"
    69  	cfg.Clusters["cluster1"].InsecureSkipTLSVerify = true
    70  	cfg.Clusters["cluster2"].Server = "https://server2"
    71  	cfg.Clusters["cluster2"].CertificateAuthorityData = []byte("ca")
    72  	cfg.Clusters["cluster3"].Server = "https://server3"
    73  	cfg.Clusters["cluster3"].CertificateAuthorityData = []byte("ca")
    74  	cfg.Clusters["cluster3"].ProxyURL = "http://proxy"
    75  	cfg.Contexts["context1"].AuthInfo = "user"
    76  	cfg.Contexts["context1"].Cluster = "cluster1"
    77  	cfg.Contexts["context1"].Namespace = "namespace1"
    78  	cfg.Contexts["context2"].AuthInfo = "user"
    79  	cfg.Contexts["context2"].Cluster = "cluster2"
    80  	cfg.Contexts["context2"].Namespace = "namespace2"
    81  	cfg.Contexts["context3"].AuthInfo = "user"
    82  	cfg.Contexts["context3"].Cluster = "cluster3"
    83  	cfg.Contexts["context3"].Namespace = "namespace3"
    84  
    85  	cfg.CurrentContext = "context1"
    86  	cfgData, err := clientcmd.Write(*cfg)
    87  	require.NoError(t, err)
    88  	_, err = kcFile.Write(cfgData)
    89  	require.NoError(t, err)
    90  	kcFile.Close()
    91  
    92  	epDefault, err := FromKubeConfig(kcFile.Name(), "", "")
    93  	require.NoError(t, err)
    94  	epContext2, err := FromKubeConfig(kcFile.Name(), "context2", "namespace-override")
    95  	require.NoError(t, err)
    96  	require.NoError(t, save(store, epDefault, "embed-default-context"))
    97  	require.NoError(t, save(store, epContext2, "embed-context2"))
    98  
    99  	epProxyURL, err := FromKubeConfig(kcFile.Name(), "context3", "namespace-override")
   100  	require.NoError(t, err)
   101  	require.NoError(t, save(store, epProxyURL, "embed-proxy-url"))
   102  
   103  	rawNoTLSMeta, err := store.GetMetadata("raw-notls")
   104  	require.NoError(t, err)
   105  	rawNoTLSSkipMeta, err := store.GetMetadata("raw-notls-skip")
   106  	require.NoError(t, err)
   107  	rawTLSMeta, err := store.GetMetadata("raw-tls")
   108  	require.NoError(t, err)
   109  	embededDefaultMeta, err := store.GetMetadata("embed-default-context")
   110  	require.NoError(t, err)
   111  	embededContext2Meta, err := store.GetMetadata("embed-context2")
   112  	require.NoError(t, err)
   113  	proxyURLMetadata, err := store.GetMetadata("proxy-url")
   114  	require.NoError(t, err)
   115  	embededProxyURL, err := store.GetMetadata("embed-proxy-url")
   116  	require.NoError(t, err)
   117  
   118  	rawNoTLS := EndpointFromContext(rawNoTLSMeta)
   119  	rawNoTLSSkip := EndpointFromContext(rawNoTLSSkipMeta)
   120  	rawTLS := EndpointFromContext(rawTLSMeta)
   121  	embededDefault := EndpointFromContext(embededDefaultMeta)
   122  	embededContext2 := EndpointFromContext(embededContext2Meta)
   123  	proxyURLEPMeta := EndpointFromContext(proxyURLMetadata)
   124  	embededProxyURLEPMeta := EndpointFromContext(embededProxyURL)
   125  
   126  	rawNoTLSEP, err := rawNoTLS.WithTLSData(store, "raw-notls")
   127  	require.NoError(t, err)
   128  	checkClientConfig(t, rawNoTLSEP, "https://test", "test",
   129  		nil, nil, nil, false, // tls
   130  		"", // proxy
   131  	)
   132  
   133  	rawNoTLSSkipEP, err := rawNoTLSSkip.WithTLSData(store, "raw-notls-skip")
   134  	require.NoError(t, err)
   135  	checkClientConfig(t, rawNoTLSSkipEP, "https://test", "test",
   136  		nil, nil, nil, true, // tls
   137  		"", // proxy
   138  	)
   139  
   140  	rawTLSEP, err := rawTLS.WithTLSData(store, "raw-tls")
   141  	require.NoError(t, err)
   142  	checkClientConfig(t, rawTLSEP, "https://test", "test",
   143  		[]byte("ca"), []byte("cert"), []byte("key"), true, // tls
   144  		"", // proxy
   145  	)
   146  
   147  	embededDefaultEP, err := embededDefault.WithTLSData(store, "embed-default-context")
   148  	require.NoError(t, err)
   149  	checkClientConfig(t, embededDefaultEP, "https://server1", "namespace1",
   150  		nil, []byte("cert"), []byte("key"), true, // tls
   151  		"", // proxy
   152  	)
   153  
   154  	embededContext2EP, err := embededContext2.WithTLSData(store, "embed-context2")
   155  	require.NoError(t, err)
   156  	checkClientConfig(t, embededContext2EP, "https://server2", "namespace-override",
   157  		[]byte("ca"), []byte("cert"), []byte("key"), false, // tls
   158  		"", // proxy
   159  	)
   160  
   161  	proxyURLEP, err := proxyURLEPMeta.WithTLSData(store, "proxy-url")
   162  	require.NoError(t, err)
   163  	checkClientConfig(t, proxyURLEP, "https://test", "test",
   164  		[]byte("ca"), []byte("cert"), []byte("key"), false, // tls
   165  		"http://testProxy", // proxy
   166  	)
   167  
   168  	embededProxyURLEP, err := embededProxyURLEPMeta.WithTLSData(store, "embed-proxy-url")
   169  	require.NoError(t, err)
   170  	checkClientConfig(t, embededProxyURLEP, "https://server3", "namespace-override",
   171  		[]byte("ca"), []byte("cert"), []byte("key"), false, // tls
   172  		"http://proxy", // proxy
   173  	)
   174  }
   175  
   176  func checkClientConfig(t *testing.T, ep Endpoint, server, namespace string, ca, cert, key []byte, skipTLSVerify bool, proxyURLString string) {
   177  	config := ep.KubernetesConfig()
   178  	cfg, err := config.ClientConfig()
   179  	require.NoError(t, err)
   180  	ns, _, _ := config.Namespace()
   181  	assert.Equal(t, server, cfg.Host)
   182  	assert.Equal(t, namespace, ns)
   183  	assert.Equal(t, ca, cfg.CAData)
   184  	assert.Equal(t, cert, cfg.CertData)
   185  	assert.Equal(t, key, cfg.KeyData)
   186  	assert.Equal(t, skipTLSVerify, cfg.Insecure)
   187  	// proxy assertions
   188  	if proxyURLString != "" { // expected proxy is set
   189  		require.NotNil(t, cfg.Proxy, "expected proxy to be set, but is nil instead")
   190  		proxyURL, err := cfg.Proxy(nil)
   191  		require.NoError(t, err)
   192  		assert.Equal(t, proxyURLString, proxyURL.String())
   193  	} else {
   194  		assert.True(t, cfg.Proxy == nil, "expected proxy to be nil, but is not nil instead")
   195  	}
   196  }
   197  
   198  func save(s store.Writer, ep Endpoint, name string) error {
   199  	meta := store.Metadata{
   200  		Endpoints: map[string]interface{}{
   201  			KubernetesEndpoint: ep.EndpointMeta,
   202  		},
   203  		Name: name,
   204  	}
   205  	if err := s.CreateOrUpdate(meta); err != nil {
   206  		return err
   207  	}
   208  	return s.ResetEndpointTLSMaterial(name, KubernetesEndpoint, ep.TLSData.ToStoreTLSData())
   209  }
   210  
   211  func TestSaveLoadGKEConfig(t *testing.T) {
   212  	storeDir, err := os.MkdirTemp("", t.Name())
   213  	require.NoError(t, err)
   214  	defer os.RemoveAll(storeDir)
   215  	store := store.New(storeDir, testStoreCfg)
   216  	cfg, err := clientcmd.LoadFromFile("fixtures/gke-kubeconfig")
   217  	require.NoError(t, err)
   218  	clientCfg := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
   219  	expectedCfg, err := clientCfg.ClientConfig()
   220  	require.NoError(t, err)
   221  	ep, err := FromKubeConfig("fixtures/gke-kubeconfig", "", "")
   222  	require.NoError(t, err)
   223  	require.NoError(t, save(store, ep, "gke-context"))
   224  	persistedMetadata, err := store.GetMetadata("gke-context")
   225  	require.NoError(t, err)
   226  	persistedEPMeta := EndpointFromContext(persistedMetadata)
   227  	assert.True(t, persistedEPMeta != nil)
   228  	persistedEP, err := persistedEPMeta.WithTLSData(store, "gke-context")
   229  	require.NoError(t, err)
   230  	persistedCfg := persistedEP.KubernetesConfig()
   231  	actualCfg, err := persistedCfg.ClientConfig()
   232  	require.NoError(t, err)
   233  	assert.Equal(t, expectedCfg.AuthProvider, actualCfg.AuthProvider)
   234  }
   235  
   236  func TestSaveLoadEKSConfig(t *testing.T) {
   237  	storeDir, err := os.MkdirTemp("", t.Name())
   238  	require.NoError(t, err)
   239  	defer os.RemoveAll(storeDir)
   240  	store := store.New(storeDir, testStoreCfg)
   241  	cfg, err := clientcmd.LoadFromFile("fixtures/eks-kubeconfig")
   242  	require.NoError(t, err)
   243  	clientCfg := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
   244  	expectedCfg, err := clientCfg.ClientConfig()
   245  	require.NoError(t, err)
   246  	ep, err := FromKubeConfig("fixtures/eks-kubeconfig", "", "")
   247  	require.NoError(t, err)
   248  	require.NoError(t, save(store, ep, "eks-context"))
   249  	persistedMetadata, err := store.GetMetadata("eks-context")
   250  	require.NoError(t, err)
   251  	persistedEPMeta := EndpointFromContext(persistedMetadata)
   252  	assert.True(t, persistedEPMeta != nil)
   253  	persistedEP, err := persistedEPMeta.WithTLSData(store, "eks-context")
   254  	require.NoError(t, err)
   255  	persistedCfg := persistedEP.KubernetesConfig()
   256  	actualCfg, err := persistedCfg.ClientConfig()
   257  	require.NoError(t, err)
   258  	assert.Equal(t, expectedCfg.ExecProvider, actualCfg.ExecProvider)
   259  }
   260  
   261  func TestSaveLoadK3SConfig(t *testing.T) {
   262  	storeDir, err := os.MkdirTemp("", t.Name())
   263  	require.NoError(t, err)
   264  	defer os.RemoveAll(storeDir)
   265  	store := store.New(storeDir, testStoreCfg)
   266  	cfg, err := clientcmd.LoadFromFile("fixtures/k3s-kubeconfig")
   267  	require.NoError(t, err)
   268  	clientCfg := clientcmd.NewDefaultClientConfig(*cfg, &clientcmd.ConfigOverrides{})
   269  	expectedCfg, err := clientCfg.ClientConfig()
   270  	require.NoError(t, err)
   271  	ep, err := FromKubeConfig("fixtures/k3s-kubeconfig", "", "")
   272  	require.NoError(t, err)
   273  	require.NoError(t, save(store, ep, "k3s-context"))
   274  	persistedMetadata, err := store.GetMetadata("k3s-context")
   275  	require.NoError(t, err)
   276  	persistedEPMeta := EndpointFromContext(persistedMetadata)
   277  	assert.True(t, persistedEPMeta != nil)
   278  	persistedEP, err := persistedEPMeta.WithTLSData(store, "k3s-context")
   279  	require.NoError(t, err)
   280  	persistedCfg := persistedEP.KubernetesConfig()
   281  	actualCfg, err := persistedCfg.ClientConfig()
   282  	require.NoError(t, err)
   283  	assert.True(t, len(actualCfg.Username) > 0)
   284  	assert.True(t, len(actualCfg.Password) > 0)
   285  	assert.Equal(t, expectedCfg.Username, actualCfg.Username)
   286  	assert.Equal(t, expectedCfg.Password, actualCfg.Password)
   287  }