default_driver.go 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375
  1. package v2beta1
  2. // import (
  3. // "context"
  4. // "fmt"
  5. // "os"
  6. // "strings"
  7. // "github.com/cli/cli/git"
  8. // "github.com/fatih/color"
  9. // "github.com/mitchellh/mapstructure"
  10. // api "github.com/porter-dev/porter/api/client"
  11. // apiTypes "github.com/porter-dev/porter/api/types"
  12. // "github.com/porter-dev/porter/cli/cmd/config"
  13. // "github.com/porter-dev/porter/cli/cmd/deploy"
  14. // "github.com/porter-dev/switchboard/v2/pkg/types"
  15. // )
  16. // type DefaultDriver struct {
  17. // Vars map[string]string
  18. // Env map[string]string
  19. // Builds []*types.Build
  20. // APIClient *api.Client
  21. // Namespace string
  22. // allErrors []error
  23. // }
  24. // func (d *DefaultDriver) PreApply(resource *types.YAMLNode[*types.Resource]) error {
  25. // return nil
  26. // }
  27. // func (d *DefaultDriver) Apply(resource *types.YAMLNode[*types.Resource]) error {
  28. // if isPorterApp(resource) {
  29. // return d.applyPorterApp(resource)
  30. // }
  31. // // everything else is an addon
  32. // return d.applyAddon(resource)
  33. // }
  34. // func (d *DefaultDriver) PostApply(resource *types.YAMLNode[*types.Resource]) error {
  35. // return nil
  36. // }
  37. // func (d *DefaultDriver) OnError(resource *types.YAMLNode[*types.Resource], errs []error) {
  38. // }
  39. // func isPorterApp(resource *types.YAMLNode[*types.Resource]) bool {
  40. // if resource.GetValue().ChartURL.GetValue() == "https://charts.getporter.dev" &&
  41. // (resource.GetValue().Type.GetValue() == "web" ||
  42. // resource.GetValue().Type.GetValue() == "worker" ||
  43. // resource.GetValue().Type.GetValue() == "job") {
  44. // return true
  45. // }
  46. // return false
  47. // }
  48. // func (d *DefaultDriver) applyPorterApp(resource *types.YAMLNode[*types.Resource]) error {
  49. // appBuild := &porterAppBuild{}
  50. // appDeploy := &porterAppDeploy{}
  51. // buildNode := resource.GetValue().Build.GetRawYAMLNode()
  52. // deployNode := resource.GetValue().Deploy.GetRawYAMLNode()
  53. // err := buildNode.Decode(appBuild)
  54. // if err != nil {
  55. // return err // FIXME: descriptive error
  56. // }
  57. // err = deployNode.Decode(appDeploy)
  58. // if err != nil {
  59. // return err // FIXME: descriptive error
  60. // }
  61. // var buildConfig *types.Build
  62. // if appBuild.Ref != "" {
  63. // for _, b := range d.Builds {
  64. // if b.Name.GetValue() == appBuild.Ref {
  65. // buildConfig = b
  66. // break
  67. // }
  68. // }
  69. // if buildConfig == nil {
  70. // // this should not happen
  71. // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+
  72. // "error:\n-----\nERROR: invalid build ref given for app '%s'", resource.GetValue().Name.GetValue())
  73. // }
  74. // } else {
  75. // buildConfig = appBuild.Build
  76. // }
  77. // if buildConfig == nil {
  78. // // this should not happen
  79. // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+
  80. // "error:\n-----\nERROR: neither build ref nor build body given for app '%s'", resource.GetValue().Name.GetValue())
  81. // }
  82. // if resource.GetValue().Type.GetValue() == "job" {
  83. // jobConfig := &porterJob{}
  84. // jobNode := resource.GetRawYAMLNode()
  85. // err := jobNode.Decode(jobConfig)
  86. // if err != nil {
  87. // return err // FIXME: descriptive error
  88. // }
  89. // return d.applyJob(resource, buildConfig, appDeploy, jobConfig)
  90. // } else if oneOf(resource.GetValue().Type.GetValue(), "web", "worker") {
  91. // } else {
  92. // // this should not happen
  93. // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+
  94. // "error:\n-----\nERROR: app '%s' is not one of 'web', 'worker', 'job'", resource.GetValue().Name.GetValue())
  95. // }
  96. // return nil
  97. // }
  98. // func (d *DefaultDriver) applyAddon(resource *types.YAMLNode[*types.Resource]) error {
  99. // return nil
  100. // }
  101. // func (d *DefaultDriver) applyJob(
  102. // resource *types.YAMLNode[*types.Resource],
  103. // buildConfig *types.Build,
  104. // appDeploy *porterAppDeploy,
  105. // jobConfig *porterJob,
  106. // ) error {
  107. // _, err := d.APIClient.GetRelease(
  108. // context.Background(),
  109. // config.GetCLIConfig().Project,
  110. // config.GetCLIConfig().Cluster,
  111. // d.Namespace,
  112. // resource.GetValue().Name.GetValue(),
  113. // )
  114. // exists := err == nil
  115. // flattenedBuildEnv := make(map[string]string)
  116. // for k, v := range buildConfig.Env {
  117. // flattenedBuildEnv[k.GetValue()] = v.GetValue()
  118. // }
  119. // var flattenedBuildEnvGroup []apiTypes.EnvGroupMeta
  120. // for _, egName := range buildConfig.EnvGroups {
  121. // flattenedBuildEnvGroup = append(flattenedBuildEnvGroup, apiTypes.EnvGroupMeta{
  122. // Name: egName.GetValue(),
  123. // Namespace: d.Namespace,
  124. // })
  125. // }
  126. // tag := getImageTag()
  127. // sharedOpts := &deploy.SharedOpts{
  128. // ProjectID: config.GetCLIConfig().Project,
  129. // ClusterID: config.GetCLIConfig().Cluster,
  130. // Namespace: d.Namespace,
  131. // LocalPath: buildConfig.Context.GetValue(),
  132. // LocalDockerfile: buildConfig.Dockerfile.GetValue(),
  133. // OverrideTag: tag,
  134. // Method: deploy.DeployBuildType(buildConfig.Method.GetValue()),
  135. // AdditionalEnv: flattenedBuildEnv,
  136. // EnvGroups: flattenedBuildEnvGroup,
  137. // }
  138. // if buildConfig.Method.GetValue() == "pack" && buildConfig.UseCache != nil {
  139. // sharedOpts.UseCache = buildConfig.UseCache.GetValue()
  140. // }
  141. // if exists {
  142. // if jobConfig.Once {
  143. // // since the job already exists and was marked 'once', simply return
  144. // return nil
  145. // }
  146. // updateAgent, err := deploy.NewDeployAgent(d.APIClient, resource.GetValue().Name.GetValue(), &deploy.DeployOpts{
  147. // SharedOpts: sharedOpts,
  148. // Local: buildConfig.Method.GetValue() != "registry",
  149. // })
  150. // if err != nil {
  151. // return fmt.Errorf("[porter.yaml v2][app:%s] error creating deploy agent to update app: %w",
  152. // resource.GetValue().Name.GetValue(), err)
  153. // }
  154. // // if the build method is registry, we do not trigger a build
  155. // if buildConfig.Method.GetValue() != "registry" {
  156. // buildEnv, err := updateAgent.GetBuildEnv(&deploy.GetBuildEnvOpts{
  157. // UseNewConfig: true,
  158. // // NewConfig: appConf.Values,
  159. // })
  160. // if err != nil {
  161. // return err // FIXME
  162. // }
  163. // err = updateAgent.SetBuildEnv(buildEnv)
  164. // if err != nil {
  165. // return err // FIXME
  166. // }
  167. // var bc *apiTypes.BuildConfig
  168. // if buildConfig.Method.GetValue() == "pack" {
  169. // // FIXME: temporary fix
  170. // var bp []string
  171. // for _, b := range buildConfig.Buildpacks {
  172. // bp = append(bp, b.GetValue())
  173. // }
  174. // bc = &apiTypes.BuildConfig{
  175. // Builder: buildConfig.Builder.GetValue(),
  176. // Buildpacks: bp,
  177. // }
  178. // }
  179. // err = updateAgent.Build(bc)
  180. // if err != nil {
  181. // return err // FIXME
  182. // }
  183. // // if !appConf.Build.UseCache { // FIXME
  184. // err = updateAgent.Push()
  185. // if err != nil {
  186. // return err // FIXME
  187. // }
  188. // // }
  189. // }
  190. // // err = updateAgent.UpdateImageAndValues(appConf.Values) // FIXME
  191. // // if err != nil {
  192. // // return err // FIXME
  193. // // }
  194. // } else { // create the job
  195. // // attempt to get repo suffix from environment variables
  196. // var repoSuffix string
  197. // if repoName := os.Getenv("PORTER_REPO_NAME"); repoName != "" {
  198. // if repoOwner := os.Getenv("PORTER_REPO_OWNER"); repoOwner != "" {
  199. // repoSuffix = strings.ToLower(strings.ReplaceAll(fmt.Sprintf("%s-%s", repoOwner, repoName), "_", "-"))
  200. // }
  201. // }
  202. // var registryURL string
  203. // if buildConfig.ImageRepoURI != nil {
  204. // registryURL = buildConfig.ImageRepoURI.GetValue()
  205. // }
  206. // if registryURL == "" {
  207. // regList, err := d.APIClient.ListRegistries(context.Background(), config.GetCLIConfig().Project)
  208. // if err != nil {
  209. // return fmt.Errorf("error fetching list of registries while trying to choose registry to deploy new"+
  210. // " image for app '%s': %w", resource.GetValue().Name.GetValue(), err)
  211. // }
  212. // if len(*regList) == 0 {
  213. // return fmt.Errorf("no registries linked with project, needed to deploy new image for app '%s'",
  214. // resource.GetValue().Name.GetValue())
  215. // } else {
  216. // registryURL = (*regList)[0].URL
  217. // }
  218. // }
  219. // createAgent := &deploy.CreateAgent{
  220. // Client: d.APIClient,
  221. // CreateOpts: &deploy.CreateOpts{
  222. // SharedOpts: sharedOpts,
  223. // Kind: resource.GetValue().Type.GetValue(),
  224. // ReleaseName: resource.GetValue().Name.GetValue(),
  225. // RegistryURL: registryURL,
  226. // RepoSuffix: repoSuffix,
  227. // },
  228. // }
  229. // if buildConfig.Method.GetValue() == "registry" {
  230. // flattenedDeployMap := make(map[string]any)
  231. // for k, v := range resource.GetValue().Deploy.GetValue() {
  232. // flattenedDeployMap[k.GetValue()] = v.GetValue()
  233. // }
  234. // values := &porterWebChartValues{}
  235. // // delete the aliases from the deploy section
  236. // delete(flattenedDeployMap, "command")
  237. // delete(flattenedDeployMap, "cpu")
  238. // delete(flattenedDeployMap, "memory")
  239. // // replace alias values to the original expect yaml values
  240. // values.Container.Command = appDeploy.Command
  241. // values.Container.Env.Build = flattenedBuildEnv
  242. // values.Container.Env.Normal = appDeploy.Env
  243. // // values.Container.Env.Synced
  244. // values.Resources.Requests.CPU = appDeploy.CPU
  245. // values.Resources.Requests.Memory = appDeploy.Memory
  246. // if len(appDeploy.Hosts) > 0 {
  247. // values.Ingress.CustomDomain = true
  248. // values.Ingress.Hosts = appDeploy.Hosts
  249. // }
  250. // overrideValues := make(map[string]any)
  251. // err = mapstructure.Decode(values, &overrideValues)
  252. // if err != nil {
  253. // return err // FIXME
  254. // }
  255. // _, err := createAgent.CreateFromRegistry("", overrideValues)
  256. // if err != nil {
  257. // return fmt.Errorf("[porter.yaml v2][app:%s] error creating job: %w", resource.GetValue().Name.GetValue(), err)
  258. // }
  259. // } else if oneOf(buildConfig.Method.GetValue(), "pack", "docker") {
  260. // _, err := createAgent.CreateFromDocker(nil, "", nil)
  261. // if err != nil {
  262. // return fmt.Errorf("[porter.yaml v2][app:%s] error creating job: %w", resource.GetValue().Name.GetValue(), err)
  263. // }
  264. // } else {
  265. // // this should not happen
  266. // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+
  267. // "error:\n-----\nERROR: build method was not one of 'pack', 'docker', 'registry' for app '%s'",
  268. // resource.GetValue().Name.GetValue())
  269. // }
  270. // }
  271. // return nil
  272. // }
  273. // // fetching the image tag works in 3 steps
  274. // // - read PORTER_TAG env var
  275. // // - read the git SHA from the current directory
  276. // // - default to 'latest' tag
  277. // func getImageTag() string {
  278. // tag := os.Getenv("PORTER_TAG")
  279. // if tag == "" {
  280. // commit, err := git.LastCommit()
  281. // if err == nil {
  282. // tag = commit.Sha[:7]
  283. // color.New(color.FgBlue).Printf("[porter.yaml v2] PORTER_TAG not defined, falling back to image tag '%s'"+
  284. // " from git SHA\n", tag)
  285. // }
  286. // } else {
  287. // color.New(color.FgBlue).Printf("[porter.yaml v2] Using image tag '%s' from PORTER_TAG environment variable\n", tag)
  288. // }
  289. // if tag == "" {
  290. // color.New(color.FgBlue).Println("[porter.yaml v2] PORTER_TAG not defined, not a git repository, falling back" +
  291. // " to image tag 'latest'")
  292. // tag = "latest"
  293. // }
  294. // return tag
  295. // }