Skip to content

Commit f7fae36

Browse files
committed
change the Kubernetes connection method
1 parent a02b29c commit f7fae36

File tree

4 files changed

+51
-24
lines changed

4 files changed

+51
-24
lines changed

README.md

+1-2
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,12 @@ This is just a small program that can be used to create and approve a Client Sig
44

55
The code is heavily based on [this article](https://medium.com/@elfakharany/automate-kubernetes-user-creation-using-the-native-go-client-e2d20dcdc9de) with some modifications for new CSR API versions and things I needed for this example. Setting `expirationSeconds` will add that to the CSR. Kubernetes servers tend to have upper limits for how long they'll issue a certificate for (although these times vary wildly), and generally `600` is the lower bound for what you can set.
66

7-
It connects to a cluster based on the current context in a provided Kubeconfig file. If no file is provided then $HOME/.kube/config is used.
7+
It connects to a cluster based on the current Kubernetes context for the running user.
88

99
There are five command line parameters :-
1010

1111
* `--username` - The username for the certificate. (MANDATORY)
1212
* `--group` - The group for the certificate. Defaults to none. (OPTIONAL)
13-
* `--kubeconfig` - The kubeconfig to use to connect to the cluster. Default is `$HOME/.kube/config` (OPTIONAL)
1413
* `--output-file` - Filename for the output kubeconfig file. Default is [username].config (OPTIONAL)
1514
* `--expirationSeconds` - Number of seconds for the certificate to be valid. If not specified this will take the server's default setting. (OPTIONAL)
1615

go.mod

+12-3
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,22 @@ go 1.18
44

55
require (
66
gopkg.in/yaml.v2 v2.4.0
7-
k8s.io/api v0.24.3
7+
k8s.io/api v0.24.4
88
)
99

1010
require (
11+
cloud.google.com/go v0.81.0 // indirect
12+
github.com/Azure/go-autorest v14.2.0+incompatible // indirect
13+
github.com/Azure/go-autorest/autorest v0.11.18 // indirect
14+
github.com/Azure/go-autorest/autorest/adal v0.9.13 // indirect
15+
github.com/Azure/go-autorest/autorest/date v0.3.0 // indirect
16+
github.com/Azure/go-autorest/logger v0.2.1 // indirect
17+
github.com/Azure/go-autorest/tracing v0.6.0 // indirect
1118
github.com/PuerkitoBio/purell v1.1.1 // indirect
1219
github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578 // indirect
1320
github.com/davecgh/go-spew v1.1.1 // indirect
1421
github.com/emicklei/go-restful v2.9.5+incompatible // indirect
22+
github.com/form3tech-oss/jwt-go v3.2.3+incompatible // indirect
1523
github.com/go-openapi/jsonpointer v0.19.5 // indirect
1624
github.com/go-openapi/jsonreference v0.19.5 // indirect
1725
github.com/go-openapi/swag v0.19.14 // indirect
@@ -22,6 +30,7 @@ require (
2230
github.com/mailru/easyjson v0.7.6 // indirect
2331
github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822 // indirect
2432
github.com/spf13/pflag v1.0.5 // indirect
33+
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 // indirect
2534
golang.org/x/oauth2 v0.0.0-20211104180415-d3ed0bb246c8 // indirect
2635
golang.org/x/sys v0.0.0-20220209214540-3681064d5158 // indirect
2736
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211 // indirect
@@ -43,8 +52,8 @@ require (
4352
golang.org/x/net v0.0.0-20220127200216-cd36cc0744dd // indirect
4453
golang.org/x/text v0.3.7 // indirect
4554
gopkg.in/inf.v0 v0.9.1 // indirect
46-
k8s.io/apimachinery v0.24.3
47-
k8s.io/client-go v0.24.3
55+
k8s.io/apimachinery v0.24.4
56+
k8s.io/client-go v0.24.4
4857
k8s.io/klog/v2 v2.60.1 // indirect
4958
k8s.io/utils v0.0.0-20220210201930-3a6ce19ff2f9 // indirect
5059
sigs.k8s.io/json v0.0.0-20211208200746-9f7c6b3444d2 // indirect

go.sum

+15
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ cloud.google.com/go v0.72.0/go.mod h1:M+5Vjvlc2wnp6tjzE102Dw08nGShTscUx2nZMufOKP
1717
cloud.google.com/go v0.74.0/go.mod h1:VV1xSbzvo+9QJOxLDaJfTjx5e+MePCpCWwvftOeQmWk=
1818
cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECHg=
1919
cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8=
20+
cloud.google.com/go v0.81.0 h1:at8Tk2zUz63cLPR0JPWm5vp77pEZmzxEQBEfRKn1VV8=
2021
cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0=
2122
cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o=
2223
cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE=
@@ -36,12 +37,18 @@ cloud.google.com/go/storage v1.6.0/go.mod h1:N7U0C8pVQ/+NIKOBQyamJIeKQKkZ+mxpohl
3637
cloud.google.com/go/storage v1.8.0/go.mod h1:Wv1Oy7z6Yz3DshWRJFhqM/UCfaWIRTdp0RXyy7KQOVs=
3738
cloud.google.com/go/storage v1.10.0/go.mod h1:FLPqc6j+Ki4BU591ie1oL6qBQGu2Bl/tZ9ullr3+Kg0=
3839
dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU=
40+
github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
3941
github.com/Azure/go-autorest v14.2.0+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
42+
github.com/Azure/go-autorest/autorest v0.11.18 h1:90Y4srNYrwOtAgVo3ndrQkTYn6kf1Eg/AjTFJ8Is2aM=
4043
github.com/Azure/go-autorest/autorest v0.11.18/go.mod h1:dSiJPy22c3u0OtOKDNttNgqpNFY/GeWa7GH/Pz56QRA=
44+
github.com/Azure/go-autorest/autorest/adal v0.9.13 h1:Mp5hbtOePIzM8pJVRa3YLrWWmZtoxRXqUEzCfJt3+/Q=
4145
github.com/Azure/go-autorest/autorest/adal v0.9.13/go.mod h1:W/MM4U6nLxnIskrw4UwWzlHfGjwUS50aOsc/I3yuU8M=
46+
github.com/Azure/go-autorest/autorest/date v0.3.0 h1:7gUk1U5M/CQbp9WoqinNzJar+8KY+LPI6wiWrP/myHw=
4247
github.com/Azure/go-autorest/autorest/date v0.3.0/go.mod h1:BI0uouVdmngYNUzGWeSYnokU+TrmwEsOqdt8Y6sso74=
4348
github.com/Azure/go-autorest/autorest/mocks v0.4.1/go.mod h1:LTp+uSrOhSkaKrUy935gNZuuIPPVsHlr9DSOxSayd+k=
49+
github.com/Azure/go-autorest/logger v0.2.1 h1:IG7i4p/mDa2Ce4TRyAO8IHnVhAVF3RFU+ZtXWSmf4Tg=
4450
github.com/Azure/go-autorest/logger v0.2.1/go.mod h1:T9E3cAhj2VqvPOtCYAvby9aBXkZmbF5NWuPV8+WeEW8=
51+
github.com/Azure/go-autorest/tracing v0.6.0 h1:TYi4+3m5t6K48TGI9AUdb+IzbnSxvnvUMfuitfgcfuo=
4552
github.com/Azure/go-autorest/tracing v0.6.0/go.mod h1:+vhtPC754Xsa23ID7GlGsrdKBpUA79WCAKPPZVC2DeU=
4653
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
4754
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
@@ -77,6 +84,7 @@ github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.m
7784
github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c=
7885
github.com/evanphx/json-patch v4.12.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
7986
github.com/form3tech-oss/jwt-go v3.2.2+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
87+
github.com/form3tech-oss/jwt-go v3.2.3+incompatible h1:7ZaBxOI7TMoYBfyA3cQHErNNyAWIKUMIwqxEtgHOs5c=
8088
github.com/form3tech-oss/jwt-go v3.2.3+incompatible/go.mod h1:pbq4aXjuKjdthFRnoDwaVPLA+WlJuPGy+QneDUgJi2k=
8189
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
8290
github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
@@ -259,6 +267,7 @@ golang.org/x/crypto v0.0.0-20190605123033-f99c8df09eb5/go.mod h1:yigFU9vqHzYiE8U
259267
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
260268
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
261269
golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
270+
golang.org/x/crypto v0.0.0-20220214200702-86341886e292 h1:f+lwQ+GtmgoY+A2YaQxlSOnDjXcQ7ZRLWOHbC6HtRqE=
262271
golang.org/x/crypto v0.0.0-20220214200702-86341886e292/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
263272
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
264273
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
@@ -610,10 +619,16 @@ honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9
610619
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
611620
k8s.io/api v0.24.3 h1:tt55QEmKd6L2k5DP6G/ZzdMQKvG5ro4H4teClqm0sTY=
612621
k8s.io/api v0.24.3/go.mod h1:elGR/XSZrS7z7cSZPzVWaycpJuGIw57j9b95/1PdJNI=
622+
k8s.io/api v0.24.4 h1:I5Y645gJ8zWKawyr78lVfDQkZrAViSbeRXsPZWTxmXk=
623+
k8s.io/api v0.24.4/go.mod h1:42pVfA0NRxrtJhZQOvRSyZcJihzAdU59WBtTjYcB0/M=
613624
k8s.io/apimachinery v0.24.3 h1:hrFiNSA2cBZqllakVYyH/VyEh4B581bQRmqATJSeQTg=
614625
k8s.io/apimachinery v0.24.3/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
626+
k8s.io/apimachinery v0.24.4 h1:S0Ur3J/PbivTcL43EdSdPhqCqKla2NIuneNwZcTDeGQ=
627+
k8s.io/apimachinery v0.24.4/go.mod h1:82Bi4sCzVBdpYjyI4jY6aHX+YCUchUIrZrXKedjd2UM=
615628
k8s.io/client-go v0.24.3 h1:Nl1840+6p4JqkFWEW2LnMKU667BUxw03REfLAVhuKQY=
616629
k8s.io/client-go v0.24.3/go.mod h1:AAovolf5Z9bY1wIg2FZ8LPQlEdKHjLI7ZD4rw920BJw=
630+
k8s.io/client-go v0.24.4 h1:hIAIJZIPyaw46AkxwyR0FRfM/pRxpUNTd3ysYu9vyRg=
631+
k8s.io/client-go v0.24.4/go.mod h1:+AxlPWw/H6f+EJhRSjIeALaJT4tbeB/8g9BNvXGPd0Y=
617632
k8s.io/gengo v0.0.0-20210813121822-485abfe95c7c/go.mod h1:FiNAH4ZV3gBg2Kwh89tzAEV2be7d5xI0vBa/VySYy3E=
618633
k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
619634
k8s.io/klog/v2 v2.2.0/go.mod h1:Od+F08eJP+W3HUb4pSrPpgp9DGU4GzlpG/TmITuYh/Y=

main.go

+23-19
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ import (
2424
v1core "k8s.io/api/core/v1"
2525
v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
2626
"k8s.io/client-go/kubernetes"
27+
_ "k8s.io/client-go/plugin/pkg/client/auth"
2728
"k8s.io/client-go/tools/clientcmd"
2829
)
2930

@@ -74,26 +75,25 @@ type KubeConfig struct {
7475
Users Users `yaml:"users"`
7576
}
7677

77-
func connectToCluster(kubeconfig string) *kubernetes.Clientset {
78-
config, err := clientcmd.BuildConfigFromFlags("", kubeconfig)
78+
func initKubeClient() (*kubernetes.Clientset, clientcmd.ClientConfig, error) {
79+
loadingRules := clientcmd.NewDefaultClientConfigLoadingRules()
80+
kubeConfig := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(loadingRules, &clientcmd.ConfigOverrides{})
81+
config, err := kubeConfig.ClientConfig()
7982
if err != nil {
80-
fmt.Println("Error creating config object")
81-
log.Fatal(err)
83+
log.Fatal("initKubeClient: failed creating ClientConfig with", err)
84+
return nil, nil, err
8285
}
8386
clientset, err := kubernetes.NewForConfig(config)
8487
if err != nil {
85-
fmt.Println("Error creating clientset")
86-
log.Fatal(err)
88+
log.Fatal("initKubeClient: failed creating Clientset with", err)
89+
return nil, nil, err
8790
}
88-
return clientset
91+
return clientset, kubeConfig, nil
8992
}
9093

9194
func main() {
9295
commonName := flag.String("username", "", "Username to generate certificate for")
9396
org := flag.String("group", "", "Group to assign to certificate")
94-
homedir, _ := os.UserHomeDir()
95-
defaultkubeconfig := homedir + "/.kube/config"
96-
kubeconfig := flag.String("kubeconfig", defaultkubeconfig, "Kubeconfig file")
9797
outputFile := flag.String("output-file", "", "File to output Kubeconfig to")
9898
expirationSeconds := flag.Int("expiration-seconds", 0, "Seconds till the certificate expires")
9999
flag.Parse()
@@ -134,7 +134,11 @@ func main() {
134134
log.Fatal(fmt.Printf("Error %s", err))
135135
}
136136

137-
clientset := connectToCluster(*kubeconfig)
137+
clientset, config, err := initKubeClient()
138+
if err != nil {
139+
fmt.Println("Error initializing Kubernetes client")
140+
log.Fatal(fmt.Printf("Error %s", err))
141+
}
138142
csr := &certificates.CertificateSigningRequest{
139143
ObjectMeta: v1.ObjectMeta{
140144
Name: "tempcsr",
@@ -191,20 +195,20 @@ func main() {
191195
}
192196
fmt.Printf("Certificate Successfully issued to username %s in group %s , signed by %s, valid until %s\n", issued_cert.Subject.CommonName, issued_group, issued_cert.Issuer.CommonName, issued_cert.NotAfter.String())
193197

194-
config, _ := clientcmd.NewNonInteractiveDeferredLoadingClientConfig(
195-
&clientcmd.ClientConfigLoadingRules{ExplicitPath: *kubeconfig},
196-
&clientcmd.ConfigOverrides{
197-
CurrentContext: "",
198-
}).RawConfig()
199-
cluster := config.Contexts[config.CurrentContext].Cluster
198+
raw, err := config.RawConfig()
199+
if err != nil {
200+
fmt.Println("error getting raw config")
201+
log.Fatal(err)
202+
}
203+
cluster := raw.Contexts[raw.CurrentContext].Cluster
200204

201205
kc := &KubeConfig{
202206
APIVersion: "v1",
203207
Clusters: Clusters{
204208
0: {
205209
Cluster{
206-
base64.StdEncoding.EncodeToString([]byte(config.Clusters[cluster].CertificateAuthorityData)),
207-
config.Clusters[cluster].Server,
210+
base64.StdEncoding.EncodeToString([]byte(raw.Clusters[cluster].CertificateAuthorityData)),
211+
raw.Clusters[cluster].Server,
208212
},
209213
cluster,
210214
},

0 commit comments

Comments
 (0)