driver_validators.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212
  1. package preview
  2. import (
  3. "fmt"
  4. "github.com/mitchellh/mapstructure"
  5. "github.com/porter-dev/switchboard/pkg/types"
  6. "k8s.io/apimachinery/pkg/util/validation"
  7. )
  8. func commonValidator(resource *types.Resource) (*Source, *Target, error) {
  9. source := &Source{}
  10. err := mapstructure.Decode(resource.Source, source)
  11. if err != nil {
  12. return nil, nil, fmt.Errorf("for resource '%s': error parsing source: %w", resource.Name, err)
  13. }
  14. target := &Target{}
  15. err = mapstructure.Decode(resource.Target, target)
  16. if err != nil {
  17. return nil, nil, fmt.Errorf("for resource '%s': error parsing target: %w", resource.Name, err)
  18. }
  19. return source, target, nil
  20. }
  21. func deployDriverValidator(resource *types.Resource) error {
  22. source, _, err := commonValidator(resource)
  23. if err != nil {
  24. return err
  25. }
  26. if source.Name == "" {
  27. return fmt.Errorf("for resource '%s': source name cannot be empty", resource.Name)
  28. }
  29. if source.Repo == "" {
  30. source.Repo = "https://charts.getporter.dev"
  31. }
  32. if source.Repo == "https://charts.getporter.dev" {
  33. appConfig := &ApplicationConfig{}
  34. err = mapstructure.Decode(resource.Config, appConfig)
  35. if err != nil {
  36. return fmt.Errorf("for resource '%s': error parsing config: %w", resource.Name, err)
  37. }
  38. if appConfig.Build.Method == "" {
  39. return fmt.Errorf("for resource '%s': build method cannot be empty", resource.Name)
  40. } else if appConfig.Build.Method != "docker" &&
  41. appConfig.Build.Method != "pack" &&
  42. appConfig.Build.Method != "registry" {
  43. return fmt.Errorf("for resource '%s': build method must be one of 'docker', 'pack', or 'registry'", resource.Name)
  44. }
  45. if appConfig.Build.Method == "docker" && appConfig.Build.Dockerfile == "" {
  46. return fmt.Errorf("for resource '%s': dockerfile cannot be empty when using the 'docker' build method",
  47. resource.Name)
  48. } else if appConfig.Build.Method == "registry" && appConfig.Build.Image == "" {
  49. return fmt.Errorf("for resource '%s': image cannot be empty when using the 'registry' build method",
  50. resource.Name)
  51. }
  52. for _, eg := range appConfig.EnvGroups {
  53. if errStrs := validation.IsDNS1123Label(eg.Name); len(errStrs) > 0 {
  54. str := fmt.Sprintf("for resource '%s': invalid characters found in env group '%s' name:",
  55. resource.Name, eg.Name)
  56. for _, errStr := range errStrs {
  57. str += fmt.Sprintf("\n * %s", errStr)
  58. }
  59. return fmt.Errorf("%s", str)
  60. }
  61. }
  62. if len(appConfig.Values) > 0 {
  63. if source.Name == "web" {
  64. err := validateWebChartValues(appConfig.Values)
  65. if err != nil {
  66. return fmt.Errorf("for resource '%s': error validating values for web deployment: %w",
  67. resource.Name, err)
  68. }
  69. } else if source.Name == "worker" {
  70. err := validateWorkerChartValues(appConfig.Values)
  71. if err != nil {
  72. return fmt.Errorf("for resource '%s': error validating values for worker deployment: %w",
  73. resource.Name, err)
  74. }
  75. } else if source.Name == "job" {
  76. err := validateJobChartValues(appConfig.Values)
  77. if err != nil {
  78. return fmt.Errorf("for resource '%s': error validating values for job deployment: %w",
  79. resource.Name, err)
  80. }
  81. }
  82. }
  83. }
  84. return nil
  85. }
  86. func buildImageDriverValidator(resource *types.Resource) error {
  87. _, target, err := commonValidator(resource)
  88. if err != nil {
  89. return err
  90. }
  91. if target.AppName == "" {
  92. return fmt.Errorf("for resource '%s': target app_name is missing", resource.Name)
  93. }
  94. driverConfig := &BuildDriverConfig{}
  95. err = mapstructure.Decode(resource.Config, driverConfig)
  96. if err != nil {
  97. return fmt.Errorf("for resource '%s': error parsing config: %w", resource.Name, err)
  98. }
  99. return nil
  100. }
  101. func pushImageDriverValidator(resource *types.Resource) error {
  102. _, target, err := commonValidator(resource)
  103. if err != nil {
  104. return err
  105. }
  106. if target.AppName == "" {
  107. return fmt.Errorf("for resource '%s': target app_name is missing", resource.Name)
  108. }
  109. driverConfig := &PushDriverConfig{}
  110. err = mapstructure.Decode(resource.Config, driverConfig)
  111. if err != nil {
  112. return fmt.Errorf("for resource '%s': error parsing config: %w", resource.Name, err)
  113. }
  114. return nil
  115. }
  116. func updateConfigDriverValidator(resource *types.Resource) error {
  117. _, target, err := commonValidator(resource)
  118. if err != nil {
  119. return err
  120. }
  121. if target.AppName == "" {
  122. return fmt.Errorf("for resource '%s': target app_name is missing", resource.Name)
  123. }
  124. driverConfig := &UpdateConfigDriverConfig{}
  125. err = mapstructure.Decode(resource.Config, driverConfig)
  126. if err != nil {
  127. return fmt.Errorf("for resource '%s': error parsing config: %w", resource.Name, err)
  128. }
  129. return nil
  130. }
  131. func randomStringDriverValidator(resource *types.Resource) error {
  132. driverConfig := &RandomStringDriverConfig{}
  133. err := mapstructure.Decode(resource.Config, driverConfig)
  134. if err != nil {
  135. return fmt.Errorf("for resource '%s': error parsing config: %w", resource.Name, err)
  136. }
  137. return nil
  138. }
  139. func envGroupDriverValidator(resource *types.Resource) error {
  140. target := &Target{}
  141. err := mapstructure.Decode(resource.Target, target)
  142. if err != nil {
  143. return fmt.Errorf("for resource '%s': error parsing target: %w", resource.Name, err)
  144. }
  145. config := &EnvGroupDriverConfig{}
  146. err = mapstructure.Decode(resource.Config, config)
  147. if err != nil {
  148. return fmt.Errorf("for resource '%s': error parsing config: %w", resource.Name, err)
  149. }
  150. return nil
  151. }
  152. func osEnvDriverValidator(resource *types.Resource) error {
  153. return nil
  154. }