github.com/pluralsh/plural-cli@v0.9.5/cmd/plural/workspace.go (about)

     1  package plural
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/urfave/cli"
    10  
    11  	"github.com/pluralsh/plural-cli/pkg/helm"
    12  	"github.com/pluralsh/plural-cli/pkg/provider"
    13  	"github.com/pluralsh/plural-cli/pkg/scaffold"
    14  	"github.com/pluralsh/plural-cli/pkg/utils"
    15  	"github.com/pluralsh/plural-cli/pkg/utils/git"
    16  	"github.com/pluralsh/plural-cli/pkg/wkspace"
    17  )
    18  
    19  func (p *Plural) workspaceCommands() []cli.Command {
    20  	return []cli.Command{
    21  		{
    22  			Name:   "kube-init",
    23  			Usage:  "generates kubernetes credentials for this subworkspace",
    24  			Action: latestVersion(kubeInit),
    25  		},
    26  		{
    27  			Name:      "readme",
    28  			Usage:     "generate chart readme for an app",
    29  			ArgsUsage: "NAME",
    30  			Flags: []cli.Flag{
    31  				cli.BoolFlag{
    32  					Name:  "dry-run",
    33  					Usage: "output to stdout instead of to a file",
    34  				},
    35  			},
    36  			Action: latestVersion(func(c *cli.Context) error { return appReadme(c.Args().Get(0), c.Bool("dry-run")) }),
    37  		},
    38  		{
    39  			Name:      "helm",
    40  			Usage:     "upgrade/installs the helm chart for this subworkspace",
    41  			ArgsUsage: "NAME",
    42  			Flags: []cli.Flag{
    43  				cli.StringSliceFlag{
    44  					Name:  "skip",
    45  					Usage: "helm sub-chart to skip. can be passed multiple times",
    46  				},
    47  				cli.StringSliceFlag{
    48  					Name:  "set",
    49  					Usage: "helm value to set. can be passed multiple times",
    50  				},
    51  				cli.StringSliceFlag{
    52  					Name:  "setJSON",
    53  					Usage: "JSON helm value to set. can be passed multiple times",
    54  				},
    55  				cli.BoolFlag{
    56  					Name:  "wait",
    57  					Usage: "have helm wait until all pods are in ready state",
    58  				},
    59  			},
    60  			Action: latestVersion(initKubeconfig(p.bounceHelm)),
    61  		},
    62  		{
    63  			Name:      "helm-diff",
    64  			Usage:     "diffs the helm release for this subworkspace",
    65  			ArgsUsage: "NAME",
    66  			Action:    latestVersion(p.diffHelm),
    67  		},
    68  		{
    69  			Name:      "helm-deps",
    70  			Usage:     "updates the helm dependencies for this workspace",
    71  			ArgsUsage: "PATH",
    72  			Action:    latestVersion(updateDeps),
    73  		},
    74  		{
    75  			Name:      "terraform-diff",
    76  			Usage:     "diffs the helm release for this subworkspace",
    77  			ArgsUsage: "NAME",
    78  			Action:    latestVersion(p.diffTerraform),
    79  		},
    80  		{
    81  			Name:      "crds",
    82  			Usage:     "installs the crds for this repo",
    83  			ArgsUsage: "NAME",
    84  			Action:    latestVersion(initKubeconfig(p.createCrds)),
    85  		},
    86  		{
    87  			Name:      "helm-template",
    88  			Usage:     "templates the helm values to stdout",
    89  			ArgsUsage: "NAME",
    90  			Action:    latestVersion(requireArgs(p.templateHelm, []string{"NAME"})),
    91  		},
    92  		{
    93  			Name:      "helm-mapkubeapis",
    94  			Usage:     "updates in-place Helm release metadata that contains deprecated or removed Kubernetes APIs to a new instance with supported Kubernetes APIs",
    95  			ArgsUsage: "NAME",
    96  			Action:    latestVersion(requireArgs(p.mapkubeapis, []string{"NAME"})),
    97  		},
    98  	}
    99  }
   100  
   101  func kubeInit(_ *cli.Context) error {
   102  	_, found := utils.ProjectRoot()
   103  	if !found {
   104  		return fmt.Errorf("Project not initialized, run `plural init` to set up a workspace")
   105  	}
   106  
   107  	prov, err := provider.GetProvider()
   108  	if err != nil {
   109  		return err
   110  	}
   111  
   112  	return prov.KubeConfig()
   113  }
   114  
   115  func (p *Plural) bounceHelm(c *cli.Context) error {
   116  	name := c.Args().Get(0)
   117  	minimal, err := wkspace.Minimal(name, p.HelmConfiguration)
   118  	if err != nil {
   119  		return err
   120  	}
   121  
   122  	var skipArgs []string
   123  	if c.IsSet("skip") {
   124  		for _, skipChart := range c.StringSlice("skip") {
   125  			skipString := fmt.Sprintf("%s.enabled=false", skipChart)
   126  			skipArgs = append(skipArgs, skipString)
   127  		}
   128  	}
   129  	var setArgs []string
   130  	if c.IsSet("set") {
   131  		setArgs = append(setArgs, c.StringSlice("set")...)
   132  	}
   133  
   134  	var setJSONArgs []string
   135  	if c.IsSet("setJSON") {
   136  		setJSONArgs = append(setJSONArgs, c.StringSlice("setJSON")...)
   137  	}
   138  
   139  	return minimal.BounceHelm(c.IsSet("wait"), skipArgs, setArgs, setJSONArgs)
   140  }
   141  
   142  func (p *Plural) diffHelm(c *cli.Context) error {
   143  	name := c.Args().Get(0)
   144  	minimal, err := wkspace.Minimal(name, p.HelmConfiguration)
   145  	if err != nil {
   146  		return err
   147  	}
   148  
   149  	return minimal.DiffHelm()
   150  }
   151  
   152  func (p *Plural) diffTerraform(c *cli.Context) error {
   153  	name := c.Args().Get(0)
   154  	minimal, err := wkspace.Minimal(name, p.HelmConfiguration)
   155  	if err != nil {
   156  		return err
   157  	}
   158  
   159  	return minimal.DiffTerraform()
   160  }
   161  
   162  func (p *Plural) createCrds(_ *cli.Context) error {
   163  	err := p.InitKube()
   164  	if err != nil {
   165  		return err
   166  	}
   167  	if empty, err := utils.IsEmpty("crds"); err != nil || empty {
   168  		return nil
   169  	}
   170  
   171  	return filepath.Walk("crds", func(path string, info os.FileInfo, err error) error {
   172  		if err != nil {
   173  			return err
   174  		}
   175  
   176  		if info.IsDir() {
   177  			return nil
   178  		}
   179  
   180  		err = p.Kube.Apply(path, true)
   181  		if err != nil {
   182  			errStr := fmt.Sprint(err)
   183  			if strings.Contains(errStr, "invalid apiVersion \"client.authentication.k8s.io/v1alpha1\"") {
   184  				return fmt.Errorf("failed with %s, this is usually due to your aws cli version being out of date", errStr)
   185  			}
   186  			return err
   187  		}
   188  
   189  		return nil
   190  	})
   191  }
   192  
   193  func updateDeps(c *cli.Context) error {
   194  	path := c.Args().Get(0)
   195  	if path == "" {
   196  		path = "."
   197  	}
   198  
   199  	return helm.UpdateDependencies(path)
   200  }
   201  
   202  func (p *Plural) templateHelm(c *cli.Context) error {
   203  	name := c.Args().Get(0)
   204  	minimal, err := wkspace.Minimal(name, p.HelmConfiguration)
   205  	if err != nil {
   206  		return err
   207  	}
   208  
   209  	return minimal.TemplateHelm()
   210  }
   211  
   212  func (p *Plural) mapkubeapis(c *cli.Context) error {
   213  	name := c.Args().Get(0)
   214  	minimal, err := wkspace.Minimal(name, p.HelmConfiguration)
   215  	if err != nil {
   216  		return err
   217  	}
   218  
   219  	return minimal.MapKubeApis()
   220  }
   221  
   222  func appReadme(name string, dryRun bool) error {
   223  	repoRoot, err := git.Root()
   224  	if err != nil {
   225  		return err
   226  	}
   227  
   228  	dir := filepath.Join(repoRoot, name, "helm", name)
   229  	return scaffold.Readme(dir, dryRun)
   230  }