2
0

hooks.go 2.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. package stack
  2. import (
  3. "context"
  4. "encoding/base64"
  5. "fmt"
  6. "strings"
  7. "github.com/fatih/color"
  8. api "github.com/porter-dev/porter/api/client"
  9. "github.com/porter-dev/porter/api/types"
  10. "github.com/porter-dev/porter/cli/cmd/config"
  11. )
  12. type DeployAppHook struct {
  13. Client *api.Client
  14. ApplicationName string
  15. ProjectID, ClusterID uint
  16. BuildImageDriverName string
  17. PorterYAML []byte
  18. Builder string
  19. }
  20. func (t *DeployAppHook) PreApply() error {
  21. err := config.ValidateCLIEnvironment()
  22. if err != nil {
  23. errMsg := composePreviewMessage("porter CLI is not configured correctly", Error)
  24. return fmt.Errorf("%s: %w", errMsg, err)
  25. }
  26. return nil
  27. }
  28. func (t *DeployAppHook) DataQueries() map[string]interface{} {
  29. res := map[string]interface{}{
  30. "image": fmt.Sprintf("{$.%s.image}", t.BuildImageDriverName),
  31. }
  32. return res
  33. }
  34. // deploy the app
  35. func (t *DeployAppHook) PostApply(driverOutput map[string]interface{}) error {
  36. client := config.GetAPIClient()
  37. namespace := fmt.Sprintf("porter-stack-%s", t.ApplicationName)
  38. _, err := client.GetRelease(
  39. context.Background(),
  40. t.ProjectID,
  41. t.ClusterID,
  42. namespace,
  43. t.ApplicationName,
  44. )
  45. shouldCreate := err != nil
  46. if err != nil {
  47. color.New(color.FgYellow).Printf("Could not read release for app %s (%s): attempting creation\n", t.ApplicationName, err.Error())
  48. } else {
  49. color.New(color.FgGreen).Printf("Found release for app %s: attempting update\n", t.ApplicationName)
  50. }
  51. return t.applyApp(client, shouldCreate, driverOutput)
  52. }
  53. func (t *DeployAppHook) applyApp(client *api.Client, shouldCreate bool, driverOutput map[string]interface{}) error {
  54. var imageInfo types.ImageInfo
  55. image, ok := driverOutput["image"].(string)
  56. // if it contains a $, then it means the query didn't resolve to anything
  57. if ok && !strings.Contains(image, "$") {
  58. imageSpl := strings.Split(image, ":")
  59. if len(imageSpl) == 2 {
  60. imageInfo = types.ImageInfo{
  61. Repository: imageSpl[0],
  62. Tag: imageSpl[1],
  63. }
  64. } else {
  65. return fmt.Errorf("could not parse image info %s", image)
  66. }
  67. }
  68. _, err := client.CreatePorterApp(
  69. context.Background(),
  70. t.ProjectID,
  71. t.ClusterID,
  72. t.ApplicationName,
  73. &types.CreatePorterAppRequest{
  74. ClusterID: t.ClusterID,
  75. ProjectID: t.ProjectID,
  76. PorterYAMLBase64: base64.StdEncoding.EncodeToString(t.PorterYAML),
  77. ImageInfo: imageInfo,
  78. OverrideRelease: false, // deploying from the cli will never delete release resources, only append or override
  79. Builder: t.Builder,
  80. },
  81. )
  82. if err != nil {
  83. if shouldCreate {
  84. return fmt.Errorf("error creating app %s: %w", t.ApplicationName, err)
  85. }
  86. return fmt.Errorf("error updating app %s: %w", t.ApplicationName, err)
  87. }
  88. return nil
  89. }
  90. func (t *DeployAppHook) OnConsolidatedErrors(map[string]error) {}
  91. func (t *DeployAppHook) OnError(error) {}