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 }