@@ -17,14 +17,15 @@ limitations under the License.
1717package util
1818
1919import (
20+ "context"
2021 "fmt"
2122 "net/http"
2223 "net/url"
2324 "strings"
2425 "sync"
26+ "time"
2527
2628 "k8s.io/apimachinery/pkg/util/validation/field"
27- "k8s.io/cli-runtime/pkg/genericclioptions"
2829 "k8s.io/client-go/dynamic"
2930 "k8s.io/client-go/rest"
3031 "k8s.io/client-go/tools/clientcmd"
@@ -36,6 +37,8 @@ import (
3637 "k8s.io/kops/pkg/client/simple"
3738 "k8s.io/kops/pkg/client/simple/api"
3839 "k8s.io/kops/pkg/client/simple/vfsclientset"
40+ "k8s.io/kops/pkg/kubeconfig"
41+ "k8s.io/kops/upup/pkg/fi/cloudup"
3942 "k8s.io/kops/util/pkg/vfs"
4043)
4144
@@ -57,7 +60,8 @@ type Factory struct {
5760
5861// clusterInfo holds REST connection configuration for connecting to a cluster
5962type clusterInfo struct {
60- clusterName string
63+ factory * Factory
64+ cluster * kops.Cluster
6165
6266 cachedHTTPClient * http.Client
6367 cachedRESTConfig * rest.Config
@@ -155,48 +159,47 @@ func (f *Factory) KopsStateStore() string {
155159 return f .options .RegistryPath
156160}
157161
158- func (f * Factory ) getClusterInfo (clusterName string ) * clusterInfo {
162+ func (f * Factory ) getClusterInfo (cluster * kops. Cluster ) * clusterInfo {
159163 f .mutex .Lock ()
160164 defer f .mutex .Unlock ()
161165
162- if clusterInfo , ok := f .clusters [clusterName ]; ok {
166+ key := cluster .ObjectMeta .Name
167+ if clusterInfo , ok := f .clusters [key ]; ok {
163168 return clusterInfo
164169 }
165- clusterInfo := & clusterInfo {}
166- f .clusters [clusterName ] = clusterInfo
170+ clusterInfo := & clusterInfo {
171+ factory : f ,
172+ cluster : cluster ,
173+ }
174+ f .clusters [key ] = clusterInfo
167175 return clusterInfo
168176}
169177
170178func (f * Factory ) RESTConfig (cluster * kops.Cluster ) (* rest.Config , error ) {
171- clusterInfo := f .getClusterInfo (cluster . ObjectMeta . Name )
179+ clusterInfo := f .getClusterInfo (cluster )
172180 return clusterInfo .RESTConfig ()
173181}
174182
175183func (f * clusterInfo ) RESTConfig () (* rest.Config , error ) {
176- if f .cachedRESTConfig == nil {
177- // Get the kubeconfig from the context
178-
179- clientGetter := genericclioptions .NewConfigFlags (true )
180- if f .clusterName != "" {
181- contextName := f .clusterName
182- clientGetter .Context = & contextName
183- }
184+ ctx := context .Background ()
184185
185- restConfig , err := clientGetter .ToRESTConfig ()
186+ if f .cachedRESTConfig == nil {
187+ restConfig , err := f .factory .buildRESTConfig (ctx , f .cluster )
186188 if err != nil {
187- return nil , fmt . Errorf ( "loading kubecfg settings for %q: %w" , f . clusterName , err )
189+ return nil , err
188190 }
189191
190192 restConfig .UserAgent = "kops"
191193 restConfig .Burst = 50
192194 restConfig .QPS = 20
195+
193196 f .cachedRESTConfig = restConfig
194197 }
195198 return f .cachedRESTConfig , nil
196199}
197200
198201func (f * Factory ) HTTPClient (cluster * kops.Cluster ) (* http.Client , error ) {
199- clusterInfo := f .getClusterInfo (cluster . ObjectMeta . Name )
202+ clusterInfo := f .getClusterInfo (cluster )
200203 return clusterInfo .HTTPClient ()
201204}
202205
@@ -216,8 +219,8 @@ func (f *clusterInfo) HTTPClient() (*http.Client, error) {
216219}
217220
218221// DynamicClient returns a dynamic client
219- func (f * Factory ) DynamicClient (clusterName string ) (dynamic.Interface , error ) {
220- clusterInfo := f .getClusterInfo (clusterName )
222+ func (f * Factory ) DynamicClient (cluster * kops. Cluster ) (dynamic.Interface , error ) {
223+ clusterInfo := f .getClusterInfo (cluster )
221224 return clusterInfo .DynamicClient ()
222225}
223226
@@ -249,3 +252,44 @@ func (f *Factory) VFSContext() *vfs.VFSContext {
249252 }
250253 return f .vfsContext
251254}
255+
256+ func (f * Factory ) buildRESTConfig (ctx context.Context , cluster * kops.Cluster ) (* rest.Config , error ) {
257+ clientset , err := f .KopsClient ()
258+ if err != nil {
259+ return nil , err
260+ }
261+
262+ keyStore , err := clientset .KeyStore (cluster )
263+ if err != nil {
264+ return nil , err
265+ }
266+
267+ secretStore , err := clientset .SecretStore (cluster )
268+ if err != nil {
269+ return nil , err
270+ }
271+
272+ cloud , err := cloudup .BuildCloud (cluster )
273+ if err != nil {
274+ return nil , err
275+ }
276+
277+ // Generate a relatively short-lived certificate / kubeconfig
278+ createKubecfgOptions := kubeconfig.CreateKubecfgOptions {
279+ Admin : 1 * time .Hour ,
280+ }
281+
282+ conf , err := kubeconfig .BuildKubecfg (
283+ ctx ,
284+ cluster ,
285+ keyStore ,
286+ secretStore ,
287+ cloud ,
288+ createKubecfgOptions ,
289+ f .KopsStateStore ())
290+ if err != nil {
291+ return nil , err
292+ }
293+
294+ return conf .ToRESTConfig ()
295+ }
0 commit comments