cluster_test.go 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466
  1. package gorm_test
  2. import (
  3. "testing"
  4. "time"
  5. "github.com/go-test/deep"
  6. "github.com/porter-dev/porter/api/types"
  7. "github.com/porter-dev/porter/internal/features"
  8. "github.com/porter-dev/porter/internal/models"
  9. ints "github.com/porter-dev/porter/internal/models/integrations"
  10. orm "gorm.io/gorm"
  11. )
  12. func TestCreateClusterCandidate(t *testing.T) {
  13. tester := &tester{
  14. dbFileName: "./porter_create_cc.db",
  15. }
  16. setupTestEnv(tester, t)
  17. initProject(tester, t)
  18. defer cleanup(tester, t)
  19. cc := &models.ClusterCandidate{
  20. AuthMechanism: models.AWS,
  21. ProjectID: tester.initProjects[0].ID,
  22. CreatedClusterID: 0,
  23. Resolvers: []models.ClusterResolver{},
  24. Name: "cluster-test",
  25. Server: "https://localhost",
  26. ContextName: "context-test",
  27. AWSClusterIDGuess: []byte("example-cluster-0"),
  28. Kubeconfig: []byte("current-context: testing\n"),
  29. }
  30. expCC := *cc
  31. cc, err := tester.repo.Cluster().CreateClusterCandidate(cc)
  32. if err != nil {
  33. t.Fatalf("%v\n", err)
  34. }
  35. cc, err = tester.repo.Cluster().ReadClusterCandidate(tester.initProjects[0].ID, cc.Model.ID)
  36. if err != nil {
  37. t.Fatalf("%v\n", err)
  38. }
  39. // make sure id is 1
  40. if cc.Model.ID != 1 {
  41. t.Errorf("incorrect cluster candidate ID: expected %d, got %d\n", 1, cc.Model.ID)
  42. }
  43. // reset fields for deep.Equal
  44. cc.Model = orm.Model{}
  45. if diff := deep.Equal(expCC, *cc); diff != nil {
  46. t.Errorf("incorrect cluster candidate")
  47. t.Error(diff)
  48. }
  49. }
  50. func TestCreateClusterCandidateWithResolvers(t *testing.T) {
  51. tester := &tester{
  52. dbFileName: "./porter_create_cc.db",
  53. }
  54. setupTestEnv(tester, t)
  55. initProject(tester, t)
  56. defer cleanup(tester, t)
  57. cc := &models.ClusterCandidate{
  58. AuthMechanism: models.AWS,
  59. ProjectID: tester.initProjects[0].ID,
  60. CreatedClusterID: 0,
  61. Resolvers: []models.ClusterResolver{
  62. {
  63. Name: types.ClusterLocalhost,
  64. Resolved: false,
  65. },
  66. },
  67. Name: "cluster-test",
  68. Server: "https://localhost",
  69. ContextName: "context-test",
  70. AWSClusterIDGuess: []byte("example-cluster-0"),
  71. Kubeconfig: []byte("current-context: testing\n"),
  72. }
  73. expCC := *cc
  74. cc, err := tester.repo.Cluster().CreateClusterCandidate(cc)
  75. if err != nil {
  76. t.Fatalf("%v\n", err)
  77. }
  78. cc, err = tester.repo.Cluster().ReadClusterCandidate(tester.initProjects[0].ID, cc.Model.ID)
  79. if err != nil {
  80. t.Fatalf("%v\n", err)
  81. }
  82. // make sure id is 1
  83. if cc.Model.ID != 1 {
  84. t.Errorf("incorrect cluster candidate ID: expected %d, got %d\n", 1, cc.Model.ID)
  85. }
  86. // make sure length of resolvers is 1
  87. if len(cc.Resolvers) != 1 {
  88. t.Fatalf("incorrect cluster candidate resolvers length: expected %d, got %d\n", 1, len(cc.Resolvers))
  89. }
  90. // make sure resolver cluster candidate id is 1
  91. if cc.Resolvers[0].ClusterCandidateID != 1 {
  92. t.Errorf("incorrect resolver ClusterCandidateID: expected %d, got %d\n", 1, cc.Resolvers[0].ClusterCandidateID)
  93. }
  94. // reset fields for deep.Equal
  95. cc.Model = orm.Model{}
  96. cc.Resolvers[0].Model = orm.Model{}
  97. expCC.Resolvers[0].Model = orm.Model{}
  98. expCC.Resolvers[0].ClusterCandidateID = 1
  99. if diff := deep.Equal(expCC, *cc); diff != nil {
  100. t.Errorf("incorrect cluster candidate")
  101. t.Error(diff)
  102. }
  103. }
  104. func TestListClusterCandidatesByProjectID(t *testing.T) {
  105. tester := &tester{
  106. dbFileName: "./porter_list_ccs.db",
  107. }
  108. setupTestEnv(tester, t)
  109. initProject(tester, t)
  110. initClusterCandidate(tester, t)
  111. defer cleanup(tester, t)
  112. ccs, err := tester.repo.Cluster().ListClusterCandidatesByProjectID(
  113. tester.initProjects[0].Model.ID,
  114. )
  115. if err != nil {
  116. t.Fatalf("%v\n", err)
  117. }
  118. if len(ccs) != 1 {
  119. t.Fatalf("length of cluster candidates incorrect: expected %d, got %d\n", 1, len(ccs))
  120. }
  121. // make sure data is correct
  122. expCC := models.ClusterCandidate{
  123. AuthMechanism: models.AWS,
  124. ProjectID: tester.initProjects[0].ID,
  125. CreatedClusterID: 0,
  126. Resolvers: []models.ClusterResolver{},
  127. Name: "cluster-test",
  128. Server: "https://localhost",
  129. ContextName: "context-test",
  130. AWSClusterIDGuess: []byte("example-cluster-0"),
  131. Kubeconfig: []byte("current-context: testing\n"),
  132. }
  133. cc := ccs[0]
  134. // reset fields for reflect.DeepEqual
  135. cc.Model = orm.Model{}
  136. if diff := deep.Equal(expCC, *cc); diff != nil {
  137. t.Errorf("incorrect cluster candidate")
  138. t.Error(diff)
  139. }
  140. }
  141. func TestUpdateClusterCandidateCreatedClusterID(t *testing.T) {
  142. tester := &tester{
  143. dbFileName: "./porter_update_cc_cluster_id.db",
  144. }
  145. setupTestEnv(tester, t)
  146. initClusterCandidate(tester, t)
  147. initCluster(tester, t)
  148. defer cleanup(tester, t)
  149. cc, err := tester.repo.Cluster().UpdateClusterCandidateCreatedClusterID(
  150. tester.initCCs[0].ID,
  151. tester.initClusters[0].ID,
  152. )
  153. if err != nil {
  154. t.Fatalf("%v\n", err)
  155. }
  156. expCC := models.ClusterCandidate{
  157. AuthMechanism: models.AWS,
  158. ProjectID: tester.initProjects[0].ID,
  159. CreatedClusterID: tester.initClusters[0].ID,
  160. Name: "cluster-test",
  161. Server: "https://localhost",
  162. ContextName: "context-test",
  163. AWSClusterIDGuess: []byte("example-cluster-0"),
  164. Kubeconfig: []byte("current-context: testing\n"),
  165. }
  166. // reset fields for reflect.DeepEqual
  167. cc.Model = orm.Model{}
  168. if diff := deep.Equal(expCC, *cc); diff != nil {
  169. t.Errorf("incorrect cluster candidate")
  170. t.Error(diff)
  171. }
  172. }
  173. func TestCreateCluster(t *testing.T) {
  174. tester := &tester{
  175. dbFileName: "./porter_create_cluster.db",
  176. }
  177. setupTestEnv(tester, t)
  178. initProject(tester, t)
  179. initKubeIntegration(tester, t)
  180. defer cleanup(tester, t)
  181. cluster := &models.Cluster{
  182. ProjectID: tester.initProjects[0].ID,
  183. Name: "cluster-test",
  184. Server: "https://localhost",
  185. KubeIntegrationID: tester.initKIs[0].ID,
  186. CertificateAuthorityData: []byte("-----BEGIN"),
  187. }
  188. expCluster := *cluster
  189. cluster, err := tester.repo.Cluster().CreateCluster(cluster, &features.Client{})
  190. if err != nil {
  191. t.Fatalf("%v\n", err)
  192. }
  193. cluster, err = tester.repo.Cluster().ReadCluster(tester.initProjects[0].ID, cluster.Model.ID)
  194. if err != nil {
  195. t.Fatalf("%v\n", err)
  196. }
  197. // make sure id is 1
  198. if cluster.Model.ID != 1 {
  199. t.Errorf("incorrect cluster ID: expected %d, got %d\n", 1, cluster.Model.ID)
  200. }
  201. // reset fields for deep.Equal
  202. expCluster.TokenCacheID = 1
  203. expCluster.TokenCache.ClusterID = 1
  204. cluster.Model = orm.Model{}
  205. cluster.TokenCache.Model = orm.Model{}
  206. if diff := deep.Equal(expCluster, *cluster); diff != nil {
  207. t.Errorf("incorrect cluster")
  208. t.Error(diff)
  209. }
  210. }
  211. func TestListClustersByProjectID(t *testing.T) {
  212. tester := &tester{
  213. dbFileName: "./porter_list_clusters.db",
  214. }
  215. setupTestEnv(tester, t)
  216. initProject(tester, t)
  217. initCluster(tester, t)
  218. defer cleanup(tester, t)
  219. clusters, err := tester.repo.Cluster().ListClustersByProjectID(
  220. tester.initProjects[0].Model.ID,
  221. )
  222. if err != nil {
  223. t.Fatalf("%v\n", err)
  224. }
  225. if len(clusters) != 1 {
  226. t.Fatalf("length of clusters incorrect: expected %d, got %d\n", 1, len(clusters))
  227. }
  228. // make sure data is correct
  229. expCluster := models.Cluster{
  230. ProjectID: tester.initProjects[0].ID,
  231. Name: "cluster-test",
  232. Server: "https://localhost",
  233. KubeIntegrationID: tester.initKIs[0].ID,
  234. CertificateAuthorityData: []byte("-----BEGIN"),
  235. TokenCacheID: 1,
  236. }
  237. cluster := clusters[0]
  238. // reset fields for reflect.DeepEqual
  239. cluster.Model = orm.Model{}
  240. cluster.TokenCache.Model = orm.Model{}
  241. if diff := deep.Equal(expCluster, *cluster); diff != nil {
  242. t.Errorf("incorrect cluster")
  243. t.Error(diff)
  244. }
  245. }
  246. func TestUpdateCluster(t *testing.T) {
  247. tester := &tester{
  248. dbFileName: "./porter_update_cluster.db",
  249. }
  250. setupTestEnv(tester, t)
  251. initProject(tester, t)
  252. initCluster(tester, t)
  253. defer cleanup(tester, t)
  254. cluster := tester.initClusters[0]
  255. cluster.Name = "cluster-new-name"
  256. cluster, err := tester.repo.Cluster().UpdateCluster(
  257. cluster,
  258. &features.Client{},
  259. )
  260. if err != nil {
  261. t.Fatalf("%v\n", err)
  262. }
  263. cluster, err = tester.repo.Cluster().ReadCluster(tester.initProjects[0].ID, tester.initClusters[0].ID)
  264. // make sure data is correct
  265. expCluster := models.Cluster{
  266. ProjectID: tester.initProjects[0].ID,
  267. Name: "cluster-new-name",
  268. Server: "https://localhost",
  269. KubeIntegrationID: tester.initKIs[0].ID,
  270. CertificateAuthorityData: []byte("-----BEGIN"),
  271. TokenCacheID: 1,
  272. TokenCache: ints.ClusterTokenCache{
  273. ClusterID: 1,
  274. },
  275. }
  276. // reset fields for reflect.DeepEqual
  277. cluster.Model = orm.Model{}
  278. cluster.TokenCache.Model = orm.Model{}
  279. if diff := deep.Equal(expCluster, *cluster); diff != nil {
  280. t.Errorf("incorrect cluster")
  281. t.Error(diff)
  282. }
  283. }
  284. func TestUpdateClusterToken(t *testing.T) {
  285. tester := &tester{
  286. dbFileName: "./porter_test_update_cluster_token.db",
  287. }
  288. setupTestEnv(tester, t)
  289. initProject(tester, t)
  290. initKubeIntegration(tester, t)
  291. defer cleanup(tester, t)
  292. cluster := &models.Cluster{
  293. ProjectID: tester.initProjects[0].ID,
  294. Name: "cluster-test",
  295. Server: "https://localhost",
  296. KubeIntegrationID: tester.initKIs[0].ID,
  297. CertificateAuthorityData: []byte("-----BEGIN"),
  298. TokenCache: ints.ClusterTokenCache{
  299. TokenCache: ints.TokenCache{
  300. Token: []byte("token-1"),
  301. Expiry: time.Now().Add(-1 * time.Hour),
  302. },
  303. },
  304. }
  305. cluster, err := tester.repo.Cluster().CreateCluster(cluster, &features.Client{})
  306. if err != nil {
  307. t.Fatalf("%v\n", err)
  308. }
  309. cluster, err = tester.repo.Cluster().ReadCluster(tester.initProjects[0].ID, cluster.Model.ID)
  310. if err != nil {
  311. t.Fatalf("%v\n", err)
  312. }
  313. // make sure cluster id of token is 1
  314. if cluster.TokenCache.ClusterID != 1 {
  315. t.Fatalf("incorrect cluster id in token cache: expected %d, got %d\n", 1, cluster.TokenCache.ClusterID)
  316. }
  317. // make sure old token is token-1
  318. if string(cluster.TokenCache.Token) != "token-1" {
  319. t.Errorf("incorrect token in cache: expected %s, got %s\n", "token-1", cluster.TokenCache.Token)
  320. }
  321. // make sure old token is expired
  322. if isExpired := cluster.TokenCache.IsExpired(); !isExpired {
  323. t.Fatalf("token was not expired\n")
  324. }
  325. cluster.TokenCache.Token = []byte("token-2")
  326. cluster.TokenCache.Expiry = time.Now().Add(24 * time.Hour)
  327. cluster, err = tester.repo.Cluster().UpdateClusterTokenCache(&cluster.TokenCache)
  328. if err != nil {
  329. t.Fatalf("%v\n", err)
  330. }
  331. cluster, err = tester.repo.Cluster().ReadCluster(tester.initProjects[0].ID, cluster.Model.ID)
  332. if err != nil {
  333. t.Fatalf("%v\n", err)
  334. }
  335. // make sure id is 1
  336. if cluster.Model.ID != 1 {
  337. t.Errorf("incorrect service account ID: expected %d, got %d\n", 1, cluster.Model.ID)
  338. }
  339. // make sure new token is correct and not expired
  340. if cluster.TokenCache.ClusterID != 1 {
  341. t.Fatalf("incorrect service account ID in token cache: expected %d, got %d\n", 1, cluster.TokenCache.ClusterID)
  342. }
  343. if isExpired := cluster.TokenCache.IsExpired(); isExpired {
  344. t.Fatalf("token was expired\n")
  345. }
  346. if string(cluster.TokenCache.Token) != "token-2" {
  347. t.Errorf("incorrect token in cache: expected %s, got %s\n", "token-2", cluster.TokenCache.Token)
  348. }
  349. }
  350. func TestDeleteCluster(t *testing.T) {
  351. tester := &tester{
  352. dbFileName: "./porter_delete_cluster.db",
  353. }
  354. setupTestEnv(tester, t)
  355. initProject(tester, t)
  356. initCluster(tester, t)
  357. defer cleanup(tester, t)
  358. cluster, err := tester.repo.Cluster().ReadCluster(tester.initProjects[0].ID, tester.initClusters[0].Model.ID)
  359. if err != nil {
  360. t.Fatalf("%v\n", err)
  361. }
  362. err = tester.repo.Cluster().DeleteCluster(cluster)
  363. if err != nil {
  364. t.Fatalf("%v\n", err)
  365. }
  366. _, err = tester.repo.Cluster().ReadCluster(tester.initProjects[0].ID, tester.initClusters[0].Model.ID)
  367. if err != orm.ErrRecordNotFound {
  368. t.Fatalf("incorrect error: expected %v, got %v\n", orm.ErrRecordNotFound, err)
  369. }
  370. clusters, err := tester.repo.Cluster().ListClustersByProjectID(tester.initProjects[0].Model.ID)
  371. if err != nil {
  372. t.Fatalf("%v\n", err)
  373. }
  374. if len(clusters) != 0 {
  375. t.Fatalf("length of clusters was not 0")
  376. }
  377. }