kubeconfig_test.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. /*
  2. Copyright 2017 The Kubernetes Authors.
  3. Licensed under the Apache License, Version 2.0 (the "License");
  4. you may not use this file except in compliance with the License.
  5. You may obtain a copy of the License at
  6. http://www.apache.org/licenses/LICENSE-2.0
  7. Unless required by applicable law or agreed to in writing, software
  8. distributed under the License is distributed on an "AS IS" BASIS,
  9. WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. See the License for the specific language governing permissions and
  11. limitations under the License.
  12. */
  13. package kubeconfig
  14. import (
  15. "bytes"
  16. "fmt"
  17. "io/ioutil"
  18. "os"
  19. "testing"
  20. clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
  21. )
  22. const (
  23. configOut1 = `apiVersion: v1
  24. clusters:
  25. - cluster:
  26. server: ""
  27. name: k8s
  28. contexts:
  29. - context:
  30. cluster: k8s
  31. user: user1
  32. name: user1@k8s
  33. current-context: user1@k8s
  34. kind: Config
  35. preferences: {}
  36. users:
  37. - name: user1
  38. user:
  39. token: abc
  40. `
  41. configOut2 = `apiVersion: v1
  42. clusters:
  43. - cluster:
  44. server: localhost:8080
  45. name: kubernetes
  46. contexts:
  47. - context:
  48. cluster: kubernetes
  49. user: user2
  50. name: user2@kubernetes
  51. current-context: user2@kubernetes
  52. kind: Config
  53. preferences: {}
  54. users:
  55. - name: user2
  56. user:
  57. token: cba
  58. `
  59. )
  60. type configClient struct {
  61. clusterName string
  62. userName string
  63. serverURL string
  64. caCert []byte
  65. }
  66. type configClientWithCerts struct {
  67. clientKey []byte
  68. clientCert []byte
  69. }
  70. type configClientWithToken struct {
  71. token string
  72. }
  73. func TestCreateWithCerts(t *testing.T) {
  74. var createBasicTest = []struct {
  75. name string
  76. cc configClient
  77. ccWithCerts configClientWithCerts
  78. expected string
  79. }{
  80. {"empty config", configClient{}, configClientWithCerts{}, ""},
  81. {"clusterName kubernetes", configClient{clusterName: "kubernetes"}, configClientWithCerts{}, ""},
  82. }
  83. for _, rt := range createBasicTest {
  84. t.Run(rt.name, func(t *testing.T) {
  85. cwc := CreateWithCerts(
  86. rt.cc.serverURL,
  87. rt.cc.clusterName,
  88. rt.cc.userName,
  89. rt.cc.caCert,
  90. rt.ccWithCerts.clientKey,
  91. rt.ccWithCerts.clientCert,
  92. )
  93. if cwc.Kind != rt.expected {
  94. t.Errorf(
  95. "failed CreateWithCerts:\n\texpected: %s\n\t actual: %s",
  96. rt.expected,
  97. cwc.Kind,
  98. )
  99. }
  100. })
  101. }
  102. }
  103. func TestCreateWithToken(t *testing.T) {
  104. var createBasicTest = []struct {
  105. name string
  106. cc configClient
  107. ccWithToken configClientWithToken
  108. expected string
  109. }{
  110. {"empty config", configClient{}, configClientWithToken{}, ""},
  111. {"clusterName kubernetes", configClient{clusterName: "kubernetes"}, configClientWithToken{}, ""},
  112. }
  113. for _, rt := range createBasicTest {
  114. t.Run(rt.name, func(t *testing.T) {
  115. cwc := CreateWithToken(
  116. rt.cc.serverURL,
  117. rt.cc.clusterName,
  118. rt.cc.userName,
  119. rt.cc.caCert,
  120. rt.ccWithToken.token,
  121. )
  122. if cwc.Kind != rt.expected {
  123. t.Errorf(
  124. "failed CreateWithToken:\n\texpected: %s\n\t actual: %s",
  125. rt.expected,
  126. cwc.Kind,
  127. )
  128. }
  129. })
  130. }
  131. }
  132. func TestWriteKubeconfigToDisk(t *testing.T) {
  133. tmpdir, err := ioutil.TempDir("", "")
  134. if err != nil {
  135. t.Fatalf("Couldn't create tmpdir")
  136. }
  137. defer os.RemoveAll(tmpdir)
  138. var writeConfig = []struct {
  139. name string
  140. cc configClient
  141. ccWithToken configClientWithToken
  142. expected error
  143. file []byte
  144. }{
  145. {"test1", configClient{clusterName: "k8s", userName: "user1"}, configClientWithToken{token: "abc"}, nil, []byte(configOut1)},
  146. {"test2", configClient{clusterName: "kubernetes", userName: "user2", serverURL: "localhost:8080"}, configClientWithToken{token: "cba"}, nil, []byte(configOut2)},
  147. }
  148. for _, rt := range writeConfig {
  149. t.Run(rt.name, func(t *testing.T) {
  150. c := CreateWithToken(
  151. rt.cc.serverURL,
  152. rt.cc.clusterName,
  153. rt.cc.userName,
  154. rt.cc.caCert,
  155. rt.ccWithToken.token,
  156. )
  157. configPath := fmt.Sprintf("%s/etc/kubernetes/%s.conf", tmpdir, rt.name)
  158. err := WriteToDisk(configPath, c)
  159. if err != rt.expected {
  160. t.Errorf(
  161. "failed WriteToDisk with an error:\n\texpected: %s\n\t actual: %s",
  162. rt.expected,
  163. err,
  164. )
  165. }
  166. newFile, _ := ioutil.ReadFile(configPath)
  167. if !bytes.Equal(newFile, rt.file) {
  168. t.Errorf(
  169. "failed WriteToDisk config write:\n\texpected: %s\n\t actual: %s",
  170. rt.file,
  171. newFile,
  172. )
  173. }
  174. })
  175. }
  176. }
  177. func TestGetCurrentAuthInfo(t *testing.T) {
  178. var testCases = []struct {
  179. name string
  180. config *clientcmdapi.Config
  181. expected bool
  182. }{
  183. {
  184. name: "nil context",
  185. config: nil,
  186. expected: false,
  187. },
  188. {
  189. name: "no CurrentContext value",
  190. config: &clientcmdapi.Config{},
  191. expected: false,
  192. },
  193. {
  194. name: "no CurrentContext object",
  195. config: &clientcmdapi.Config{CurrentContext: "kubernetes"},
  196. expected: false,
  197. },
  198. {
  199. name: "CurrentContext object with bad contents",
  200. config: &clientcmdapi.Config{
  201. CurrentContext: "kubernetes",
  202. Contexts: map[string]*clientcmdapi.Context{"NOTkubernetes": {}},
  203. },
  204. expected: false,
  205. },
  206. {
  207. name: "no AuthInfo value",
  208. config: &clientcmdapi.Config{
  209. CurrentContext: "kubernetes",
  210. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {}},
  211. },
  212. expected: false,
  213. },
  214. {
  215. name: "no AuthInfo object",
  216. config: &clientcmdapi.Config{
  217. CurrentContext: "kubernetes",
  218. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},
  219. },
  220. expected: false,
  221. },
  222. {
  223. name: "AuthInfo object with bad contents",
  224. config: &clientcmdapi.Config{
  225. CurrentContext: "kubernetes",
  226. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},
  227. AuthInfos: map[string]*clientcmdapi.AuthInfo{"NOTkubernetes": {}},
  228. },
  229. expected: false,
  230. },
  231. {
  232. name: "valid AuthInfo",
  233. config: &clientcmdapi.Config{
  234. CurrentContext: "kubernetes",
  235. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},
  236. AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {}},
  237. },
  238. expected: true,
  239. },
  240. }
  241. for _, rt := range testCases {
  242. t.Run(rt.name, func(t *testing.T) {
  243. r := getCurrentAuthInfo(rt.config)
  244. if rt.expected != (r != nil) {
  245. t.Errorf(
  246. "failed TestHasCredentials:\n\texpected: %v\n\t actual: %v",
  247. rt.expected,
  248. r,
  249. )
  250. }
  251. })
  252. }
  253. }
  254. func TestHasCredentials(t *testing.T) {
  255. var testCases = []struct {
  256. name string
  257. config *clientcmdapi.Config
  258. expected bool
  259. }{
  260. {
  261. name: "no authInfo",
  262. config: nil,
  263. expected: false,
  264. },
  265. {
  266. name: "no credentials",
  267. config: &clientcmdapi.Config{
  268. CurrentContext: "kubernetes",
  269. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},
  270. AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {}},
  271. },
  272. expected: false,
  273. },
  274. {
  275. name: "token authentication credentials",
  276. config: &clientcmdapi.Config{
  277. CurrentContext: "kubernetes",
  278. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},
  279. AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {Token: "123"}},
  280. },
  281. expected: true,
  282. },
  283. {
  284. name: "basic authentication credentials",
  285. config: &clientcmdapi.Config{
  286. CurrentContext: "kubernetes",
  287. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},
  288. AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {Username: "A", Password: "B"}},
  289. },
  290. expected: true,
  291. },
  292. {
  293. name: "X509 authentication credentials",
  294. config: &clientcmdapi.Config{
  295. CurrentContext: "kubernetes",
  296. Contexts: map[string]*clientcmdapi.Context{"kubernetes": {AuthInfo: "kubernetes"}},
  297. AuthInfos: map[string]*clientcmdapi.AuthInfo{"kubernetes": {ClientKey: "A", ClientCertificate: "B"}},
  298. },
  299. expected: true,
  300. },
  301. }
  302. for _, rt := range testCases {
  303. t.Run(rt.name, func(t *testing.T) {
  304. r := HasAuthenticationCredentials(rt.config)
  305. if rt.expected != r {
  306. t.Errorf(
  307. "failed TestHasCredentials:\n\texpected: %v\n\t actual: %v",
  308. rt.expected,
  309. r,
  310. )
  311. }
  312. })
  313. }
  314. }