1
16
17 package kubeconfig
18
19 import (
20 "fmt"
21 "os"
22
23 "github.com/pkg/errors"
24
25 clientset "k8s.io/client-go/kubernetes"
26 "k8s.io/client-go/tools/clientcmd"
27 clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
28 )
29
30
31 func CreateBasic(serverURL, clusterName, userName string, caCert []byte) *clientcmdapi.Config {
32
33 contextName := fmt.Sprintf("%s@%s", userName, clusterName)
34
35 return &clientcmdapi.Config{
36 Clusters: map[string]*clientcmdapi.Cluster{
37 clusterName: {
38 Server: serverURL,
39 CertificateAuthorityData: caCert,
40 },
41 },
42 Contexts: map[string]*clientcmdapi.Context{
43 contextName: {
44 Cluster: clusterName,
45 AuthInfo: userName,
46 },
47 },
48 AuthInfos: map[string]*clientcmdapi.AuthInfo{},
49 CurrentContext: contextName,
50 }
51 }
52
53
54 func CreateWithCerts(serverURL, clusterName, userName string, caCert []byte, clientKey []byte, clientCert []byte) *clientcmdapi.Config {
55 config := CreateBasic(serverURL, clusterName, userName, caCert)
56 config.AuthInfos[userName] = &clientcmdapi.AuthInfo{
57 ClientKeyData: clientKey,
58 ClientCertificateData: clientCert,
59 }
60 return config
61 }
62
63
64 func CreateWithToken(serverURL, clusterName, userName string, caCert []byte, token string) *clientcmdapi.Config {
65 config := CreateBasic(serverURL, clusterName, userName, caCert)
66 config.AuthInfos[userName] = &clientcmdapi.AuthInfo{
67 Token: token,
68 }
69 return config
70 }
71
72
73 func ClientSetFromFile(path string) (clientset.Interface, error) {
74 config, err := clientcmd.LoadFromFile(path)
75 if err != nil {
76 return nil, errors.Wrap(err, "failed to load admin kubeconfig")
77 }
78 return ToClientSet(config)
79 }
80
81
82 func ToClientSet(config *clientcmdapi.Config) (clientset.Interface, error) {
83 overrides := clientcmd.ConfigOverrides{Timeout: "10s"}
84 clientConfig, err := clientcmd.NewDefaultClientConfig(*config, &overrides).ClientConfig()
85 if err != nil {
86 return nil, errors.Wrap(err, "failed to create API client configuration from kubeconfig")
87 }
88
89 client, err := clientset.NewForConfig(clientConfig)
90 if err != nil {
91 return nil, errors.Wrap(err, "failed to create API client")
92 }
93 return client, nil
94 }
95
96
97 func WriteToDisk(filename string, kubeconfig *clientcmdapi.Config) error {
98 err := clientcmd.WriteToFile(*kubeconfig, filename)
99 if err != nil {
100 return err
101 }
102
103 return nil
104 }
105
106
107 func GetClusterFromKubeConfig(config *clientcmdapi.Config) (string, *clientcmdapi.Cluster) {
108
109 if config.Clusters[""] != nil {
110 return "", config.Clusters[""]
111 }
112
113 currentContext := config.Contexts[config.CurrentContext]
114 if currentContext != nil {
115 return currentContext.Cluster, config.Clusters[currentContext.Cluster]
116 }
117 return "", nil
118 }
119
120
121
122 func HasAuthenticationCredentials(config *clientcmdapi.Config) bool {
123 authInfo := getCurrentAuthInfo(config)
124 if authInfo == nil {
125 return false
126 }
127
128
129 if len(authInfo.Token) != 0 || len(authInfo.TokenFile) != 0 {
130 return true
131 }
132
133
134 if len(authInfo.Username) != 0 && len(authInfo.Password) != 0 {
135 return true
136 }
137
138
139 if (len(authInfo.ClientCertificate) != 0 || len(authInfo.ClientCertificateData) != 0) &&
140 (len(authInfo.ClientKey) != 0 || len(authInfo.ClientKeyData) != 0) {
141 return true
142 }
143
144
145 if authInfo.Exec != nil && len(authInfo.Exec.Command) != 0 {
146 return true
147 }
148
149
150 if authInfo.AuthProvider != nil && len(authInfo.AuthProvider.Name) != 0 {
151 return true
152 }
153
154 return false
155 }
156
157
158
159 func EnsureAuthenticationInfoAreEmbedded(config *clientcmdapi.Config) error {
160 authInfo := getCurrentAuthInfo(config)
161 if authInfo == nil {
162 return errors.New("invalid kubeconfig file. AuthInfo is not defined for the current user")
163 }
164
165 if len(authInfo.ClientCertificateData) == 0 && len(authInfo.ClientCertificate) != 0 {
166 clientCert, err := os.ReadFile(authInfo.ClientCertificate)
167 if err != nil {
168 return errors.Wrap(err, "error while reading client cert file defined in kubeconfig")
169 }
170 authInfo.ClientCertificateData = clientCert
171 authInfo.ClientCertificate = ""
172 }
173 if len(authInfo.ClientKeyData) == 0 && len(authInfo.ClientKey) != 0 {
174 clientKey, err := os.ReadFile(authInfo.ClientKey)
175 if err != nil {
176 return errors.Wrap(err, "error while reading client key file defined in kubeconfig")
177 }
178 authInfo.ClientKeyData = clientKey
179 authInfo.ClientKey = ""
180 }
181 if len(authInfo.Token) == 0 && len(authInfo.TokenFile) != 0 {
182 tokenBytes, err := os.ReadFile(authInfo.TokenFile)
183 if err != nil {
184 return errors.Wrap(err, "error while reading token file defined in kubeconfig")
185 }
186 authInfo.Token = string(tokenBytes)
187 authInfo.TokenFile = ""
188 }
189
190 return nil
191 }
192
193
194
195 func EnsureCertificateAuthorityIsEmbedded(cluster *clientcmdapi.Cluster) error {
196 if cluster == nil {
197 return errors.New("received nil value for Cluster")
198 }
199
200 if len(cluster.CertificateAuthorityData) == 0 && len(cluster.CertificateAuthority) != 0 {
201 ca, err := os.ReadFile(cluster.CertificateAuthority)
202 if err != nil {
203 return errors.Wrap(err, "error while reading certificate authority file defined in kubeconfig")
204 }
205 cluster.CertificateAuthorityData = ca
206 cluster.CertificateAuthority = ""
207 }
208
209 return nil
210 }
211
212
213 func getCurrentAuthInfo(config *clientcmdapi.Config) *clientcmdapi.AuthInfo {
214 if config == nil || config.CurrentContext == "" ||
215 len(config.Contexts) == 0 || config.Contexts[config.CurrentContext] == nil {
216 return nil
217 }
218 user := config.Contexts[config.CurrentContext].AuthInfo
219
220 if user == "" || len(config.AuthInfos) == 0 || config.AuthInfos[user] == nil {
221 return nil
222 }
223
224 return config.AuthInfos[user]
225 }
226
View as plain text