common.go 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. return namespace == "cert-manager" || namespace == "ingress-nginx" ||
  42. namespace == "kube-node-lease" || namespace == "kube-public" ||
  43. namespace == "kube-system" || namespace == "monitoring" ||
  44. namespace == "porter-agent-system" || namespace == "default" ||
  45. namespace == "ingress-nginx-private"
  46. }
  47. func isGithubPRClosed(
  48. client *github.Client,
  49. owner, name string,
  50. prNumber int,
  51. ) (bool, error) {
  52. ghPR, _, err := client.PullRequests.Get(
  53. context.Background(), owner, name, prNumber,
  54. )
  55. if err != nil {
  56. return false, fmt.Errorf("%v: %w", errGithubAPI, err)
  57. }
  58. return ghPR.GetState() == "closed", nil
  59. }
  60. func validateGetDeploymentRequest(
  61. projectID, clusterID, envID uint,
  62. owner, name string,
  63. request *types.GetDeploymentRequest,
  64. repo repository.Repository,
  65. ) (*models.Deployment, apierrors.RequestError) {
  66. if request.PRNumber == 0 && request.DeploymentID == 0 && request.Namespace == "" && request.Branch == "" {
  67. return nil, apierrors.NewErrPassThroughToClient(
  68. fmt.Errorf("one of id, pr_number, namespace or branch must be present in request body"), http.StatusBadRequest,
  69. )
  70. }
  71. var depl *models.Deployment
  72. var err error
  73. // read the deployment
  74. if request.DeploymentID != 0 {
  75. depl, err = repo.Environment().ReadDeploymentByID(projectID, clusterID, request.DeploymentID)
  76. if err != nil {
  77. if errors.Is(err, gorm.ErrRecordNotFound) {
  78. return nil, apierrors.NewErrNotFound(errDeploymentNotFound)
  79. }
  80. return nil, apierrors.NewErrInternal(err)
  81. }
  82. } else if request.PRNumber != 0 {
  83. depl, err = repo.Environment().ReadDeploymentByGitDetails(envID, owner, name, request.PRNumber)
  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.Namespace != "" {
  91. depl, err = repo.Environment().ReadDeployment(envID, request.Namespace)
  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.Branch != "" {
  99. depl, err = repo.Environment().ReadDeploymentForBranch(envID, owner, name, request.Branch)
  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. }
  107. if depl == nil {
  108. return nil, apierrors.NewErrNotFound(errDeploymentNotFound)
  109. }
  110. return depl, nil
  111. }