package v2beta1 // import ( // "context" // "fmt" // "os" // "strings" // "github.com/cli/cli/git" // "github.com/fatih/color" // "github.com/mitchellh/mapstructure" // api "github.com/porter-dev/porter/api/client" // apiTypes "github.com/porter-dev/porter/api/types" // "github.com/porter-dev/porter/cli/cmd/config" // "github.com/porter-dev/porter/cli/cmd/deploy" // "github.com/porter-dev/switchboard/v2/pkg/types" // ) // type DefaultDriver struct { // Vars map[string]string // Env map[string]string // Builds []*types.Build // APIClient *api.Client // Namespace string // allErrors []error // } // func (d *DefaultDriver) PreApply(resource *types.YAMLNode[*types.Resource]) error { // return nil // } // func (d *DefaultDriver) Apply(resource *types.YAMLNode[*types.Resource]) error { // if isPorterApp(resource) { // return d.applyPorterApp(resource) // } // // everything else is an addon // return d.applyAddon(resource) // } // func (d *DefaultDriver) PostApply(resource *types.YAMLNode[*types.Resource]) error { // return nil // } // func (d *DefaultDriver) OnError(resource *types.YAMLNode[*types.Resource], errs []error) { // } // func isPorterApp(resource *types.YAMLNode[*types.Resource]) bool { // if resource.GetValue().ChartURL.GetValue() == "https://charts.getporter.dev" && // (resource.GetValue().Type.GetValue() == "web" || // resource.GetValue().Type.GetValue() == "worker" || // resource.GetValue().Type.GetValue() == "job") { // return true // } // return false // } // func (d *DefaultDriver) applyPorterApp(resource *types.YAMLNode[*types.Resource]) error { // appBuild := &porterAppBuild{} // appDeploy := &porterAppDeploy{} // buildNode := resource.GetValue().Build.GetRawYAMLNode() // deployNode := resource.GetValue().Deploy.GetRawYAMLNode() // err := buildNode.Decode(appBuild) // if err != nil { // return err // FIXME: descriptive error // } // err = deployNode.Decode(appDeploy) // if err != nil { // return err // FIXME: descriptive error // } // var buildConfig *types.Build // if appBuild.Ref != "" { // for _, b := range d.Builds { // if b.Name.GetValue() == appBuild.Ref { // buildConfig = b // break // } // } // if buildConfig == nil { // // this should not happen // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+ // "error:\n-----\nERROR: invalid build ref given for app '%s'", resource.GetValue().Name.GetValue()) // } // } else { // buildConfig = appBuild.Build // } // if buildConfig == nil { // // this should not happen // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+ // "error:\n-----\nERROR: neither build ref nor build body given for app '%s'", resource.GetValue().Name.GetValue()) // } // if resource.GetValue().Type.GetValue() == "job" { // jobConfig := &porterJob{} // jobNode := resource.GetRawYAMLNode() // err := jobNode.Decode(jobConfig) // if err != nil { // return err // FIXME: descriptive error // } // return d.applyJob(resource, buildConfig, appDeploy, jobConfig) // } else if oneOf(resource.GetValue().Type.GetValue(), "web", "worker") { // } else { // // this should not happen // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+ // "error:\n-----\nERROR: app '%s' is not one of 'web', 'worker', 'job'", resource.GetValue().Name.GetValue()) // } // return nil // } // func (d *DefaultDriver) applyAddon(resource *types.YAMLNode[*types.Resource]) error { // return nil // } // func (d *DefaultDriver) applyJob( // resource *types.YAMLNode[*types.Resource], // buildConfig *types.Build, // appDeploy *porterAppDeploy, // jobConfig *porterJob, // ) error { // _, err := d.APIClient.GetRelease( // context.Background(), // config.GetCLIConfig().Project, // config.GetCLIConfig().Cluster, // d.Namespace, // resource.GetValue().Name.GetValue(), // ) // exists := err == nil // flattenedBuildEnv := make(map[string]string) // for k, v := range buildConfig.Env { // flattenedBuildEnv[k.GetValue()] = v.GetValue() // } // var flattenedBuildEnvGroup []apiTypes.EnvGroupMeta // for _, egName := range buildConfig.EnvGroups { // flattenedBuildEnvGroup = append(flattenedBuildEnvGroup, apiTypes.EnvGroupMeta{ // Name: egName.GetValue(), // Namespace: d.Namespace, // }) // } // tag := getImageTag() // sharedOpts := &deploy.SharedOpts{ // ProjectID: config.GetCLIConfig().Project, // ClusterID: config.GetCLIConfig().Cluster, // Namespace: d.Namespace, // LocalPath: buildConfig.Context.GetValue(), // LocalDockerfile: buildConfig.Dockerfile.GetValue(), // OverrideTag: tag, // Method: deploy.DeployBuildType(buildConfig.Method.GetValue()), // AdditionalEnv: flattenedBuildEnv, // EnvGroups: flattenedBuildEnvGroup, // } // if buildConfig.Method.GetValue() == "pack" && buildConfig.UseCache != nil { // sharedOpts.UseCache = buildConfig.UseCache.GetValue() // } // if exists { // if jobConfig.Once { // // since the job already exists and was marked 'once', simply return // return nil // } // updateAgent, err := deploy.NewDeployAgent(d.APIClient, resource.GetValue().Name.GetValue(), &deploy.DeployOpts{ // SharedOpts: sharedOpts, // Local: buildConfig.Method.GetValue() != "registry", // }) // if err != nil { // return fmt.Errorf("[porter.yaml v2][app:%s] error creating deploy agent to update app: %w", // resource.GetValue().Name.GetValue(), err) // } // // if the build method is registry, we do not trigger a build // if buildConfig.Method.GetValue() != "registry" { // buildEnv, err := updateAgent.GetBuildEnv(&deploy.GetBuildEnvOpts{ // UseNewConfig: true, // // NewConfig: appConf.Values, // }) // if err != nil { // return err // FIXME // } // err = updateAgent.SetBuildEnv(buildEnv) // if err != nil { // return err // FIXME // } // var bc *apiTypes.BuildConfig // if buildConfig.Method.GetValue() == "pack" { // // FIXME: temporary fix // var bp []string // for _, b := range buildConfig.Buildpacks { // bp = append(bp, b.GetValue()) // } // bc = &apiTypes.BuildConfig{ // Builder: buildConfig.Builder.GetValue(), // Buildpacks: bp, // } // } // err = updateAgent.Build(bc) // if err != nil { // return err // FIXME // } // // if !appConf.Build.UseCache { // FIXME // err = updateAgent.Push() // if err != nil { // return err // FIXME // } // // } // } // // err = updateAgent.UpdateImageAndValues(appConf.Values) // FIXME // // if err != nil { // // return err // FIXME // // } // } else { // create the job // // attempt to get repo suffix from environment variables // var repoSuffix string // if repoName := os.Getenv("PORTER_REPO_NAME"); repoName != "" { // if repoOwner := os.Getenv("PORTER_REPO_OWNER"); repoOwner != "" { // repoSuffix = strings.ToLower(strings.ReplaceAll(fmt.Sprintf("%s-%s", repoOwner, repoName), "_", "-")) // } // } // var registryURL string // if buildConfig.ImageRepoURI != nil { // registryURL = buildConfig.ImageRepoURI.GetValue() // } // if registryURL == "" { // regList, err := d.APIClient.ListRegistries(context.Background(), config.GetCLIConfig().Project) // if err != nil { // return fmt.Errorf("error fetching list of registries while trying to choose registry to deploy new"+ // " image for app '%s': %w", resource.GetValue().Name.GetValue(), err) // } // if len(*regList) == 0 { // return fmt.Errorf("no registries linked with project, needed to deploy new image for app '%s'", // resource.GetValue().Name.GetValue()) // } else { // registryURL = (*regList)[0].URL // } // } // createAgent := &deploy.CreateAgent{ // Client: d.APIClient, // CreateOpts: &deploy.CreateOpts{ // SharedOpts: sharedOpts, // Kind: resource.GetValue().Type.GetValue(), // ReleaseName: resource.GetValue().Name.GetValue(), // RegistryURL: registryURL, // RepoSuffix: repoSuffix, // }, // } // if buildConfig.Method.GetValue() == "registry" { // flattenedDeployMap := make(map[string]any) // for k, v := range resource.GetValue().Deploy.GetValue() { // flattenedDeployMap[k.GetValue()] = v.GetValue() // } // values := &porterWebChartValues{} // // delete the aliases from the deploy section // delete(flattenedDeployMap, "command") // delete(flattenedDeployMap, "cpu") // delete(flattenedDeployMap, "memory") // // replace alias values to the original expect yaml values // values.Container.Command = appDeploy.Command // values.Container.Env.Build = flattenedBuildEnv // values.Container.Env.Normal = appDeploy.Env // // values.Container.Env.Synced // values.Resources.Requests.CPU = appDeploy.CPU // values.Resources.Requests.Memory = appDeploy.Memory // if len(appDeploy.Hosts) > 0 { // values.Ingress.CustomDomain = true // values.Ingress.Hosts = appDeploy.Hosts // } // overrideValues := make(map[string]any) // err = mapstructure.Decode(values, &overrideValues) // if err != nil { // return err // FIXME // } // _, err := createAgent.CreateFromRegistry("", overrideValues) // if err != nil { // return fmt.Errorf("[porter.yaml v2][app:%s] error creating job: %w", resource.GetValue().Name.GetValue(), err) // } // } else if oneOf(buildConfig.Method.GetValue(), "pack", "docker") { // _, err := createAgent.CreateFromDocker(nil, "", nil) // if err != nil { // return fmt.Errorf("[porter.yaml v2][app:%s] error creating job: %w", resource.GetValue().Name.GetValue(), err) // } // } else { // // this should not happen // return fmt.Errorf("internal error: please let the Porter team know about this and quote the following "+ // "error:\n-----\nERROR: build method was not one of 'pack', 'docker', 'registry' for app '%s'", // resource.GetValue().Name.GetValue()) // } // } // return nil // } // // fetching the image tag works in 3 steps // // - read PORTER_TAG env var // // - read the git SHA from the current directory // // - default to 'latest' tag // func getImageTag() string { // tag := os.Getenv("PORTER_TAG") // if tag == "" { // commit, err := git.LastCommit() // if err == nil { // tag = commit.Sha[:7] // color.New(color.FgBlue).Printf("[porter.yaml v2] PORTER_TAG not defined, falling back to image tag '%s'"+ // " from git SHA\n", tag) // } // } else { // color.New(color.FgBlue).Printf("[porter.yaml v2] Using image tag '%s' from PORTER_TAG environment variable\n", tag) // } // if tag == "" { // color.New(color.FgBlue).Println("[porter.yaml v2] PORTER_TAG not defined, not a git repository, falling back" + // " to image tag 'latest'") // tag = "latest" // } // return tag // }