@@ -6,151 +6,127 @@ package cmd
6
6
7
7
import (
8
8
"context"
9
- "fmt"
9
+ "os"
10
+ "path/filepath"
10
11
11
12
"github.com/cockroachdb/errors"
13
+ kctx "github.com/gitpod-io/gitpod/previewctl/pkg/k8s/context"
14
+ "github.com/gitpod-io/gitpod/previewctl/pkg/k8s/context/gke"
15
+ "github.com/gitpod-io/gitpod/previewctl/pkg/k8s/context/harvester"
12
16
"github.com/sirupsen/logrus"
13
17
"github.com/spf13/cobra"
14
18
"k8s.io/client-go/tools/clientcmd"
15
19
"k8s.io/client-go/tools/clientcmd/api"
20
+ "k8s.io/client-go/util/homedir"
16
21
17
- "github.com/gitpod-io/gitpod/previewctl/pkg/gcloud"
18
22
kube "github.com/gitpod-io/gitpod/previewctl/pkg/k8s"
19
23
)
20
24
21
25
var (
22
- serviceAccountPath string
23
- kubeConfigSavePath string
26
+ DefaultKubeConfigPath = filepath .Join (homedir .HomeDir (), clientcmd .RecommendedHomeDir , clientcmd .RecommendedFileName )
24
27
)
25
28
26
29
const (
27
- coreDevClusterName = "core-dev"
28
- coreDevProjectID = "gitpod-core-dev"
29
- coreDevClusterZone = "europe-west1-b"
30
- coreDevDesiredContextName = "dev"
30
+ coreDevClusterName = "core-dev"
31
+ coreDevProjectID = "gitpod-core-dev"
32
+ coreDevClusterZone = "europe-west1-b"
31
33
)
32
34
33
35
type getCredentialsOpts struct {
34
- gcpClient * gcloud.Config
35
- logger * logrus.Logger
36
+ logger * logrus.Logger
36
37
37
- getCredentialsMap map [ string ] func ( ctx context. Context ) ( * api. Config , error )
38
- configMap map [ string ] * api. Config
38
+ serviceAccountPath string
39
+ kubeConfigSavePath string
39
40
}
40
41
41
42
func newGetCredentialsCommand (logger * logrus.Logger ) * cobra.Command {
42
- var err error
43
- var client * gcloud.Config
44
43
ctx := context .Background ()
45
44
opts := & getCredentialsOpts {
46
- logger : logger ,
47
- configMap : map [string ]* api.Config {},
45
+ logger : logger ,
48
46
}
49
47
50
48
cmd := & cobra.Command {
51
49
Use : "get-credentials" ,
52
50
Long : `previewctl get-credentials retrieves the kubernetes configs for core-dev and harvester clusters,
53
- merges them with the default config, and outputs them either to stdout or to a file. ` ,
54
- PersistentPreRunE : func (cmd * cobra.Command , args []string ) error {
55
- client , err = gcloud . New (ctx , serviceAccountPath )
51
+ merges them with the default config, and saves them to the path in KUBECONFIG or the default path '~/.kube/config'" ` ,
52
+ RunE : func (cmd * cobra.Command , args []string ) error {
53
+ configs , err := opts . getCredentials (ctx )
56
54
if err != nil {
57
55
return err
58
56
}
59
57
60
- opts .gcpClient = client
61
- opts .getCredentialsMap = map [string ]func (ctx context.Context ) (* api.Config , error ){
62
- "dev" : opts .getCoreDevKubeConfig ,
63
- "harvester" : opts .getHarvesterKubeConfig ,
64
- }
65
-
66
- return nil
67
- },
68
- RunE : func (cmd * cobra.Command , args []string ) error {
69
- for _ , kc := range []string {coreDevDesiredContextName , "harvester" } {
70
- if ok := hasAccess (logger , kc ); ! ok {
71
- config , err := opts.getCredentialsMap [kc ](ctx )
72
- if err != nil {
73
- return err
74
- }
75
-
76
- opts .configMap [kc ] = config
77
- }
78
- }
79
-
80
- return opts .mergeContexts ()
58
+ opts .kubeConfigSavePath = getKubeConfigPath ()
59
+ return kube .OutputContext (opts .kubeConfigSavePath , configs )
81
60
},
82
61
}
83
62
84
- cmd .PersistentFlags ().StringVar (& serviceAccountPath , "gcp-service-account" , "" , "path to the GCP service account to use" )
85
- cmd .PersistentFlags ().StringVar (& kubeConfigSavePath , "kube-save-path" , "" , "path to save the generated kubeconfig to" )
63
+ cmd .PersistentFlags ().StringVar (& opts .serviceAccountPath , "gcp-service-account" , "" , "path to the GCP service account to use" )
86
64
87
65
return cmd
88
66
}
89
67
90
- func hasAccess (logger * logrus.Logger , contextName string ) bool {
91
- config , err := kube .NewFromDefaultConfigWithContext (logger , contextName )
92
- if err != nil {
93
- if errors .Is (err , kube .ErrContextNotExists ) {
94
- return false
95
- }
96
-
97
- logger .Fatal (err )
98
- }
99
-
100
- return config .HasAccess ()
101
- }
102
-
103
- func (o * getCredentialsOpts ) mergeContexts () error {
104
- var err error
105
- configs := make ([]* api.Config , 0 , len (o .configMap ))
106
-
107
- for _ , config := range o .configMap {
108
- configs = append (configs , config )
109
- }
68
+ func (o * getCredentialsOpts ) getCredentials (ctx context.Context ) (* api.Config , error ) {
69
+ gkeLoader , err := gke .New (ctx , gke.ConfigLoaderOpts {
70
+ Logger : o .logger ,
71
+ ServiceAccountPath : o .serviceAccountPath ,
72
+ Name : coreDevClusterName ,
73
+ ProjectID : coreDevProjectID ,
74
+ Zone : coreDevClusterZone ,
75
+ RenamedContextName : gke .DevContextName ,
76
+ })
110
77
111
- finalConfig , err := kube .MergeWithDefaultConfig (configs ... )
112
78
if err != nil {
113
- return err
79
+ return nil , errors . Wrap ( err , "failed to instantiate gke loader" )
114
80
}
115
81
116
- if kubeConfigSavePath != "" {
117
- return clientcmd .WriteToFile (* finalConfig , kubeConfigSavePath )
82
+ loaderMap := map [string ]kctx.Loader {
83
+ gke .DevContextName : gkeLoader ,
84
+ harvester .ContextName : & harvester.ConfigLoader {},
118
85
}
119
86
120
- bytes , err := clientcmd .Write (* finalConfig )
121
- if err != nil {
122
- return err
123
- }
87
+ for _ , contextName := range []string {gke .DevContextName , harvester .ContextName } {
88
+ loader := loaderMap [contextName ]
89
+ if kc , err := kube .NewFromDefaultConfigWithContext (o .logger , contextName ); err == nil && kc .HasAccess (ctx ) {
90
+ continue
91
+ }
124
92
125
- fmt .Println (string (bytes ))
93
+ kc , err := loader .Load (ctx )
94
+ if err != nil {
95
+ return nil , err
96
+ }
126
97
127
- return err
128
- }
98
+ configs , err := kube .MergeContextsWithDefault (kc )
99
+ if err != nil {
100
+ return nil , err
101
+ }
129
102
130
- func (o * getCredentialsOpts ) getCoreDevKubeConfig (ctx context.Context ) (* api.Config , error ) {
131
- coreDevConfig , err := o .gcpClient .GenerateConfig (ctx , coreDevClusterName , coreDevProjectID , coreDevClusterZone , coreDevDesiredContextName )
132
- if err != nil {
133
- return nil , err
103
+ // always save the context at the default path
104
+ err = kube .OutputContext (DefaultKubeConfigPath , configs )
105
+ if err != nil {
106
+ return nil , err
107
+ }
134
108
}
135
109
136
- return coreDevConfig , nil
110
+ return kube . MergeContextsWithDefault ()
137
111
}
138
112
139
- func ( o * getCredentialsOpts ) getHarvesterKubeConfig ( ctx context.Context ) ( * api. Config , error ) {
140
- coreDevClientConfig , err := clientcmd . NewNonInteractiveClientConfig ( * o . configMap [ coreDevDesiredContextName ], coreDevDesiredContextName , nil , nil ). ClientConfig ( )
113
+ func hasAccess ( ctx context.Context , logger * logrus. Logger , contextName string ) bool {
114
+ config , err := kube . NewFromDefaultConfigWithContext ( logger , contextName )
141
115
if err != nil {
142
- return nil , err
143
- }
116
+ if errors .Is (err , kube .ErrContextNotExists ) {
117
+ return false
118
+ }
144
119
145
- kubeConfig , err := kube .NewWithConfig (o .logger , coreDevClientConfig )
146
- if err != nil {
147
- return nil , err
120
+ logger .Fatal (err )
148
121
}
149
122
150
- harvesterConfig , err := kubeConfig .GetHarvesterKubeConfig (ctx )
151
- if err != nil {
152
- return nil , err
123
+ return config .HasAccess (ctx )
124
+ }
125
+
126
+ func getKubeConfigPath () string {
127
+ if v := os .Getenv ("KUBECONFIG" ); v != "" {
128
+ DefaultKubeConfigPath = v
153
129
}
154
130
155
- return harvesterConfig , nil
131
+ return DefaultKubeConfigPath
156
132
}
0 commit comments