parse.go 3.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495
  1. package porter_app
  2. import (
  3. "context"
  4. v1 "github.com/porter-dev/porter/internal/porter_app/v1"
  5. v2 "github.com/porter-dev/porter/internal/porter_app/v2"
  6. "sigs.k8s.io/yaml"
  7. "github.com/porter-dev/porter/internal/telemetry"
  8. )
  9. // PorterYamlVersion is a string type for the version of the porter yaml
  10. type PorterYamlVersion string
  11. const (
  12. // PorterYamlVersion_V2 is the v2 version of the porter yaml
  13. PorterYamlVersion_V2 PorterYamlVersion = "v2"
  14. // PorterYamlVersion_V1 is the v1, legacy version of the porter yaml
  15. PorterYamlVersion_V1 PorterYamlVersion = "v1stack"
  16. )
  17. // ParseYAML converts a Porter YAML file into a PorterApp proto object
  18. func ParseYAML(ctx context.Context, porterYaml []byte, appName string) ([]v2.AppWithPreviewOverrides, error) {
  19. ctx, span := telemetry.NewSpan(ctx, "porter-app-parse-yaml")
  20. defer span.End()
  21. var appDefinitions []v2.AppWithPreviewOverrides
  22. if porterYaml == nil {
  23. return appDefinitions, telemetry.Error(ctx, span, nil, "porter yaml input is nil")
  24. }
  25. version := &YamlVersion{}
  26. err := yaml.Unmarshal(porterYaml, version)
  27. if err != nil {
  28. return appDefinitions, telemetry.Error(ctx, span, err, "error unmarshaling porter yaml")
  29. }
  30. switch version.Version {
  31. case PorterYamlVersion_V2:
  32. appDefinitions, err = v2.AppProtoFromYaml(ctx, porterYaml, appName)
  33. if err != nil {
  34. return appDefinitions, telemetry.Error(ctx, span, err, "error converting v2 yaml to proto")
  35. }
  36. // backwards compatibility for old porter.yaml files
  37. // track this span in telemetry and reach out to customers who are still using old porter.yaml if they exist.
  38. // once no one is converting from old porter.yaml, we can remove this code
  39. case PorterYamlVersion_V1, "":
  40. appProto, envVariables, err := v1.AppProtoFromYaml(ctx, porterYaml, appName)
  41. if err != nil {
  42. return appDefinitions, telemetry.Error(ctx, span, err, "error converting v1 yaml to proto")
  43. }
  44. appDefinition := v2.AppWithPreviewOverrides{
  45. AppProtoWithEnv: v2.AppProtoWithEnv{
  46. AppProto: appProto,
  47. EnvVariables: envVariables,
  48. },
  49. }
  50. appDefinitions = append(appDefinitions, appDefinition)
  51. default:
  52. return appDefinitions, telemetry.Error(ctx, span, nil, "porter yaml version not supported")
  53. }
  54. if appDefinitions == nil {
  55. return appDefinitions, telemetry.Error(ctx, span, nil, "porter yaml output is nil")
  56. }
  57. var found bool
  58. for _, appDefinition := range appDefinitions {
  59. if appDefinition.AppProto.Name == "" {
  60. return appDefinitions, telemetry.Error(ctx, span, nil, "all apps must have a name")
  61. }
  62. if appDefinition.AppProto.Name == appName {
  63. found = true
  64. }
  65. }
  66. if appName != "" {
  67. telemetry.WithAttributes(span, telemetry.AttributeKV{Key: "override-name", Value: appName})
  68. if !found {
  69. return appDefinitions, telemetry.Error(ctx, span, nil, "no app names specified in porter.yaml match provided app name")
  70. }
  71. }
  72. return appDefinitions, nil
  73. }
  74. // yamlVersion is a struct used to unmarshal the version field of a Porter YAML file
  75. type YamlVersion struct {
  76. Version PorterYamlVersion `yaml:"version"`
  77. }