apply.go 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201
  1. package cmd
  2. import (
  3. "io/ioutil"
  4. "os"
  5. "strconv"
  6. api "github.com/porter-dev/porter/api/client"
  7. "github.com/porter-dev/porter/api/types"
  8. "github.com/porter-dev/switchboard/pkg/drivers"
  9. "github.com/porter-dev/switchboard/pkg/models"
  10. "github.com/porter-dev/switchboard/pkg/parser"
  11. switchboardTypes "github.com/porter-dev/switchboard/pkg/types"
  12. "github.com/porter-dev/switchboard/pkg/worker"
  13. "github.com/porter-dev/switchboard/utils/objutils"
  14. "github.com/rs/zerolog"
  15. "github.com/spf13/cobra"
  16. )
  17. // applyCmd represents the "porter apply" base command when called
  18. // with a porter.yaml file as an argument
  19. var applyCmd = &cobra.Command{
  20. Use: "apply",
  21. Short: "Applies the provided porter.yaml to a project",
  22. Run: func(cmd *cobra.Command, args []string) {
  23. err := checkLoginAndRun(args, apply)
  24. if err != nil {
  25. os.Exit(1)
  26. }
  27. },
  28. }
  29. var porterYAML string
  30. func init() {
  31. rootCmd.AddCommand(applyCmd)
  32. applyCmd.Flags().StringVarP(&porterYAML, "file", "f", "", "path to porter.yaml")
  33. applyCmd.MarkFlagRequired("file")
  34. }
  35. func apply(_ *types.GetAuthenticatedUserResponse, client *api.Client, args []string) error {
  36. fileBytes, err := ioutil.ReadFile(porterYAML)
  37. if err != nil {
  38. return err
  39. }
  40. resGroup, err := parser.ParseRawBytes(fileBytes)
  41. if err != nil {
  42. return err
  43. }
  44. basePath, err := os.Getwd()
  45. if err != nil {
  46. return err
  47. }
  48. worker := worker.NewWorker()
  49. worker.RegisterDriver("porter.deploy", NewPorterDriver)
  50. return worker.Apply(resGroup, &switchboardTypes.ApplyOpts{
  51. BasePath: basePath,
  52. })
  53. }
  54. type Source struct {
  55. Name string
  56. Repo string
  57. Version string
  58. }
  59. type Target struct {
  60. Project uint
  61. Cluster uint
  62. Namespace string
  63. }
  64. type Driver struct {
  65. source *Source
  66. target *Target
  67. output map[string]interface{}
  68. lookupTable *map[string]drivers.Driver
  69. logger *zerolog.Logger
  70. }
  71. func NewPorterDriver(resource *models.Resource, opts *drivers.SharedDriverOpts) (drivers.Driver, error) {
  72. driver := &Driver{
  73. lookupTable: opts.DriverLookupTable,
  74. logger: opts.Logger,
  75. }
  76. if resource.Source != nil {
  77. source, err := getSource(resource.Source)
  78. if err != nil {
  79. return nil, err
  80. }
  81. driver.source = source
  82. } else {
  83. // default source
  84. driver.source = &Source{
  85. Name: "web",
  86. Repo: "https://charts.getporter.dev",
  87. Version: "v0.13.0",
  88. }
  89. }
  90. if resource.Target != nil {
  91. target, err := getTarget(resource.Target)
  92. if err != nil {
  93. return nil, err
  94. }
  95. driver.target = target
  96. } else {
  97. // default target
  98. driver.target = &Target{
  99. Project: config.Project,
  100. Cluster: config.Cluster,
  101. Namespace: "default",
  102. }
  103. }
  104. return driver, nil
  105. }
  106. func (d *Driver) ShouldApply(resource *models.Resource) bool {
  107. return true
  108. }
  109. func (d *Driver) Apply(resource *models.Resource) (*models.Resource, error) {
  110. app = resource.Name
  111. config.SetProject(d.target.Project)
  112. config.SetCluster(d.target.Cluster)
  113. err := updateFull(nil, GetAPIClient(config), []string{})
  114. if err != nil {
  115. return nil, err
  116. }
  117. return resource, nil
  118. }
  119. func (d *Driver) Output() (map[string]interface{}, error) {
  120. return d.output, nil
  121. }
  122. func getSource(genericSource map[string]interface{}) (*Source, error) {
  123. source := &Source{}
  124. name, err := objutils.GetNestedString(genericSource, "name")
  125. if err != nil {
  126. return nil, err
  127. }
  128. source.Name = name
  129. repo, err := objutils.GetNestedString(genericSource, "repo")
  130. if err != nil {
  131. return nil, err
  132. }
  133. source.Repo = repo
  134. version, err := objutils.GetNestedString(genericSource, "version")
  135. if err != nil {
  136. return nil, err
  137. }
  138. source.Version = version
  139. return source, nil
  140. }
  141. func getTarget(genericTarget map[string]interface{}) (*Target, error) {
  142. target := &Target{}
  143. project, err := objutils.GetNestedString(genericTarget, "project")
  144. if err != nil {
  145. return nil, err
  146. }
  147. projectNum, err := strconv.Atoi(project)
  148. if err != nil {
  149. return nil, err
  150. }
  151. target.Project = uint(projectNum)
  152. cluster, err := objutils.GetNestedString(genericTarget, "cluster")
  153. if err != nil {
  154. return nil, err
  155. }
  156. clusterNum, err := strconv.Atoi(cluster)
  157. if err != nil {
  158. return nil, err
  159. }
  160. target.Cluster = uint(clusterNum)
  161. namespace, err := objutils.GetNestedString(genericTarget, "namespace")
  162. if err != nil {
  163. return nil, err
  164. }
  165. target.Namespace = namespace
  166. return target, nil
  167. }