@@ -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
48
+ setDefaultKubeConfigPath ()
49
+
50
50
cmd := & cobra.Command {
51
51
Use : "get-credentials" ,
52
52
Long : `previewctl get-credentials retrieves the kubernetes configs for core-dev and harvester clusters,
53
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 )
54
+ RunE : func (cmd * cobra.Command , args []string ) error {
55
+ configs , err := opts . getCredentials (ctx )
56
56
if err != nil {
57
57
return err
58
58
}
59
59
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 ()
60
+ return kube .OutputContext (opts .kubeConfigSavePath , configs )
81
61
},
82
62
}
83
63
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" )
64
+ cmd .PersistentFlags ().StringVar (& opts . serviceAccountPath , "gcp-service-account" , "" , "path to the GCP service account to use" )
65
+ cmd .PersistentFlags ().StringVar (& opts . kubeConfigSavePath , "kube-save-path" , DefaultKubeConfigPath , "path to save the generated kubeconfig to" )
86
66
87
67
return cmd
88
68
}
89
69
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
- }
70
+ func (o * getCredentialsOpts ) getCredentials (ctx context.Context ) (* api.Config , error ) {
71
+ gkeLoader , err := gke .New (ctx , gke.ConfigLoaderOpts {
72
+ Logger : o .logger ,
73
+ ServiceAccountPath : o .serviceAccountPath ,
74
+ Name : coreDevClusterName ,
75
+ ProjectID : coreDevProjectID ,
76
+ Zone : coreDevClusterZone ,
77
+ RenamedContextName : gke .DevContextName ,
78
+ })
110
79
111
- finalConfig , err := kube .MergeWithDefaultConfig (configs ... )
112
80
if err != nil {
113
- return err
81
+ return nil , errors . Wrap ( err , "failed to instantiate gke loader" )
114
82
}
115
83
116
- if kubeConfigSavePath != "" {
117
- return clientcmd .WriteToFile (* finalConfig , kubeConfigSavePath )
84
+ loaderMap := map [string ]kctx.Loader {
85
+ gke .DevContextName : gkeLoader ,
86
+ harvester .ContextName : & harvester.ConfigLoader {},
118
87
}
119
88
120
- bytes , err := clientcmd .Write (* finalConfig )
121
- if err != nil {
122
- return err
123
- }
89
+ for _ , contextName := range []string {gke .DevContextName , harvester .ContextName } {
90
+ loader := loaderMap [contextName ]
91
+ if kc , err := kube .NewFromDefaultConfigWithContext (o .logger , contextName ); err == nil && kc .HasAccess (ctx ) {
92
+ continue
93
+ }
124
94
125
- fmt .Println (string (bytes ))
95
+ kc , err := loader .Load (ctx )
96
+ if err != nil {
97
+ return nil , err
98
+ }
126
99
127
- return err
128
- }
100
+ configs , err := kube .MergeContextsWithDefault (kc )
101
+ if err != nil {
102
+ return nil , err
103
+ }
129
104
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
105
+ // always save the context at the default path
106
+ err = kube .OutputContext (DefaultKubeConfigPath , configs )
107
+ if err != nil {
108
+ return nil , err
109
+ }
134
110
}
135
111
136
- return coreDevConfig , nil
112
+ return kube . MergeContextsWithDefault ()
137
113
}
138
114
139
- func ( o * getCredentialsOpts ) getHarvesterKubeConfig ( ctx context.Context ) ( * api. Config , error ) {
140
- coreDevClientConfig , err := clientcmd . NewNonInteractiveClientConfig ( * o . configMap [ coreDevDesiredContextName ], coreDevDesiredContextName , nil , nil ). ClientConfig ( )
115
+ func hasAccess ( ctx context.Context , logger * logrus. Logger , contextName string ) bool {
116
+ config , err := kube . NewFromDefaultConfigWithContext ( logger , contextName )
141
117
if err != nil {
142
- return nil , err
143
- }
118
+ if errors .Is (err , kube .ErrContextNotExists ) {
119
+ return false
120
+ }
144
121
145
- kubeConfig , err := kube .NewWithConfig (o .logger , coreDevClientConfig )
146
- if err != nil {
147
- return nil , err
122
+ logger .Fatal (err )
148
123
}
149
124
150
- harvesterConfig , err := kubeConfig .GetHarvesterKubeConfig (ctx )
151
- if err != nil {
152
- return nil , err
153
- }
125
+ return config .HasAccess (ctx )
126
+ }
154
127
155
- return harvesterConfig , nil
128
+ func setDefaultKubeConfigPath () {
129
+ if v := os .Getenv ("KUBECONFIG" ); v != "" {
130
+ DefaultKubeConfigPath = v
131
+ }
156
132
}
0 commit comments