From 46fc1aaaf5bad9bd721804f1fd1b64b7b2db534b Mon Sep 17 00:00:00 2001 From: Sebastian Florek Date: Fri, 24 Apr 2026 14:24:07 +0200 Subject: [PATCH] fix(up): fix dry-run for plural up across all providers --- cmd/command/up/up.go | 5 +-- pkg/client/plural.go | 15 ++++--- pkg/provider/aws.go | 6 +++ pkg/provider/azure.go | 7 +++- pkg/provider/byok.go | 11 ++++- pkg/provider/gcp/option.go | 8 ++++ pkg/up/context.go | 60 +++++++++++++------------- pkg/up/deploy.go | 79 +++++++++++++++++----------------- pkg/up/generate.go | 86 +++++++++++++++++++------------------- pkg/up/prune.go | 16 +++---- pkg/up/template.go | 57 ++++++++++++------------- 11 files changed, 190 insertions(+), 160 deletions(-) diff --git a/cmd/command/up/up.go b/cmd/command/up/up.go index ac88948d..15b16d2e 100644 --- a/cmd/command/up/up.go +++ b/cmd/command/up/up.go @@ -122,12 +122,11 @@ func (p *Plural) handleUp(c *cli.Context) error { return err } - ctx, err := up.Build(c.Bool("cloud")) - ctx.IgnorePreflights(c.Bool("ignore-preflights") || c.Bool("dry-run")) - + ctx, err := up.Build(cloud) if err != nil { return err } + ctx.IgnorePreflights(c.Bool("ignore-preflights") || dryRun) byok := ctx.Provider.Name() == api.BYOK diff --git a/pkg/client/plural.go b/pkg/client/plural.go index 0d11537d..acc8dcb9 100644 --- a/pkg/client/plural.go +++ b/pkg/client/plural.go @@ -8,23 +8,25 @@ import ( "strings" "github.com/pluralsh/console/go/polly/algorithms" - gitutils "github.com/pluralsh/plural-cli/pkg/utils/git" "github.com/samber/lo" apierrors "k8s.io/apimachinery/pkg/api/errors" + gitutils "github.com/pluralsh/plural-cli/pkg/utils/git" + "github.com/urfave/cli" "github.com/pluralsh/plural-cli/pkg/common" "github.com/pluralsh/plural-cli/pkg/scm" "github.com/pluralsh/plural-cli/pkg/wkspace" + "sigs.k8s.io/yaml" + "github.com/pluralsh/plural-cli/pkg/api" "github.com/pluralsh/plural-cli/pkg/config" "github.com/pluralsh/plural-cli/pkg/console" "github.com/pluralsh/plural-cli/pkg/kubernetes" "github.com/pluralsh/plural-cli/pkg/manifest" "github.com/pluralsh/plural-cli/pkg/utils" - "sigs.k8s.io/yaml" ) type Plural struct { @@ -106,13 +108,14 @@ func (p *Plural) HandleInit(c *cli.Context) error { return err } -func (p *Plural) HandleInitWithProject(c *cli.Context) (*manifest.ProjectManifest, error) { +func (p *Plural) HandleInitWithProject(c *cli.Context) (project *manifest.ProjectManifest, err error) { gitCreated := false repo := "" + dryRun := c.Bool("dry-run") p.InitPluralClient() - git, err := wkspace.Preflight(c.Bool("dry-run"), c.Bool("ignore-preflights")) - if err != nil && (git || c.Bool("dry-run")) { + git, err := wkspace.Preflight(dryRun, c.Bool("ignore-preflights")) + if err != nil && (git || dryRun) { return nil, err } @@ -156,7 +159,7 @@ func (p *Plural) HandleInitWithProject(c *cli.Context) (*manifest.ProjectManifes return nil, err } - project, err := manifest.FetchProject() + project, err = manifest.FetchProject() if err != nil { return nil, err } diff --git a/pkg/provider/aws.go b/pkg/provider/aws.go index ebefa8c6..ef3571f5 100644 --- a/pkg/provider/aws.go +++ b/pkg/provider/aws.go @@ -76,6 +76,12 @@ func mkAWS(conf config.Config, dryRun bool) (provider *AWSProvider, err error) { ctx := context.Background() provider = &AWSProvider{} if dryRun { + projectManifest := manifest.ProjectManifest{ + Provider: api.ProviderAWS, + Owner: &manifest.Owner{Email: conf.Email, Endpoint: conf.Endpoint}, + } + + provider.writer = func() error { return projectManifest.Write(manifest.ProjectManifestPath()) } return provider, nil } iamSession, callerIdentity, err := GetAWSCallerIdentity(ctx) diff --git a/pkg/provider/azure.go b/pkg/provider/azure.go index ee828d4a..248bdd5e 100644 --- a/pkg/provider/azure.go +++ b/pkg/provider/azure.go @@ -89,6 +89,11 @@ type AzureProvider struct { func mkAzure(conf config.Config, dryRun bool) (prov *AzureProvider, err error) { prov = &AzureProvider{} if dryRun { + projectManifest := manifest.ProjectManifest{ + Provider: api.ProviderAzure, + Owner: &manifest.Owner{Email: conf.Email, Endpoint: conf.Endpoint}, + } + prov.writer = func() error { return projectManifest.Write(manifest.ProjectManifestPath()) } return prov, nil } subId, tenID, subName, err := GetAzureAccount() @@ -155,7 +160,7 @@ func mkAzure(conf config.Config, dryRun bool) (prov *AzureProvider, err error) { func AzureFromManifest(man *manifest.ProjectManifest, clientSet *ClientSet) (*AzureProvider, error) { var err error clients := clientSet - if clientSet == nil { + if clientSet == nil && utils.ToString(man.Context["SubscriptionId"]) != "" { clients, err = GetClientSet(utils.ToString(man.Context["SubscriptionId"])) if err != nil { return nil, err diff --git a/pkg/provider/byok.go b/pkg/provider/byok.go index c2321bf7..c3c4cec5 100644 --- a/pkg/provider/byok.go +++ b/pkg/provider/byok.go @@ -8,6 +8,9 @@ import ( "strings" "github.com/AlecAivazis/survey/v2" + "k8s.io/client-go/tools/clientcmd" + clientcmdapi "k8s.io/client-go/tools/clientcmd/api" + "github.com/pluralsh/plural-cli/pkg/api" "github.com/pluralsh/plural-cli/pkg/config" "github.com/pluralsh/plural-cli/pkg/kubernetes" @@ -15,8 +18,6 @@ import ( "github.com/pluralsh/plural-cli/pkg/provider/permissions" "github.com/pluralsh/plural-cli/pkg/provider/preflights" "github.com/pluralsh/plural-cli/pkg/utils" - "k8s.io/client-go/tools/clientcmd" - clientcmdapi "k8s.io/client-go/tools/clientcmd/api" ) const defaultValue = "default" @@ -42,6 +43,12 @@ func mkBYOK(conf config.Config, name string, dryRun, cloud bool) (prov *ByokProv ctx: map[string]interface{}{}, } if dryRun { + projectManifest := manifest.ProjectManifest{ + Provider: api.BYOK, + Owner: &manifest.Owner{Email: conf.Email, Endpoint: conf.Endpoint}, + } + + prov.writer = func() error { return projectManifest.Write(manifest.ProjectManifestPath()) } return prov, nil } diff --git a/pkg/provider/gcp/option.go b/pkg/provider/gcp/option.go index 93ee2b9f..f8c990b5 100644 --- a/pkg/provider/gcp/option.go +++ b/pkg/provider/gcp/option.go @@ -14,6 +14,14 @@ type Option func(*Provider) error func WithConfig(c config.Config, defaultCluster string, cloudEnabled, dryRun bool) Option { return func(gcp *Provider) error { if dryRun { + projectManifest := manifest.ProjectManifest{ + Bucket: "dry-run", + Provider: api.ProviderGCP, + Owner: &manifest.Owner{Email: c.Email, Endpoint: c.Endpoint}, + } + gcp.InputProvider = NewReadonlyInputProvider(defaultCluster, "", "") + gcp.bucket = projectManifest.Bucket + gcp.writer = func() error { return projectManifest.Write(manifest.ProjectManifestPath()) } return nil } err := printUserInfo() diff --git a/pkg/up/context.go b/pkg/up/context.go index fb5f2c30..bf32f61b 100644 --- a/pkg/up/context.go +++ b/pkg/up/context.go @@ -42,70 +42,70 @@ type delims struct { right string } -func (ctx *Context) identifier() string { - if ctx.RepoUrl == "" { +func (c *Context) identifier() string { + if c.RepoUrl == "" { return "" } - if strings.HasPrefix(ctx.RepoUrl, "http") { - parsed, err := giturls.Parse(ctx.RepoUrl) + if strings.HasPrefix(c.RepoUrl, "http") { + parsed, err := giturls.Parse(c.RepoUrl) if err == nil { return strings.TrimSuffix(strings.TrimPrefix(parsed.Path, "/"), ".git") } } - split := strings.Split(ctx.RepoUrl, ":") + split := strings.Split(c.RepoUrl, ":") return strings.TrimSuffix(split[len(split)-1], ".git") } -func (ctx *Context) changeDelims() { - ctx.Delims = &delims{"[[", "]]"} +func (c *Context) changeDelims() { + c.Delims = &delims{"[[", "]]"} } -func (ctx *Context) IgnorePreflights(ignore bool) { - ctx.ignorePreflights = ignore +func (c *Context) IgnorePreflights(ignore bool) { + c.ignorePreflights = ignore } -func (ctx *Context) SetImportCluster(id string) { - ctx.ImportCluster = lo.ToPtr(id) +func (c *Context) SetImportCluster(id string) { + c.ImportCluster = lo.ToPtr(id) } -func (ctx *Context) Backfill() error { +func (c *Context) Backfill() error { context, err := manifest.FetchContext() if err != nil { - return ctx.backfillConsoleContext(ctx.Manifest) + return c.backfillConsoleContext(c.Manifest) } console, ok := context.Configuration["console"] if !ok { - return ctx.backfillConsoleContext(ctx.Manifest) + return c.backfillConsoleContext(c.Manifest) } _, hasSSH := console["private_key"] _, hasHTTPS := console["git_password"] if !hasSSH && !hasHTTPS { - return ctx.backfillConsoleContext(ctx.Manifest) + return c.backfillConsoleContext(c.Manifest) } if v, ok := console["repo_url"]; ok { if r, ok := v.(string); ok { - ctx.RepoUrl = r + c.RepoUrl = r } } if v, ok := console["git_username"]; ok { if s, ok := v.(string); ok { - ctx.GitUsername = s + c.GitUsername = s } } if v, ok := console["git_password"]; ok { if s, ok := v.(string); ok { - ctx.GitPassword = s + c.GitPassword = s } } - if ctx.RepoUrl == "" { + if c.RepoUrl == "" { return fmt.Errorf("you never configured a repoUrl for your workspace, check `context.yaml`") } @@ -133,7 +133,7 @@ func Build(cloud bool) (*Context, error) { }, nil } -func (context *Context) backfillConsoleContext(_ *manifest.ProjectManifest) error { +func (c *Context) backfillConsoleContext(_ *manifest.ProjectManifest) error { path := manifest.ContextPath() ctx, err := manifest.FetchContext() if err != nil { @@ -153,13 +153,13 @@ func (context *Context) backfillConsoleContext(_ *manifest.ProjectManifest) erro } if strings.HasPrefix(url, "http") { - return context.backfillHTTPS(url, console, ctx, path) + return c.backfillHTTPS(url, console, ctx, path) } - return context.backfillSSH(url, console, ctx, path) + return c.backfillSSH(url, console, ctx, path) } -func (context *Context) backfillSSH(url string, console map[string]interface{}, ctx *manifest.Context, path string) error { +func (c *Context) backfillSSH(url string, console map[string]interface{}, ctx *manifest.Context, path string) error { utils.Highlight("If you want, you can use `plural crypto ssh-keygen` to generate a keypair to use as a deploy key as well\n\n") files, err := filepath.Glob(filepath.Join(os.Getenv("HOME"), ".ssh", "*")) @@ -188,7 +188,7 @@ func (context *Context) backfillSSH(url string, console map[string]interface{}, return err } - if !context.ignorePreflights { + if !c.ignorePreflights { if err := verifySSHKey(contents, url); err != nil { return fmt.Errorf("ssh key not valid for url %s, error: %w. If you want to bypass this check, you can use the --ignore-preflights flag", url, err) } @@ -197,11 +197,11 @@ func (context *Context) backfillSSH(url string, console map[string]interface{}, console["repo_url"] = url console["private_key"] = contents ctx.Configuration["console"] = console - context.RepoUrl = url + c.RepoUrl = url return ctx.Write(path) } -func (context *Context) backfillHTTPS(url string, console map[string]interface{}, ctx *manifest.Context, path string) error { +func (c *Context) backfillHTTPS(url string, console map[string]interface{}, ctx *manifest.Context, path string) error { utils.Highlight("If you want, you can also reclone with an SSH URL and re-run to use deploy-key authentication instead\n\n") var username, token string @@ -219,7 +219,7 @@ func (context *Context) backfillHTTPS(url string, console map[string]interface{} return err } - if !context.ignorePreflights { + if !c.ignorePreflights { if err := verifyHTTPS(username, token, url); err != nil { return fmt.Errorf("PAT not valid for url %s, error: %w. If you want to bypass this check, you can use the --ignore-preflights flag", url, err) } @@ -229,9 +229,9 @@ func (context *Context) backfillHTTPS(url string, console map[string]interface{} console["git_username"] = username console["git_password"] = token ctx.Configuration["console"] = console - context.RepoUrl = url - context.GitUsername = username - context.GitPassword = token + c.RepoUrl = url + c.GitUsername = username + c.GitPassword = token return ctx.Write(path) } diff --git a/pkg/up/deploy.go b/pkg/up/deploy.go index de1e2f5e..c432732f 100644 --- a/pkg/up/deploy.go +++ b/pkg/up/deploy.go @@ -8,12 +8,13 @@ import ( "os/exec" "time" - "github.com/pluralsh/plural-cli/pkg/api" - "github.com/pluralsh/plural-cli/pkg/kubernetes" "github.com/samber/lo" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/pluralsh/plural-cli/pkg/api" + "github.com/pluralsh/plural-cli/pkg/kubernetes" + "github.com/pluralsh/plural-cli/pkg/utils" ) @@ -44,11 +45,11 @@ func init() { } } -func (ctx *Context) runCheckpoint(current, checkpoint string, fn func() error) error { +func (c *Context) runCheckpoint(current, checkpoint string, fn func() error) error { if current == "" || priorities[checkpoint] > priorities[current] { err := fn() if err == nil { - ctx.Manifest.Checkpoint = checkpoint + c.Manifest.Checkpoint = checkpoint } return err } @@ -58,21 +59,21 @@ func (ctx *Context) runCheckpoint(current, checkpoint string, fn func() error) e return nil } -func (ctx *Context) Deploy(commit func() error) error { - if ctx.Provider.Name() == api.BYOK && ctx.Cloud { +func (c *Context) Deploy(commit func() error) error { + if c.Provider.Name() == api.BYOK && c.Cloud { return nil } - if ctx.Provider.Name() == api.BYOK { - return ctx.deployBYOK(commit) + if c.Provider.Name() == api.BYOK { + return c.deployBYOK(commit) } - if err := ctx.Provider.CreateBucket(); err != nil { + if err := c.Provider.CreateBucket(); err != nil { return err } - defer ctx.Manifest.Flush() + defer c.Manifest.Flush() - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "init", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "init", func() error { return runAll([]terraformCmd{ {dir: "./terraform/mgmt", cmd: "init", args: []string{"-upgrade"}}, {dir: "./terraform/mgmt", cmd: "apply", args: []string{"-auto-approve"}, retries: 1}, @@ -81,22 +82,22 @@ func (ctx *Context) Deploy(commit func() error) error { return err } - if ctx.ImportCluster != nil { - prov := ctx.Provider.Name() - if err := ctx.templateFrom(ctx.path(fmt.Sprintf("templates/setup/mgmt/%s.tf", prov)), "terraform/mgmt/plural.tf"); err != nil { + if c.ImportCluster != nil { + prov := c.Provider.Name() + if err := c.templateFrom(c.path(fmt.Sprintf("templates/setup/mgmt/%s.tf", prov)), "terraform/mgmt/plural.tf"); err != nil { return err } - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "import", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "import", func() error { return runAll([]terraformCmd{ {dir: "./terraform/mgmt", cmd: "init", args: []string{"-upgrade"}}, - {dir: "./terraform/mgmt", cmd: "import", args: []string{"plural_cluster.mgmt", *ctx.ImportCluster}}, + {dir: "./terraform/mgmt", cmd: "import", args: []string{"plural_cluster.mgmt", *c.ImportCluster}}, }) }); err != nil { return err } - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "apply:import", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "apply:import", func() error { return runAll([]terraformCmd{ {dir: "./terraform/mgmt", cmd: "apply", args: []string{"-auto-approve"}, retries: 1}, }) @@ -111,14 +112,14 @@ func (ctx *Context) Deploy(commit func() error) error { return err } - ctx.StacksIdentity = stacksRole(outs) + c.StacksIdentity = stacksRole(outs) - if err := ctx.afterSetup(); err != nil { + if err := c.afterSetup(); err != nil { return err } - if !ctx.Cloud { - subdomain := ctx.Manifest.Network.Subdomain + if !c.Cloud { + subdomain := c.Manifest.Network.Subdomain if err := testDns(fmt.Sprintf("console.%s", subdomain)); err != nil { return err } @@ -128,14 +129,14 @@ func (ctx *Context) Deploy(commit func() error) error { } } - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "commit", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "commit", func() error { utils.Highlight("\nSetting up gitops management, first lets commit the changes made up to this point...\n\n") return commit() }); err != nil { return err } - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "apps", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "apps", func() error { return runAll([]terraformCmd{ {dir: "./terraform/mgmt", cmd: "apply", args: []string{"-auto-approve"}}, {dir: "./terraform/apps", cmd: "init", args: []string{"-upgrade"}}, @@ -145,12 +146,12 @@ func (ctx *Context) Deploy(commit func() error) error { return err } - return ctx.Prune() + return c.Prune() } -func (ctx *Context) Destroy() error { +func (c *Context) Destroy() error { utils.Highlight("Destroying management cluster terraform stack in terraform/mgmt...\n\n") - if ctx.Cloud { + if c.Cloud { return runAll([]terraformCmd{ {dir: "./terraform/mgmt", cmd: "init", args: []string{"-upgrade"}}, {dir: "./terraform/mgmt", cmd: "state", args: []string{"rm", "plural_cluster.mgmt"}}, @@ -164,10 +165,10 @@ func (ctx *Context) Destroy() error { }) } -func (ctx *Context) DestroyNamespace(name string) error { +func (c *Context) DestroyNamespace(name string) error { utils.Highlight("\nCleaning up namespace %s...\n", name) // ensure current kubeconfig is correct before destroying stuff - if err := ctx.Provider.KubeConfig(); err != nil { + if err := c.Provider.KubeConfig(); err != nil { return err } kube, err := kubernetes.Kubernetes() @@ -175,14 +176,14 @@ func (ctx *Context) DestroyNamespace(name string) error { utils.Error("Could not set up k8s client due to %s\n", err) return err } - c := context.Background() - namespace, err := kube.GetClient().CoreV1().Namespaces().Get(c, name, metav1.GetOptions{}) + ctx := context.Background() + namespace, err := kube.GetClient().CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{}) if err != nil && !errors.IsNotFound(err) { return err } if namespace != nil { - return kube.GetClient().CoreV1().Namespaces().Delete(c, name, metav1.DeleteOptions{ + return kube.GetClient().CoreV1().Namespaces().Delete(ctx, name, metav1.DeleteOptions{ GracePeriodSeconds: lo.ToPtr(int64(0)), }) } @@ -241,10 +242,10 @@ func (tf *terraformCmd) run() (err error) { // deployBYOK runs only the terraform/mgmt apply which installs the Plural console // onto an already-existing (BYOK) local Kubernetes cluster. No cloud infrastructure // or apps terraform is executed. -func (ctx *Context) deployBYOK(commit func() error) error { - defer ctx.Manifest.Flush() +func (c *Context) deployBYOK(commit func() error) error { + defer c.Manifest.Flush() - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "init", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "init", func() error { return runAll([]terraformCmd{ {dir: "./terraform/mgmt", cmd: "init", args: []string{"-upgrade"}}, {dir: "./terraform/mgmt", cmd: "apply", args: []string{"-auto-approve"}, retries: 1}, @@ -253,25 +254,25 @@ func (ctx *Context) deployBYOK(commit func() error) error { return err } - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "commit", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "commit", func() error { utils.Highlight("\nCommitting generated gitops configuration...\n\n") return commit() }); err != nil { return err } - subdomain := ctx.Manifest.Network.Subdomain + subdomain := c.Manifest.Network.Subdomain if err := waitForConsole(); err != nil { return err } utils.Success("Console is up! Access it at https://console.%s\n", subdomain) - if err := ctx.afterSetup(); err != nil { + if err := c.afterSetup(); err != nil { return err } - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "apps", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "apps", func() error { return runAll([]terraformCmd{ {dir: "./terraform/mgmt", cmd: "apply", args: []string{"-auto-approve"}}, {dir: "./terraform/apps", cmd: "init", args: []string{"-upgrade"}}, @@ -281,5 +282,5 @@ func (ctx *Context) deployBYOK(commit func() error) error { return err } - return ctx.pruneBYOK() + return c.pruneBYOK() } diff --git a/pkg/up/generate.go b/pkg/up/generate.go index dee93317..43e447bc 100644 --- a/pkg/up/generate.go +++ b/pkg/up/generate.go @@ -21,13 +21,13 @@ type templatePair struct { } //nolint:gocyclo -func (ctx *Context) Generate(gitRef string) (dir string, err error) { - if ctx.Provider.Name() == api.BYOK && ctx.Cloud { +func (c *Context) Generate(gitRef string) (dir string, err error) { + if c.Provider.Name() == api.BYOK && c.Cloud { return "", nil } dir, err = os.MkdirTemp("", "sampledir") - ctx.dir = dir - hasDomain := ctx.Manifest.AppDomain != "" + c.dir = dir + hasDomain := c.Manifest.AppDomain != "" if err != nil { return } @@ -36,23 +36,23 @@ func (ctx *Context) Generate(gitRef string) (dir string, err error) { return } - prov := ctx.Provider.Name() + prov := c.Provider.Name() tpls := []templatePair{ - {from: ctx.path("charts/runtime/values.yaml.tpl"), to: "./temp/helm/runtime.yaml", overwrite: true}, - {from: ctx.path("charts/runtime/values.yaml.liquid.tpl"), to: "./helm/runtime.yaml.liquid", overwrite: true}, - {from: ctx.path(fmt.Sprintf("templates/providers/bootstrap/%s.tf", prov)), to: "terraform/mgmt/provider.tf"}, - {from: ctx.path(fmt.Sprintf("templates/setup/providers/%s.tf", prov)), to: "terraform/mgmt/mgmt.tf"}, - {from: ctx.path("templates/setup/console.tf"), to: "terraform/mgmt/console.tf", cloudless: true}, - {from: ctx.path(fmt.Sprintf("templates/providers/apps/%s.tf", prov)), to: "terraform/apps/provider.tf", cloudless: true}, - {from: ctx.path("templates/providers/apps/cloud.tf"), to: "terraform/apps/provider.tf", cloud: true}, - {from: ctx.path("templates/setup/cd.tf"), to: "terraform/apps/cd.tf"}, - {from: ctx.path("README.md"), to: "README.md", overwrite: true}, + {from: c.path("charts/runtime/values.yaml.tpl"), to: "./temp/helm/runtime.yaml", overwrite: true}, + {from: c.path("charts/runtime/values.yaml.liquid.tpl"), to: "./helm/runtime.yaml.liquid", overwrite: true}, + {from: c.path(fmt.Sprintf("templates/providers/bootstrap/%s.tf", prov)), to: "terraform/mgmt/provider.tf"}, + {from: c.path(fmt.Sprintf("templates/setup/providers/%s.tf", prov)), to: "terraform/mgmt/mgmt.tf"}, + {from: c.path("templates/setup/console.tf"), to: "terraform/mgmt/console.tf", cloudless: true}, + {from: c.path(fmt.Sprintf("templates/providers/apps/%s.tf", prov)), to: "terraform/apps/provider.tf", cloudless: true}, + {from: c.path("templates/providers/apps/cloud.tf"), to: "terraform/apps/provider.tf", cloud: true}, + {from: c.path("templates/setup/cd.tf"), to: "terraform/apps/cd.tf"}, + {from: c.path("README.md"), to: "README.md", overwrite: true}, } if prov == api.ProviderGCP { - tpls = append(tpls, templatePair{from: ctx.path("templates/setup/config_secrets_gcp.tf"), to: "terraform/mgmt/config_secrets.tf", cloudless: true}) + tpls = append(tpls, templatePair{from: c.path("templates/setup/config_secrets_gcp.tf"), to: "terraform/mgmt/config_secrets.tf", cloudless: true}) } else { - tpls = append(tpls, templatePair{from: ctx.path("templates/setup/config_secrets.tf"), to: "terraform/mgmt/config_secrets.tf", cloudless: true}) + tpls = append(tpls, templatePair{from: c.path("templates/setup/config_secrets.tf"), to: "terraform/mgmt/config_secrets.tf", cloudless: true}) } for _, tpl := range tpls { @@ -61,36 +61,36 @@ func (ctx *Context) Generate(gitRef string) (dir string, err error) { continue } - if tpl.cloudless && ctx.Cloud { + if tpl.cloudless && c.Cloud { continue } - if tpl.cloud && !ctx.Cloud { + if tpl.cloud && !c.Cloud { continue } - if err = ctx.templateFrom(tpl.from, tpl.to); err != nil { + if err = c.templateFrom(tpl.from, tpl.to); err != nil { err = fmt.Errorf("failed to template %s: %w", tpl.from, err) return } } copies := []templatePair{ - {from: ctx.path("terraform/modules/clusters"), to: "terraform/modules/clusters", overwrite: true}, - {from: ctx.path(fmt.Sprintf("terraform/clouds/%s", prov)), to: "terraform/mgmt/cluster", overwrite: true}, - {from: ctx.path("setup"), to: "bootstrap", overwrite: true}, - {from: ctx.path(fmt.Sprintf("terraform/core-infra/%s", prov)), to: "terraform/core-infra"}, - {from: ctx.path("templates"), to: "templates", overwrite: true}, - {from: ctx.path("services"), to: "services", overwrite: true}, - {from: ctx.path("helm"), to: "helm", overwrite: true}, + {from: c.path("terraform/modules/clusters"), to: "terraform/modules/clusters", overwrite: true}, + {from: c.path(fmt.Sprintf("terraform/clouds/%s", prov)), to: "terraform/mgmt/cluster", overwrite: true}, + {from: c.path("setup"), to: "bootstrap", overwrite: true}, + {from: c.path(fmt.Sprintf("terraform/core-infra/%s", prov)), to: "terraform/core-infra"}, + {from: c.path("templates"), to: "templates", overwrite: true}, + {from: c.path("services"), to: "services", overwrite: true}, + {from: c.path("helm"), to: "helm", overwrite: true}, } - if ctx.Cloud { - copies = append(copies, templatePair{from: ctx.path("o11y"), to: "bootstrap/o11y"}) + if c.Cloud { + copies = append(copies, templatePair{from: c.path("o11y"), to: "bootstrap/o11y"}) } if hasDomain { - copies = append(copies, templatePair{from: ctx.path("network"), to: "bootstrap/network"}) + copies = append(copies, templatePair{from: c.path("network"), to: "bootstrap/network"}) } for _, copy := range copies { @@ -119,14 +119,14 @@ func (ctx *Context) Generate(gitRef string) (dir string, err error) { if !utils.Exists(tpl.from) { continue } - if err = ctx.templateFrom(tpl.from, tpl.to); err != nil { + if err = c.templateFrom(tpl.from, tpl.to); err != nil { err = fmt.Errorf("failed to template %s: %w (you might need to regenerate your repo from scratch if partially applied)", tpl.from, err) return } } toRemove := make([]string, 0) - if ctx.Cloud { + if c.Cloud { toRemove = append(toRemove, "bootstrap/console.yaml") } @@ -142,7 +142,7 @@ func (ctx *Context) Generate(gitRef string) (dir string, err error) { os.Remove(f) } - ctx.changeDelims() + c.changeDelims() overwrites := []templatePair{ {from: "bootstrap", to: "bootstrap"}, } @@ -161,7 +161,7 @@ func (ctx *Context) Generate(gitRef string) (dir string, err error) { } destFile = filepath.Join(tpl.to, destFile) - if err = ctx.templateFrom(file, destFile); err != nil { + if err = c.templateFrom(file, destFile); err != nil { err = fmt.Errorf("failed to template %s: %w", file, err) return dir, err } @@ -170,7 +170,7 @@ func (ctx *Context) Generate(gitRef string) (dir string, err error) { continue } - if err = ctx.templateFrom(tpl.from, tpl.to); err != nil { + if err = c.templateFrom(tpl.from, tpl.to); err != nil { return } } @@ -178,17 +178,17 @@ func (ctx *Context) Generate(gitRef string) (dir string, err error) { return } -func (ctx *Context) afterSetup() error { - prov := ctx.Provider.Name() +func (c *Context) afterSetup() error { + prov := c.Provider.Name() overwrites := []templatePair{ - {from: ctx.path(fmt.Sprintf("templates/setup/stacks/%s.yaml", prov)), to: "bootstrap/stacks/serviceaccount.yaml"}, + {from: c.path(fmt.Sprintf("templates/setup/stacks/%s.yaml", prov)), to: "bootstrap/stacks/serviceaccount.yaml"}, {from: "bootstrap/stacks/mgmt.yaml", to: "bootstrap/stacks/mgmt.yaml"}, {from: "bootstrap/stacks/core-infra.yaml", to: "bootstrap/stacks/core-infra.yaml"}, } - ctx.Delims = nil + c.Delims = nil for _, tpl := range overwrites { - if err := ctx.templateFrom(tpl.from, tpl.to); err != nil { + if err := c.templateFrom(tpl.from, tpl.to); err != nil { err = fmt.Errorf("failed to template %s: %w", tpl.from, err) return err } @@ -199,7 +199,7 @@ func (ctx *Context) afterSetup() error { } for _, redact := range redacts { - if err := ctx.redact(redact.from); err != nil { + if err := c.redact(redact.from); err != nil { return err } } @@ -210,7 +210,7 @@ func (ctx *Context) afterSetup() error { for _, uncomment := range uncomments { if utils.Exists(uncomment.from) { - if err := ctx.uncomment(uncomment.from); err != nil { + if err := c.uncomment(uncomment.from); err != nil { return err } } @@ -219,6 +219,6 @@ func (ctx *Context) afterSetup() error { return nil } -func (ctx *Context) path(p string) string { - return filepath.Join(ctx.dir, p) +func (c *Context) path(p string) string { + return filepath.Join(c.dir, p) } diff --git a/pkg/up/prune.go b/pkg/up/prune.go index 60291e25..24d8be71 100644 --- a/pkg/up/prune.go +++ b/pkg/up/prune.go @@ -8,10 +8,10 @@ import ( "github.com/pluralsh/plural-cli/pkg/utils/git" ) -func (ctx *Context) Prune() error { - if ctx.Cloud { - return ctx.runCheckpoint(ctx.Manifest.Checkpoint, "prune:cloud", func() error { - return ctx.pruneCloud() +func (c *Context) Prune() error { + if c.Cloud { + return c.runCheckpoint(c.Manifest.Checkpoint, "prune:cloud", func() error { + return c.pruneCloud() }) } @@ -20,7 +20,7 @@ func (ctx *Context) Prune() error { return err } - if err := ctx.runCheckpoint(ctx.Manifest.Checkpoint, "prune:mgmt", func() error { + if err := c.runCheckpoint(c.Manifest.Checkpoint, "prune:mgmt", func() error { utils.Highlight("\nCleaning up unneeded resources...\n\n") toRemove := []string{ @@ -53,7 +53,7 @@ func (ctx *Context) Prune() error { return git.Sync(repoRoot, "Post-setup resource cleanup", true) } -func (ctx *Context) pruneCloud() error { +func (c *Context) pruneCloud() error { utils.Highlight("\nCleaning up unneeded resources...\n\n") repoRoot, err := git.Root() if err != nil { @@ -81,8 +81,8 @@ func stateRmBestEffort(dir, field string) { // pruneBYOK removes the bootstrap helm/null resources from terraform state and // cleans up the one-shot files used during installation (no cloud infra to touch). -func (ctx *Context) pruneBYOK() error { - return ctx.runCheckpoint(ctx.Manifest.Checkpoint, "prune:mgmt", func() error { +func (c *Context) pruneBYOK() error { + return c.runCheckpoint(c.Manifest.Checkpoint, "prune:mgmt", func() error { utils.Highlight("\nCleaning up unneeded resources...\n\n") // These may or may not be in state depending on install_prereqs value. diff --git a/pkg/up/template.go b/pkg/up/template.go index f0a18f58..486712c1 100644 --- a/pkg/up/template.go +++ b/pkg/up/template.go @@ -8,12 +8,13 @@ import ( "time" "github.com/pluralsh/console/go/polly/retry" + "github.com/pluralsh/plural-cli/pkg/api" plrltpl "github.com/pluralsh/plural-cli/pkg/template" "github.com/pluralsh/plural-cli/pkg/utils" ) -func (ctx *Context) redact(file string) error { +func (c *Context) redact(file string) error { buf, err := utils.ReadFile(file) if err != nil { return err @@ -22,7 +23,7 @@ func (ctx *Context) redact(file string) error { return utils.WriteFile(file, []byte(re.ReplaceAllString(buf, ""))) } -func (ctx *Context) uncomment(file string) error { +func (c *Context) uncomment(file string) error { buf, err := utils.ReadFile(file) if err != nil { return err @@ -31,13 +32,13 @@ func (ctx *Context) uncomment(file string) error { return utils.WriteFile(file, []byte(re.ReplaceAllString(buf, ""))) } -func (ctx *Context) templateFrom(file, to string) error { +func (c *Context) templateFrom(file, to string) error { buf, err := utils.ReadFile(file) if err != nil { return err } - res, err := ctx.template(buf) + res, err := c.template(buf) if err != nil { return err } @@ -45,8 +46,8 @@ func (ctx *Context) templateFrom(file, to string) error { return utils.WriteFile(to, []byte(res)) } -func (ctx *Context) template(tmplate string) (string, error) { - cluster, provider := ctx.Provider.Cluster(), ctx.Provider.Name() +func (c *Context) template(tmplate string) (string, error) { + cluster, provider := c.Provider.Cluster(), c.Provider.Name() client := api.NewClient() @@ -55,7 +56,7 @@ func (ctx *Context) template(tmplate string) (string, error) { return "", fmt.Errorf("you must run `plural login` before installing") } eabCredential := &api.EabCredential{} - if ctx.Provider.Name() != api.BYOK { + if c.Provider.Name() != api.BYOK && !c.ignorePreflights { retrier := retry.NewConstant(15*time.Millisecond, 3) eabCredential, err = retry.Retry(retrier, func() (*api.EabCredential, error) { return client.GetEabCredential(cluster, provider) }) if err != nil { @@ -67,34 +68,34 @@ func (ctx *Context) template(tmplate string) (string, error) { "UserEmail": me.Email, "Cluster": cluster, "Provider": provider, - "Bucket": ctx.Provider.Bucket(), - "Project": ctx.Provider.Project(), - "Region": ctx.Provider.Region(), - "Context": ctx.Provider.Context(), - "Config": ctx.Config, - "RepoUrl": ctx.RepoUrl, - "Identifier": ctx.identifier(), + "Bucket": c.Provider.Bucket(), + "Project": c.Provider.Project(), + "Region": c.Provider.Region(), + "Context": c.Provider.Context(), + "Config": c.Config, + "RepoUrl": c.RepoUrl, + "Identifier": c.identifier(), "Acme": eabCredential, - "StacksIdentity": ctx.StacksIdentity, - "RequireDB": !ctx.Cloud, - "CloudCluster": ctx.CloudCluster, - "Cloud": ctx.Cloud, + "StacksIdentity": c.StacksIdentity, + "RequireDB": !c.Cloud, + "CloudCluster": c.CloudCluster, + "Cloud": c.Cloud, "ClusterName": cluster, - "ProjectID": ctx.Provider.Project(), - "GitUsername": ctx.GitUsername, - "GitPassword": ctx.GitPassword, + "ProjectID": c.Provider.Project(), + "GitUsername": c.GitUsername, + "GitPassword": c.GitPassword, } - if ctx.Manifest.Network != nil { - values["Subdomain"] = ctx.Manifest.Network.Subdomain - values["Network"] = ctx.Manifest.Network + if c.Manifest.Network != nil { + values["Subdomain"] = c.Manifest.Network.Subdomain + values["Network"] = c.Manifest.Network } - if ctx.Manifest.AppDomain != "" { - values["AppDomain"] = ctx.Manifest.AppDomain + if c.Manifest.AppDomain != "" { + values["AppDomain"] = c.Manifest.AppDomain } tpl := template.New("tpl").Funcs(plrltpl.GetFuncMap()) - if ctx.Delims != nil { - tpl.Delims(ctx.Delims.left, ctx.Delims.right) + if c.Delims != nil { + tpl.Delims(c.Delims.left, c.Delims.right) } readyTpl, err := tpl.Parse(tmplate)