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

     1  package plural
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  
     8  	"github.com/pluralsh/plural-cli/pkg/api"
     9  	"github.com/pluralsh/plural-cli/pkg/config"
    10  	"github.com/pluralsh/plural-cli/pkg/helm"
    11  	"github.com/pluralsh/plural-cli/pkg/pluralfile"
    12  	scftmpl "github.com/pluralsh/plural-cli/pkg/scaffold/template"
    13  	"github.com/pluralsh/plural-cli/pkg/utils"
    14  	"github.com/pluralsh/plural-cli/pkg/utils/pathing"
    15  	"github.com/urfave/cli"
    16  	"sigs.k8s.io/yaml"
    17  )
    18  
    19  func (p *Plural) pushCommands() []cli.Command {
    20  	return []cli.Command{
    21  		{
    22  			Name:      "terraform",
    23  			Usage:     "pushes a terraform module",
    24  			ArgsUsage: "path/to/module REPO",
    25  			Action:    latestVersion(p.handleTerraformUpload),
    26  		},
    27  		{
    28  			Name:      "helm",
    29  			Usage:     "pushes a helm chart",
    30  			ArgsUsage: "path/to/chart REPO",
    31  			Action:    latestVersion(handleHelmUpload),
    32  		},
    33  		{
    34  			Name:      "recipe",
    35  			Usage:     "pushes a recipe",
    36  			ArgsUsage: "path/to/recipe.yaml REPO",
    37  			Action:    latestVersion(p.handleRecipeUpload),
    38  		},
    39  		{
    40  			Name:      "artifact",
    41  			Usage:     "creates an artifact for the repo",
    42  			ArgsUsage: "path/to/def.yaml REPO",
    43  			Action:    latestVersion(p.handleArtifact),
    44  			Flags: []cli.Flag{
    45  				cli.StringFlag{
    46  					Name:  "platform",
    47  					Value: "mac",
    48  					Usage: "name of the OS this binary is built for",
    49  				},
    50  				cli.StringFlag{
    51  					Name:  "arch",
    52  					Value: "amd64",
    53  					Usage: "machine architecture the binary is compatible with",
    54  				},
    55  			},
    56  		},
    57  		{
    58  			Name:      "crd",
    59  			Usage:     "registers a new crd for a chart",
    60  			ArgsUsage: "path/to/def.yaml REPO CHART",
    61  			Action:    latestVersion(p.createCrd),
    62  		},
    63  	}
    64  }
    65  
    66  func apply(c *cli.Context) error {
    67  	path, _ := os.Getwd()
    68  	var file = pathing.SanitizeFilepath(filepath.Join(path, "Pluralfile"))
    69  	if c.IsSet("file") {
    70  		file, _ = filepath.Abs(c.String("file"))
    71  	}
    72  
    73  	if err := os.Chdir(filepath.Dir(file)); err != nil {
    74  		return err
    75  	}
    76  
    77  	plrl, err := pluralfile.Parse(file)
    78  	if err != nil {
    79  		return err
    80  	}
    81  
    82  	lock, err := plrl.Lock(file)
    83  	if err != nil {
    84  		return err
    85  	}
    86  	return plrl.Execute(file, lock)
    87  }
    88  
    89  func (p *Plural) handleTerraformUpload(c *cli.Context) error {
    90  	p.InitPluralClient()
    91  	_, err := p.UploadTerraform(c.Args().Get(0), c.Args().Get(1))
    92  	return api.GetErrorResponse(err, "UploadTerraform")
    93  }
    94  
    95  func handleHelmTemplate(c *cli.Context) error {
    96  	path := c.String("values")
    97  	f, err := scftmpl.TmpValuesFile(path)
    98  	if err != nil {
    99  		return err
   100  	}
   101  
   102  	defer func(name string) {
   103  		_ = os.Remove(name)
   104  	}(f.Name())
   105  
   106  	name := "default"
   107  	namespace := "default"
   108  	actionConfig, err := helm.GetActionConfig(namespace)
   109  	if err != nil {
   110  		return err
   111  	}
   112  	values, err := getValues(f.Name())
   113  	if err != nil {
   114  		return err
   115  	}
   116  	res, err := helm.Template(actionConfig, name, namespace, c.Args().Get(0), false, false, values)
   117  	if err != nil {
   118  		return err
   119  	}
   120  	fmt.Println(string(res))
   121  	return nil
   122  }
   123  
   124  func handleHelmUpload(c *cli.Context) error {
   125  	conf := config.Read()
   126  	pth, repo := c.Args().Get(0), c.Args().Get(1)
   127  
   128  	f, err := buildValuesFromTemplate(pth)
   129  	if err != nil {
   130  		return err
   131  	}
   132  	defer func(name string) {
   133  		_ = os.Remove(name)
   134  
   135  	}(f.Name())
   136  
   137  	utils.Highlight("linting helm: ")
   138  	values, err := getValues(f.Name())
   139  	if err != nil {
   140  		return err
   141  	}
   142  	if err := helm.Lint(pth, "default", values); err != nil {
   143  		return err
   144  	}
   145  
   146  	cmUrl := fmt.Sprintf("%s/cm/%s", conf.BaseUrl(), repo)
   147  	return helm.Push(pth, cmUrl)
   148  }
   149  
   150  func buildValuesFromTemplate(pth string) (f *os.File, err error) {
   151  	templatePath := pathing.SanitizeFilepath(filepath.Join(pth, "values.yaml.tpl"))
   152  	_, err = utils.ReadFile(templatePath)
   153  	if os.IsNotExist(err) {
   154  		templatePath = pathing.SanitizeFilepath(filepath.Join(pth, "values.yaml.lua"))
   155  		_, err := utils.ReadFile(templatePath)
   156  		if err != nil {
   157  			return nil, err
   158  		}
   159  
   160  	}
   161  
   162  	return scftmpl.TmpValuesFile(templatePath)
   163  }
   164  
   165  func (p *Plural) handleRecipeUpload(c *cli.Context) error {
   166  	p.InitPluralClient()
   167  	fullPath, _ := filepath.Abs(c.Args().Get(0))
   168  	contents, err := os.ReadFile(fullPath)
   169  	if err != nil {
   170  		return err
   171  	}
   172  
   173  	recipeInput, err := api.ConstructRecipe(contents)
   174  	if err != nil {
   175  		return err
   176  	}
   177  
   178  	_, err = p.CreateRecipe(c.Args().Get(1), recipeInput)
   179  	return api.GetErrorResponse(err, "CreateRecipe")
   180  }
   181  
   182  func (p *Plural) handleArtifact(c *cli.Context) error {
   183  	p.InitPluralClient()
   184  	fullPath, _ := filepath.Abs(c.Args().Get(0))
   185  	contents, err := os.ReadFile(fullPath)
   186  	if err != nil {
   187  		return err
   188  	}
   189  
   190  	input, err := api.ConstructArtifactAttributes(contents)
   191  	if err != nil {
   192  		return err
   193  	}
   194  	input.Platform = c.String("platform")
   195  	input.Arch = c.String("arch")
   196  	_, err = p.CreateArtifact(c.Args().Get(1), input)
   197  	return api.GetErrorResponse(err, "CreateArtifact")
   198  }
   199  
   200  func (p *Plural) createCrd(c *cli.Context) error {
   201  	p.InitPluralClient()
   202  	fullPath, _ := filepath.Abs(c.Args().Get(0))
   203  	repo := c.Args().Get(1)
   204  	chart := c.Args().Get(2)
   205  	err := p.CreateCrd(repo, chart, fullPath)
   206  	return api.GetErrorResponse(err, "CreateCrd")
   207  }
   208  
   209  func getValues(path string) (map[string]interface{}, error) {
   210  	values := make(map[string]interface{})
   211  	valsContent, err := os.ReadFile(path)
   212  	if err != nil {
   213  		return nil, err
   214  	}
   215  	if err := yaml.Unmarshal(valsContent, &values); err != nil {
   216  		return nil, err
   217  	}
   218  	return values, nil
   219  }