2
0

common.go 3.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142
  1. package environment
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "net/http"
  7. "strconv"
  8. "github.com/bradleyfalzon/ghinstallation/v2"
  9. "github.com/google/go-github/v41/github"
  10. "github.com/porter-dev/porter/api/server/shared/apierrors"
  11. "github.com/porter-dev/porter/api/server/shared/config"
  12. "github.com/porter-dev/porter/api/types"
  13. "github.com/porter-dev/porter/internal/models"
  14. "github.com/porter-dev/porter/internal/repository"
  15. "gorm.io/gorm"
  16. )
  17. var (
  18. errDeploymentNotFound = errors.New("no such deployment exists")
  19. errEnvironmentNotFound = errors.New("no such environment exists")
  20. errGithubAPI = errors.New("error communicating with the github API")
  21. )
  22. func getGithubClientFromEnvironment(config *config.Config, env *models.Environment) (*github.Client, error) {
  23. // get the github app client
  24. ghAppId, err := strconv.Atoi(config.ServerConf.GithubAppID)
  25. if err != nil {
  26. return nil, fmt.Errorf("malformed GITHUB_APP_ID in server configuration: %w", err)
  27. }
  28. // authenticate as github app installation
  29. itr, err := ghinstallation.New(
  30. http.DefaultTransport,
  31. int64(ghAppId),
  32. int64(env.GitInstallationID),
  33. config.ServerConf.GithubAppSecret,
  34. )
  35. if err != nil {
  36. return nil, fmt.Errorf("error in creating github client from preview environment: %w", err)
  37. }
  38. return github.NewClient(&http.Client{Transport: itr}), nil
  39. }
  40. func isSystemNamespace(namespace string) bool {
  41. systemNamespaces := map[string]bool{
  42. "ack-system": true,
  43. "cert-manager": true,
  44. "default": true,
  45. "ingress-nginx": true,
  46. "ingress-nginx-private": true,
  47. "kube-node-lease": true,
  48. "kube-public": true,
  49. "kube-system": true,
  50. "monitoring": true,
  51. "porter-agent-system": true,
  52. }
  53. return systemNamespaces[namespace]
  54. }
  55. func isGithubPRClosed(
  56. client *github.Client,
  57. owner, name string,
  58. prNumber int,
  59. ) (bool, error) {
  60. ghPR, _, err := client.PullRequests.Get(
  61. context.Background(), owner, name, prNumber,
  62. )
  63. if err != nil {
  64. return false, fmt.Errorf("%v: %w", errGithubAPI, err)
  65. }
  66. return ghPR.GetState() == "closed", nil
  67. }
  68. func validateGetDeploymentRequest(
  69. projectID, clusterID, envID uint,
  70. owner, name string,
  71. request *types.GetDeploymentRequest,
  72. repo repository.Repository,
  73. ) (*models.Deployment, apierrors.RequestError) {
  74. if request.PRNumber == 0 && request.DeploymentID == 0 && request.Namespace == "" && request.Branch == "" {
  75. return nil, apierrors.NewErrPassThroughToClient(
  76. fmt.Errorf("one of id, pr_number, namespace or branch must be present in request body"), http.StatusBadRequest,
  77. )
  78. }
  79. var depl *models.Deployment
  80. var err error
  81. // read the deployment
  82. if request.DeploymentID != 0 {
  83. depl, err = repo.Environment().ReadDeploymentByID(projectID, clusterID, request.DeploymentID)
  84. if err != nil {
  85. if errors.Is(err, gorm.ErrRecordNotFound) {
  86. return nil, apierrors.NewErrNotFound(errDeploymentNotFound)
  87. }
  88. return nil, apierrors.NewErrInternal(err)
  89. }
  90. } else if request.PRNumber != 0 {
  91. depl, err = repo.Environment().ReadDeploymentByGitDetails(envID, owner, name, request.PRNumber)
  92. if err != nil {
  93. if errors.Is(err, gorm.ErrRecordNotFound) {
  94. return nil, apierrors.NewErrNotFound(errDeploymentNotFound)
  95. }
  96. return nil, apierrors.NewErrInternal(err)
  97. }
  98. } else if request.Namespace != "" {
  99. depl, err = repo.Environment().ReadDeployment(envID, request.Namespace)
  100. if err != nil {
  101. if errors.Is(err, gorm.ErrRecordNotFound) {
  102. return nil, apierrors.NewErrNotFound(errDeploymentNotFound)
  103. }
  104. return nil, apierrors.NewErrInternal(err)
  105. }
  106. } else if request.Branch != "" {
  107. depl, err = repo.Environment().ReadDeploymentForBranch(envID, owner, name, request.Branch)
  108. if err != nil {
  109. if errors.Is(err, gorm.ErrRecordNotFound) {
  110. return nil, apierrors.NewErrNotFound(errDeploymentNotFound)
  111. }
  112. return nil, apierrors.NewErrInternal(err)
  113. }
  114. }
  115. if depl == nil {
  116. return nil, apierrors.NewErrNotFound(errDeploymentNotFound)
  117. }
  118. return depl, nil
  119. }