@@ -30,17 +30,19 @@ import (
3030 "github.com/abiosoft/lineprefix"
3131 "github.com/fatih/color"
3232
33+ "k8s.io/apiserver/pkg/authentication/user"
3334 "k8s.io/client-go/tools/clientcmd"
3435 clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
3536 "k8s.io/klog/v2"
3637
3738 kcpclientset "github.com/kcp-dev/sdk/client/clientset/versioned/cluster"
3839 kcptestingserver "github.com/kcp-dev/sdk/testing/server"
40+ "github.com/kcp-dev/sdk/testing/third_party/library-go/crypto"
3941
4042 "github.com/kcp-dev/kcp/cmd/test-server/helpers"
4143)
4244
43- func startCacheServer (ctx context.Context , logDirPath , workingDir , hostIP string , syntheticDelay time.Duration ) (<- chan error , string , error ) {
45+ func startCacheServer (ctx context.Context , logDirPath , workingDir , hostIP string , syntheticDelay time.Duration , clientCA * crypto. CA , clientCAPath string ) (<- chan error , string , error ) {
4446 cyan := color .New (color .BgHiCyan , color .FgHiWhite ).SprintFunc ()
4547 inverse := color .New (color .BgHiWhite , color .FgHiCyan ).SprintFunc ()
4648 out := lineprefix .New (
@@ -52,6 +54,32 @@ func startCacheServer(ctx context.Context, logDirPath, workingDir, hostIP string
5254 lineprefix .Color (color .New (color .FgHiWhite )),
5355 )
5456 cacheWorkingDir := filepath .Join (workingDir , ".kcp-cache" )
57+
58+ // Generate a client certificate for accessing the cache server.
59+ cacheClientCert := filepath .Join (cacheWorkingDir , "cache-client.crt" )
60+ cacheClientKey := filepath .Join (cacheWorkingDir , "cache-client.key" )
61+ if err := os .MkdirAll (cacheWorkingDir , 0755 ); err != nil {
62+ return nil , "" , err
63+ }
64+ _ , err := clientCA .MakeClientCertificate (cacheClientCert , cacheClientKey ,
65+ & user.DefaultInfo {Name : "cache-client" , Groups : []string {"system:masters" }}, 365 )
66+ if err != nil {
67+ return nil , "" , fmt .Errorf ("failed to create cache client cert: %w" , err )
68+ }
69+
70+ // Use absolute paths for the client cert/key so they resolve correctly
71+ // regardless of how the kubeconfig is loaded. ClientConfigLoadingRules
72+ // resolves relative paths relative to the kubeconfig file, while
73+ // LoadFromFile + NewNonInteractiveClientConfig uses them as-is from CWD.
74+ absCacheClientCert , err := filepath .Abs (cacheClientCert )
75+ if err != nil {
76+ return nil , "" , fmt .Errorf ("failed to resolve absolute path for cache client cert: %w" , err )
77+ }
78+ absCacheClientKey , err := filepath .Abs (cacheClientKey )
79+ if err != nil {
80+ return nil , "" , fmt .Errorf ("failed to resolve absolute path for cache client key: %w" , err )
81+ }
82+
5583 cachePort := 8012
5684 workdir , commandLine := kcptestingserver .Command ("cache-server" , "cache" )
5785 commandLine = append (
@@ -62,6 +90,7 @@ func startCacheServer(ctx context.Context, logDirPath, workingDir, hostIP string
6290 "--embedded-etcd-peer-port=8011" ,
6391 fmt .Sprintf ("--secure-port=%d" , cachePort ),
6492 fmt .Sprintf ("--synthetic-delay=%s" , syntheticDelay .String ()),
93+ fmt .Sprintf ("--client-ca-file=%s" , clientCAPath ),
6594 )
6695 fmt .Fprintf (out , "running: %v\n " , strings .Join (commandLine , " " ))
6796 cmd := exec .CommandContext (ctx , commandLine [0 ], commandLine [1 :]... ) //nolint:gosec
@@ -119,35 +148,40 @@ func startCacheServer(ctx context.Context, logDirPath, workingDir, hostIP string
119148 continue
120149 }
121150
122- if _ , err := os .Stat (cacheKubeconfigPath ); os .IsNotExist (err ) {
123- cacheServerCert , err := os .ReadFile (filepath .Join (cacheWorkingDir , "apiserver.crt" ))
124- if err != nil {
125- return nil , "" , err
126- }
127- cacheServerKubeConfig := clientcmdapi.Config {
128- Clusters : map [string ]* clientcmdapi.Cluster {
129- "cache" : {
130- Server : fmt .Sprintf ("https://localhost:%d" , cachePort ),
131- CertificateAuthorityData : cacheServerCert ,
132- },
151+ cacheServerCert , err := os .ReadFile (filepath .Join (cacheWorkingDir , "apiserver.crt" ))
152+ if err != nil {
153+ return nil , "" , err
154+ }
155+ cacheServerKubeConfig := clientcmdapi.Config {
156+ Clusters : map [string ]* clientcmdapi.Cluster {
157+ "cache" : {
158+ Server : fmt .Sprintf ("https://localhost:%d" , cachePort ),
159+ CertificateAuthorityData : cacheServerCert ,
133160 },
134- Contexts : map [string ]* clientcmdapi.Context {
135- "cache" : {
136- Cluster : "cache" ,
137- },
161+ },
162+ AuthInfos : map [string ]* clientcmdapi.AuthInfo {
163+ "cache" : {
164+ ClientCertificate : absCacheClientCert ,
165+ ClientKey : absCacheClientKey ,
138166 },
139- CurrentContext : "cache" ,
140- }
141- if err := clientcmd .WriteToFile (cacheServerKubeConfig , cacheKubeconfigPath ); err != nil {
142- return nil , "" , err
143- }
167+ },
168+ Contexts : map [string ]* clientcmdapi.Context {
169+ "cache" : {
170+ Cluster : "cache" ,
171+ AuthInfo : "cache" ,
172+ },
173+ },
174+ CurrentContext : "cache" ,
175+ }
176+ if err := clientcmd .WriteToFile (cacheServerKubeConfig , cacheKubeconfigPath ); err != nil {
177+ return nil , "" , err
144178 }
145179
146- cacheServerKubeConfig , err := clientcmd .LoadFromFile (cacheKubeconfigPath )
180+ loadedKubeConfig , err := clientcmd .LoadFromFile (cacheKubeconfigPath )
147181 if err != nil {
148182 return nil , "" , err
149183 }
150- cacheClientConfig := clientcmd .NewNonInteractiveClientConfig (* cacheServerKubeConfig , "cache" , nil , nil )
184+ cacheClientConfig := clientcmd .NewNonInteractiveClientConfig (* loadedKubeConfig , "cache" , nil , nil )
151185 cacheClientRestConfig , err := cacheClientConfig .ClientConfig ()
152186 if err != nil {
153187 return nil , "" , err
0 commit comments