kubeconfig_test.go 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360
  1. package kubernetes_test
  2. import (
  3. "testing"
  4. "github.com/go-test/deep"
  5. "github.com/porter-dev/porter/internal/kubernetes"
  6. "github.com/porter-dev/porter/internal/kubernetes/fixtures"
  7. "github.com/porter-dev/porter/internal/models"
  8. "k8s.io/client-go/tools/clientcmd"
  9. )
  10. type ccsTest struct {
  11. name string
  12. raw []byte
  13. expected []*models.ClusterCandidate
  14. }
  15. var ClusterCandidatesTests = []ccsTest{
  16. ccsTest{
  17. name: "test without cluster ca data",
  18. raw: []byte(fixtures.ClusterCAWithoutData),
  19. expected: []*models.ClusterCandidate{
  20. &models.ClusterCandidate{
  21. AuthMechanism: models.X509,
  22. ProjectID: 1,
  23. Resolvers: []models.ClusterResolver{
  24. models.ClusterResolver{
  25. Name: models.ClusterCAData,
  26. Resolved: false,
  27. Data: []byte(`{"filename":"/fake/path/to/ca.pem"}`),
  28. },
  29. },
  30. Name: "cluster-test",
  31. Server: "https://10.10.10.10",
  32. ContextName: "context-test",
  33. Kubeconfig: []byte(fixtures.ClusterCAWithoutData),
  34. AWSClusterIDGuess: []byte{},
  35. },
  36. },
  37. },
  38. ccsTest{
  39. name: "test cluster localhost",
  40. raw: []byte(fixtures.ClusterLocalhost),
  41. expected: []*models.ClusterCandidate{
  42. &models.ClusterCandidate{
  43. AuthMechanism: models.X509,
  44. ProjectID: 1,
  45. Resolvers: []models.ClusterResolver{
  46. models.ClusterResolver{
  47. Name: models.ClusterLocalhost,
  48. Resolved: false,
  49. },
  50. },
  51. Name: "cluster-test",
  52. Server: "https://localhost:30000",
  53. ContextName: "context-test",
  54. Kubeconfig: []byte(fixtures.ClusterLocalhost),
  55. AWSClusterIDGuess: []byte{},
  56. },
  57. },
  58. },
  59. ccsTest{
  60. name: "x509 test with cert and key data",
  61. raw: []byte(fixtures.X509WithData),
  62. expected: []*models.ClusterCandidate{
  63. &models.ClusterCandidate{
  64. AuthMechanism: models.X509,
  65. ProjectID: 1,
  66. Resolvers: []models.ClusterResolver{},
  67. Name: "cluster-test",
  68. Server: "https://10.10.10.10",
  69. ContextName: "context-test",
  70. Kubeconfig: []byte(fixtures.X509WithData),
  71. AWSClusterIDGuess: []byte{},
  72. },
  73. },
  74. },
  75. ccsTest{
  76. name: "x509 test without cert data",
  77. raw: []byte(fixtures.X509WithoutCertData),
  78. expected: []*models.ClusterCandidate{
  79. &models.ClusterCandidate{
  80. AuthMechanism: models.X509,
  81. ProjectID: 1,
  82. Resolvers: []models.ClusterResolver{
  83. models.ClusterResolver{
  84. Name: "upload-client-cert-data",
  85. Resolved: false,
  86. Data: []byte(`{"filename":"/fake/path/to/cert.pem"}`),
  87. },
  88. },
  89. Name: "cluster-test",
  90. Server: "https://10.10.10.10",
  91. ContextName: "context-test",
  92. Kubeconfig: []byte(fixtures.X509WithoutCertData),
  93. AWSClusterIDGuess: []byte{},
  94. },
  95. },
  96. },
  97. ccsTest{
  98. name: "x509 test without key data",
  99. raw: []byte(fixtures.X509WithoutKeyData),
  100. expected: []*models.ClusterCandidate{
  101. &models.ClusterCandidate{
  102. AuthMechanism: models.X509,
  103. ProjectID: 1,
  104. Resolvers: []models.ClusterResolver{
  105. models.ClusterResolver{
  106. Name: "upload-client-key-data",
  107. Resolved: false,
  108. Data: []byte(`{"filename":"/fake/path/to/key.pem"}`),
  109. },
  110. },
  111. Name: "cluster-test",
  112. Server: "https://10.10.10.10",
  113. ContextName: "context-test",
  114. Kubeconfig: []byte(fixtures.X509WithoutKeyData),
  115. AWSClusterIDGuess: []byte{},
  116. },
  117. },
  118. },
  119. ccsTest{
  120. name: "x509 test without cert and key data",
  121. raw: []byte(fixtures.X509WithoutCertAndKeyData),
  122. expected: []*models.ClusterCandidate{
  123. &models.ClusterCandidate{
  124. AuthMechanism: models.X509,
  125. ProjectID: 1,
  126. Resolvers: []models.ClusterResolver{
  127. models.ClusterResolver{
  128. Name: "upload-client-cert-data",
  129. Resolved: false,
  130. Data: []byte(`{"filename":"/fake/path/to/cert.pem"}`),
  131. },
  132. models.ClusterResolver{
  133. Name: "upload-client-key-data",
  134. Resolved: false,
  135. Data: []byte(`{"filename":"/fake/path/to/key.pem"}`),
  136. },
  137. },
  138. Name: "cluster-test",
  139. Server: "https://10.10.10.10",
  140. ContextName: "context-test",
  141. Kubeconfig: []byte(fixtures.X509WithoutCertAndKeyData),
  142. AWSClusterIDGuess: []byte{},
  143. },
  144. },
  145. },
  146. ccsTest{
  147. name: "bearer token test with data",
  148. raw: []byte(fixtures.BearerTokenWithData),
  149. expected: []*models.ClusterCandidate{
  150. &models.ClusterCandidate{
  151. AuthMechanism: models.Bearer,
  152. ProjectID: 1,
  153. Resolvers: []models.ClusterResolver{},
  154. Name: "cluster-test",
  155. Server: "https://10.10.10.10",
  156. ContextName: "context-test",
  157. Kubeconfig: []byte(fixtures.BearerTokenWithData),
  158. AWSClusterIDGuess: []byte{},
  159. },
  160. },
  161. },
  162. ccsTest{
  163. name: "bearer token test without data",
  164. raw: []byte(fixtures.BearerTokenWithoutData),
  165. expected: []*models.ClusterCandidate{
  166. &models.ClusterCandidate{
  167. AuthMechanism: models.Bearer,
  168. ProjectID: 1,
  169. Resolvers: []models.ClusterResolver{
  170. models.ClusterResolver{
  171. Name: "upload-token-data",
  172. Resolved: false,
  173. Data: []byte(`{"filename":"/path/to/token/file.txt"}`),
  174. },
  175. },
  176. Name: "cluster-test",
  177. Server: "https://10.10.10.10",
  178. ContextName: "context-test",
  179. Kubeconfig: []byte(fixtures.BearerTokenWithoutData),
  180. AWSClusterIDGuess: []byte{},
  181. },
  182. },
  183. },
  184. ccsTest{
  185. name: "gcp test",
  186. raw: []byte(fixtures.GCPPlugin),
  187. expected: []*models.ClusterCandidate{
  188. &models.ClusterCandidate{
  189. AuthMechanism: models.GCP,
  190. ProjectID: 1,
  191. Resolvers: []models.ClusterResolver{
  192. models.ClusterResolver{
  193. Name: "upload-gcp-key-data",
  194. Resolved: false,
  195. },
  196. },
  197. Name: "cluster-test",
  198. Server: "https://10.10.10.10",
  199. ContextName: "context-test",
  200. Kubeconfig: []byte(fixtures.GCPPlugin),
  201. AWSClusterIDGuess: []byte{},
  202. },
  203. },
  204. },
  205. ccsTest{
  206. name: "aws iam authenticator test",
  207. raw: []byte(fixtures.AWSIamAuthenticatorExec),
  208. expected: []*models.ClusterCandidate{
  209. &models.ClusterCandidate{
  210. AuthMechanism: models.AWS,
  211. ProjectID: 1,
  212. Resolvers: []models.ClusterResolver{
  213. models.ClusterResolver{
  214. Name: "upload-aws-data",
  215. Resolved: false,
  216. },
  217. },
  218. Name: "cluster-test",
  219. Server: "https://10.10.10.10",
  220. ContextName: "context-test",
  221. Kubeconfig: []byte(fixtures.AWSIamAuthenticatorExec),
  222. AWSClusterIDGuess: []byte("cluster-test-aws-id-guess"),
  223. },
  224. },
  225. },
  226. ccsTest{
  227. name: "aws eks get-token test",
  228. raw: []byte(fixtures.AWSEKSGetTokenExec),
  229. expected: []*models.ClusterCandidate{
  230. &models.ClusterCandidate{
  231. AuthMechanism: models.AWS,
  232. ProjectID: 1,
  233. Resolvers: []models.ClusterResolver{
  234. models.ClusterResolver{
  235. Name: "upload-aws-data",
  236. Resolved: false,
  237. },
  238. },
  239. Name: "cluster-test",
  240. Server: "https://10.10.10.10",
  241. ContextName: "context-test",
  242. Kubeconfig: []byte(fixtures.AWSEKSGetTokenExec),
  243. AWSClusterIDGuess: []byte("cluster-test-aws-id-guess"),
  244. },
  245. },
  246. },
  247. ccsTest{
  248. name: "oidc without ca data",
  249. raw: []byte(fixtures.OIDCAuthWithoutData),
  250. expected: []*models.ClusterCandidate{
  251. &models.ClusterCandidate{
  252. AuthMechanism: models.OIDC,
  253. ProjectID: 1,
  254. Resolvers: []models.ClusterResolver{
  255. models.ClusterResolver{
  256. Name: "upload-oidc-idp-issuer-ca-data",
  257. Resolved: false,
  258. Data: []byte(`{"filename":"/fake/path/to/ca.pem"}`),
  259. },
  260. },
  261. Name: "cluster-test",
  262. Server: "https://10.10.10.10",
  263. ContextName: "context-test",
  264. Kubeconfig: []byte(fixtures.OIDCAuthWithoutData),
  265. AWSClusterIDGuess: []byte{},
  266. },
  267. },
  268. },
  269. ccsTest{
  270. name: "oidc with ca data",
  271. raw: []byte(fixtures.OIDCAuthWithData),
  272. expected: []*models.ClusterCandidate{
  273. &models.ClusterCandidate{
  274. AuthMechanism: models.OIDC,
  275. ProjectID: 1,
  276. Resolvers: []models.ClusterResolver{},
  277. Name: "cluster-test",
  278. Server: "https://10.10.10.10",
  279. ContextName: "context-test",
  280. Kubeconfig: []byte(fixtures.OIDCAuthWithData),
  281. AWSClusterIDGuess: []byte{},
  282. },
  283. },
  284. },
  285. ccsTest{
  286. name: "basic auth test",
  287. raw: []byte(fixtures.BasicAuth),
  288. expected: []*models.ClusterCandidate{
  289. &models.ClusterCandidate{
  290. AuthMechanism: models.Basic,
  291. ProjectID: 1,
  292. Resolvers: []models.ClusterResolver{},
  293. Name: "cluster-test",
  294. Server: "https://10.10.10.10",
  295. ContextName: "context-test",
  296. Kubeconfig: []byte(fixtures.BasicAuth),
  297. AWSClusterIDGuess: []byte{},
  298. },
  299. },
  300. },
  301. }
  302. func TestGetClusterCandidatesNonLocal(t *testing.T) {
  303. for _, c := range ClusterCandidatesTests {
  304. result, err := kubernetes.GetClusterCandidatesFromKubeconfig(c.raw, 1, false)
  305. if err != nil {
  306. t.Fatalf("error occurred %v\n", err)
  307. }
  308. // make result into a map so it's easier to compare
  309. resMap := make(map[string]*models.ClusterCandidate)
  310. for _, res := range result {
  311. resMap[res.Server+"-"+string(res.AuthMechanism)] = res
  312. }
  313. for _, exp := range c.expected {
  314. res, ok := resMap[exp.Server+"-"+string(exp.AuthMechanism)]
  315. if !ok {
  316. t.Fatalf("%s failed: no matching result for %s\n", c.name,
  317. exp.Server+"-"+string(exp.AuthMechanism))
  318. }
  319. // compare kubeconfig by transforming into a client config
  320. resConfig, _ := clientcmd.NewClientConfigFromBytes(res.Kubeconfig)
  321. expConfig, err := clientcmd.NewClientConfigFromBytes(exp.Kubeconfig)
  322. if err != nil {
  323. t.Fatalf("config from bytes, error occurred %v\n", err)
  324. }
  325. resRawConf, _ := resConfig.RawConfig()
  326. expRawConf, err := expConfig.RawConfig()
  327. if err != nil {
  328. t.Fatalf("raw config conversion, error occurred %v\n", err)
  329. }
  330. if diff := deep.Equal(expRawConf, resRawConf); diff != nil {
  331. t.Errorf("incorrect kubeconfigs")
  332. t.Error(diff)
  333. }
  334. // reset kubeconfigs since they won't be exactly "deep equal"
  335. exp.Kubeconfig = []byte{}
  336. res.Kubeconfig = []byte{}
  337. if diff := deep.Equal(exp, res); diff != nil {
  338. t.Errorf("incorrect cluster candidate")
  339. t.Error(diff)
  340. }
  341. }
  342. }
  343. }