preDeploy.go 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. package stack
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/mitchellh/mapstructure"
  6. api "github.com/porter-dev/porter/api/client"
  7. "github.com/porter-dev/porter/cli/cmd/deploy"
  8. "github.com/porter-dev/porter/internal/integrations/preview"
  9. switchboardTypes "github.com/porter-dev/switchboard/pkg/types"
  10. )
  11. func createPreDeployResource(client *api.Client, release *Service, stackName, buildResourceName, pushResourceName string, projectID, clusterID uint, env map[string]string) (*switchboardTypes.Resource, string, error) {
  12. var finalCmd string
  13. if release != nil && release.Run != nil {
  14. finalCmd = *release.Run
  15. } else {
  16. finalCmd = getPredeployStartCommandFromRelease(client, stackName, projectID, clusterID)
  17. if finalCmd == "" {
  18. return nil, "", nil
  19. }
  20. }
  21. config := &preview.ApplicationConfig{}
  22. config.Build.Method = "registry"
  23. config.Build.Image = fmt.Sprintf("{ .%s.image }", buildResourceName)
  24. config.Build.Env = CopyEnv(env)
  25. config.WaitForJob = true
  26. config.InjectBuild = true
  27. helm_values := make(map[string]interface{})
  28. if release != nil && release.Config != nil {
  29. helm_values = release.Config
  30. }
  31. helm_values["container"] = map[string]interface{}{
  32. "command": finalCmd,
  33. "env": map[string]interface{}{
  34. "normal": CopyEnv(env),
  35. },
  36. }
  37. helm_values["paused"] = false
  38. config.Values = convertMap(helm_values).(map[string]interface{})
  39. rawConfig := make(map[string]any)
  40. err := mapstructure.Decode(config, &rawConfig)
  41. if err != nil {
  42. return nil, "", fmt.Errorf("could not decode config for release: %w", err)
  43. }
  44. return &switchboardTypes.Resource{
  45. Name: fmt.Sprintf("%s-r", stackName),
  46. DependsOn: []string{"get-env", buildResourceName, pushResourceName},
  47. Source: map[string]any{
  48. "name": "job",
  49. },
  50. Target: map[string]any{
  51. "app_name": fmt.Sprintf("%s-r", stackName),
  52. "namespace": fmt.Sprintf("porter-stack-%s", stackName),
  53. },
  54. Config: rawConfig,
  55. }, finalCmd, nil
  56. }
  57. func getPredeployStartCommandFromRelease(client *api.Client, stackName string, projectID uint, clusterID uint) string {
  58. namespace := fmt.Sprintf("porter-stack-%s", stackName)
  59. releaseName := fmt.Sprintf("%s-r", stackName)
  60. release, err := client.GetRelease(
  61. context.Background(),
  62. projectID,
  63. clusterID,
  64. namespace,
  65. releaseName,
  66. )
  67. if err != nil || release == nil || release.Config == nil {
  68. return ""
  69. }
  70. containerMap, err := deploy.GetNestedMap(release.Config, "container")
  71. if err == nil {
  72. if command, ok := containerMap["command"]; ok {
  73. if commandString, ok := command.(string); ok {
  74. return commandString
  75. }
  76. }
  77. }
  78. return ""
  79. }
  80. func convertMap(m interface{}) interface{} {
  81. switch m := m.(type) {
  82. case map[string]interface{}:
  83. for k, v := range m {
  84. m[k] = convertMap(v)
  85. }
  86. case map[interface{}]interface{}:
  87. result := map[string]interface{}{}
  88. for k, v := range m {
  89. result[k.(string)] = convertMap(v)
  90. }
  91. return result
  92. case []interface{}:
  93. for i, v := range m {
  94. m[i] = convertMap(v)
  95. }
  96. }
  97. return m
  98. }