kubeconfig_test.go 9.6 KB

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