update_config_driver.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. package preview
  2. import (
  3. "context"
  4. "fmt"
  5. "os"
  6. "github.com/cli/cli/git"
  7. "github.com/fatih/color"
  8. "github.com/mitchellh/mapstructure"
  9. "github.com/porter-dev/porter/api/types"
  10. "github.com/porter-dev/porter/cli/cmd/config"
  11. "github.com/porter-dev/porter/cli/cmd/deploy"
  12. "github.com/porter-dev/switchboard/pkg/drivers"
  13. "github.com/porter-dev/switchboard/pkg/models"
  14. )
  15. type UpdateConfigDriverConfig struct {
  16. UpdateConfig struct {
  17. Image string
  18. } `mapstructure:"update_config"`
  19. EnvGroups []types.EnvGroupMeta `mapstructure:"env_groups"`
  20. Values map[string]interface{}
  21. }
  22. type UpdateConfigDriver struct {
  23. source *Source
  24. target *Target
  25. config *UpdateConfigDriverConfig
  26. lookupTable *map[string]drivers.Driver
  27. output map[string]interface{}
  28. }
  29. func NewUpdateConfigDriver(resource *models.Resource, opts *drivers.SharedDriverOpts) (drivers.Driver, error) {
  30. driver := &UpdateConfigDriver{
  31. lookupTable: opts.DriverLookupTable,
  32. output: make(map[string]interface{}),
  33. }
  34. source, err := GetSource(resource.Source)
  35. if err != nil {
  36. return nil, err
  37. }
  38. driver.source = source
  39. target, err := GetTarget(resource.Target)
  40. if err != nil {
  41. return nil, err
  42. }
  43. if target.AppName == "" {
  44. return nil, fmt.Errorf("target app_name is missing")
  45. }
  46. driver.target = target
  47. return driver, nil
  48. }
  49. func (d *UpdateConfigDriver) ShouldApply(resource *models.Resource) bool {
  50. return true
  51. }
  52. func (d *UpdateConfigDriver) Apply(resource *models.Resource) (*models.Resource, error) {
  53. updateConfigDriverConfig, err := d.getConfig(resource)
  54. if err != nil {
  55. return nil, err
  56. }
  57. d.config = updateConfigDriverConfig
  58. client := config.GetAPIClient()
  59. _, err = client.GetRelease(
  60. context.Background(),
  61. d.target.Project,
  62. d.target.Cluster,
  63. d.target.Namespace,
  64. d.target.AppName,
  65. )
  66. shouldCreate := err != nil
  67. // FIXME: give tag option in config build, but override if PORTER_TAG is present
  68. tag := os.Getenv("PORTER_TAG")
  69. if tag == "" {
  70. commit, err := git.LastCommit()
  71. if err != nil {
  72. return nil, err
  73. }
  74. tag = commit.Sha[:7]
  75. }
  76. sharedOpts := &deploy.SharedOpts{
  77. ProjectID: d.target.Project,
  78. ClusterID: d.target.Cluster,
  79. OverrideTag: tag,
  80. Namespace: d.target.Namespace,
  81. Method: "registry",
  82. EnvGroups: d.config.EnvGroups,
  83. }
  84. if shouldCreate {
  85. color.New(color.FgYellow).Printf("Could not read release %s/%s (%s): attempting creation\n", d.target.Namespace, d.target.AppName, err.Error())
  86. createAgent := &deploy.CreateAgent{
  87. Client: client,
  88. CreateOpts: &deploy.CreateOpts{
  89. SharedOpts: sharedOpts,
  90. Kind: d.source.Name,
  91. ReleaseName: d.target.AppName,
  92. },
  93. }
  94. subdomain, err := createAgent.CreateFromRegistry(d.config.UpdateConfig.Image, d.config.Values)
  95. if err != nil {
  96. return nil, err
  97. }
  98. d.output["live_url"] = subdomain
  99. } else {
  100. updateAgent, err := deploy.NewDeployAgent(client, d.target.AppName, &deploy.DeployOpts{
  101. SharedOpts: sharedOpts,
  102. Local: false,
  103. })
  104. if err != nil {
  105. return nil, err
  106. }
  107. err = updateAgent.UpdateImageAndValues(d.config.Values)
  108. if err != nil {
  109. return nil, err
  110. }
  111. }
  112. return resource, nil
  113. }
  114. func (d *UpdateConfigDriver) Output() (map[string]interface{}, error) {
  115. return d.output, nil
  116. }
  117. func (d *UpdateConfigDriver) getConfig(resource *models.Resource) (*UpdateConfigDriverConfig, error) {
  118. populatedConf, err := drivers.ConstructConfig(&drivers.ConstructConfigOpts{
  119. RawConf: resource.Config,
  120. LookupTable: *d.lookupTable,
  121. Dependencies: resource.Dependencies,
  122. })
  123. if err != nil {
  124. return nil, err
  125. }
  126. config := &UpdateConfigDriverConfig{}
  127. err = mapstructure.Decode(populatedConf, config)
  128. if err != nil {
  129. return nil, err
  130. }
  131. return config, nil
  132. }