Alexander Belanger пре 5 година
родитељ
комит
36c01b7cf5
3 измењених фајлова са 122 додато и 236 уклоњено
  1. 17 6
      internal/templater/helm/writer.go
  2. 1 4
      internal/templater/parser/parser.go
  3. 104 226
      server/api/deploy_handler.go

+ 17 - 6
internal/templater/helm/writer.go

@@ -4,6 +4,7 @@ import (
 	"fmt"
 
 	"github.com/porter-dev/porter/internal/helm"
+	"helm.sh/helm/v3/pkg/chart"
 )
 
 // ValuesTemplateWriter upgrades and installs charts by setting Helm values
@@ -11,11 +12,14 @@ type ValuesTemplateWriter struct {
 	// The object to read from, identified by its group-version-kind
 	Agent *helm.Agent
 
-	// ChartPath for installing a chart
-	ChartPath string
+	// Chart that gets installed
+	Chart *chart.Chart
 
-	// ReleaseName for upgrading the chart
+	// ReleaseName for upgrading the chart or installing
 	ReleaseName string
+
+	// Namespace it gets installed to
+	Namespace string
 }
 
 // Transform does nothing, since Helm handles the transforms internally
@@ -27,11 +31,18 @@ func (w *ValuesTemplateWriter) Transform() error {
 func (w *ValuesTemplateWriter) Create(
 	vals map[string]interface{},
 ) (map[string]interface{}, error) {
-	if w.ChartPath != "" {
-		return nil, fmt.Errorf("chart path not set")
+	if w.Chart == nil {
+		return nil, fmt.Errorf("chart must be set")
+	}
+
+	conf := &helm.InstallChartConfig{
+		Chart:     w.Chart,
+		Name:      w.ReleaseName,
+		Namespace: w.Namespace,
+		Values:    vals,
 	}
 
-	_, err := w.Agent.InstallChartByValues(w.ChartPath, vals)
+	_, err := w.Agent.InstallChart(conf)
 
 	if err != nil {
 		return nil, err

+ 1 - 4
internal/templater/parser/parser.go

@@ -26,9 +26,6 @@ type ClientConfigDefault struct {
 	HelmAgent   *helm.Agent
 	HelmRelease *release.Release
 	HelmChart   *chart.Chart
-
-	// for installing a new chart
-	HelmChartPath string
 }
 
 func FormYAMLFromBytes(def *ClientConfigDefault, bytes []byte) (*models.FormYAML, error) {
@@ -174,7 +171,7 @@ func formContextToContextConfig(def *ClientConfigDefault, context *models.FormCo
 
 		res.TemplateWriter = &th.ValuesTemplateWriter{
 			Agent:       def.HelmAgent,
-			ChartPath:   def.HelmChartPath,
+			Chart:       def.HelmChart,
 			ReleaseName: relName,
 		}
 	case "helm/manifests":

+ 104 - 226
server/api/deploy_handler.go

@@ -1,235 +1,113 @@
 package api
 
 import (
-	"archive/tar"
-	"bytes"
-	"compress/gzip"
-	"encoding/json"
-	"errors"
-	"fmt"
-	"io"
-	"io/ioutil"
 	"net/http"
-	"net/url"
-	"strings"
-
-	"github.com/porter-dev/porter/internal/forms"
-	"github.com/porter-dev/porter/internal/helm"
-	"github.com/porter-dev/porter/internal/models"
-	"gopkg.in/yaml.v2"
 )
 
 // HandleDeployTemplate triggers a chart deployment from a template
 func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
-	vals, err := url.ParseQuery(r.URL.RawQuery)
-
-	if err != nil {
-		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
-		return
-	}
-
-	form := &forms.InstallChartTemplateForm{
-		ReleaseForm: &forms.ReleaseForm{
-			Form: &helm.Form{
-				Repo: app.repo,
-			},
-		},
-		ChartTemplateForm: &forms.ChartTemplateForm{},
-	}
-
-	form.ReleaseForm.PopulateHelmOptionsFromQueryParams(
-		vals,
-		app.repo.Cluster,
-	)
-
-	if err := json.NewDecoder(r.Body).Decode(form); err != nil {
-		app.handleErrorFormDecoding(err, ErrUserDecode, w)
-		return
-	}
-
-	agent, err := app.getAgentFromReleaseForm(
-		w,
-		r,
-		form.ReleaseForm,
-	)
-
-	if err != nil {
-		return
-	}
-
-	baseURL := "https://porter-dev.github.io/chart-repo/"
-	values, err := getDefaultValues(form.ChartTemplateForm.TemplateName, baseURL)
-	if err != nil {
-		return
-	}
-
-	// Set image URL
-	if form.ChartTemplateForm.ImageURL != "" {
-		(*values)["image"].(map[interface{}]interface{})["repository"] = form.ChartTemplateForm.ImageURL
-	}
-
-	// Loop through form params to override
-	for k := range form.ChartTemplateForm.FormValues {
-		switch v := interface{}(k).(type) {
-		case string:
-			splits := strings.Split(v, ".")
-
-			// Validate that the field to override exists
-			currentLoc := *values
-			for s := range splits {
-				key := splits[s]
-				val := currentLoc[key]
-				if val == nil {
-					fmt.Printf("No such field: %v\n", key)
-				} else if s == len(splits)-1 {
-					newValue := form.ChartTemplateForm.FormValues[v]
-					fmt.Printf("Overriding default %v with %v\n", val, newValue)
-					currentLoc[key] = newValue
-				} else {
-					fmt.Println("Traversing...")
-					currentLoc = val.(map[interface{}]interface{})
-				}
-			}
-		default:
-			fmt.Println("Non-string type")
-		}
-	}
-
-	v, err := yaml.Marshal(values)
-
-	if err != nil {
-		return
-	}
-
-	var tgz string
-	switch form.ChartTemplateForm.TemplateName {
-	case "redis":
-		tgz = "redis-0.0.1.tgz"
-	}
-
-	// Output values.yaml string
-	_, err = agent.InstallChart(
-		"./internal/local_templates/"+tgz,
-		v,
-		form.ChartTemplateForm.Name,
-		form.ReleaseForm.Form.Namespace,
-	)
-
-	if err != nil {
-		app.sendExternalError(err, http.StatusInternalServerError, HTTPError{
-			Code:   ErrReleaseDeploy,
-			Errors: []string{"error installing a new chart: " + err.Error()},
-		}, w)
-
-		return
-	}
-
-	w.WriteHeader(http.StatusOK)
-}
-
-// ------------------------ Deploy handler helper functions ------------------------ //
-
-func getDefaultValues(templateName string, baseURL string) (*map[interface{}]interface{}, error) {
-	resp, err := http.Get(baseURL + "index.yaml")
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-
-	defer resp.Body.Close()
-	body, _ := ioutil.ReadAll(resp.Body)
-
-	form := models.IndexYAML{}
-	if err := yaml.Unmarshal([]byte(body), &form); err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-
-	// Loop over charts in index.yaml
-	for k := range form.Entries {
-		indexChart := form.Entries[k][0]
-		tarURL := indexChart.Urls[0]
-		splits := strings.Split(tarURL, "-")
-
-		strAcc := splits[0]
-		for i := 1; i < len(splits)-1; i++ {
-			strAcc += "-" + splits[i]
-		}
-
-		// Unpack the target chart and retrieve values.yaml
-		if strAcc == templateName {
-			tgtURL := baseURL + tarURL
-			values, err := processValues(tgtURL)
-			if err != nil {
-				fmt.Println(err)
-				return nil, err
-			}
-			return values, nil
-		}
-	}
-	return nil, errors.New("no values.yaml found")
-}
-
-func processValues(tgtURL string) (*map[interface{}]interface{}, error) {
-	resp, err := http.Get(tgtURL)
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-
-	defer resp.Body.Close()
-	body, _ := ioutil.ReadAll(resp.Body)
-	buf := bytes.NewBuffer(body)
-
-	gzf, err := gzip.NewReader(buf)
-	if err != nil {
-		fmt.Println(err)
-		return nil, err
-	}
-
-	// Process tarball to generate FormYAML and retrieve markdown
-	tarReader := tar.NewReader(gzf)
-	for {
-		header, err := tarReader.Next()
-		if err == io.EOF {
-			break
-		} else if err != nil {
-			fmt.Println(err)
-			return nil, err
-		}
-
-		name := header.Name
-		switch header.Typeflag {
-		case tar.TypeDir:
-			continue
-		case tar.TypeReg:
-
-			// Handle values.yaml located in archive
-			if strings.Contains(name, "values.yaml") {
-				bufForm := new(bytes.Buffer)
-
-				_, err := io.Copy(bufForm, tarReader)
-				if err != nil {
-					fmt.Println(err)
-					return nil, err
-				}
-
-				// Unmarshal yaml byte buffer
-				form := make(map[interface{}]interface{})
-				if err := yaml.Unmarshal(bufForm.Bytes(), &form); err != nil {
-					fmt.Println(err)
-					return nil, err
-				}
-				return &form, nil
-			}
-		default:
-			fmt.Printf("%s : %c %s %s\n",
-				"Unknown type",
-				header.Typeflag,
-				"in file",
-				name,
-			)
-		}
-	}
-	return nil, errors.New("no values.yaml found")
+	// vals, err := url.ParseQuery(r.URL.RawQuery)
+
+	// if err != nil {
+	// 	app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
+	// 	return
+	// }
+
+	// form := &forms.InstallChartTemplateForm{
+	// 	ReleaseForm: &forms.ReleaseForm{
+	// 		Form: &helm.Form{
+	// 			Repo: app.repo,
+	// 		},
+	// 	},
+	// 	ChartTemplateForm: &forms.ChartTemplateForm{},
+	// }
+
+	// form.ReleaseForm.PopulateHelmOptionsFromQueryParams(
+	// 	vals,
+	// 	app.repo.Cluster,
+	// )
+
+	// if err := json.NewDecoder(r.Body).Decode(form); err != nil {
+	// 	app.handleErrorFormDecoding(err, ErrUserDecode, w)
+	// 	return
+	// }
+
+	// agent, err := app.getAgentFromReleaseForm(
+	// 	w,
+	// 	r,
+	// 	form.ReleaseForm,
+	// )
+
+	// if err != nil {
+	// 	return
+	// }
+
+	// baseURL := "https://porter-dev.github.io/chart-repo/"
+	// values, err := getDefaultValues(form.ChartTemplateForm.TemplateName, baseURL)
+	// if err != nil {
+	// 	return
+	// }
+
+	// // Set image URL
+	// if form.ChartTemplateForm.ImageURL != "" {
+	// 	(*values)["image"].(map[interface{}]interface{})["repository"] = form.ChartTemplateForm.ImageURL
+	// }
+
+	// // Loop through form params to override
+	// for k := range form.ChartTemplateForm.FormValues {
+	// 	switch v := interface{}(k).(type) {
+	// 	case string:
+	// 		splits := strings.Split(v, ".")
+
+	// 		// Validate that the field to override exists
+	// 		currentLoc := *values
+	// 		for s := range splits {
+	// 			key := splits[s]
+	// 			val := currentLoc[key]
+	// 			if val == nil {
+	// 				fmt.Printf("No such field: %v\n", key)
+	// 			} else if s == len(splits)-1 {
+	// 				newValue := form.ChartTemplateForm.FormValues[v]
+	// 				fmt.Printf("Overriding default %v with %v\n", val, newValue)
+	// 				currentLoc[key] = newValue
+	// 			} else {
+	// 				fmt.Println("Traversing...")
+	// 				currentLoc = val.(map[interface{}]interface{})
+	// 			}
+	// 		}
+	// 	default:
+	// 		fmt.Println("Non-string type")
+	// 	}
+	// }
+
+	// v, err := yaml.Marshal(values)
+
+	// if err != nil {
+	// 	return
+	// }
+
+	// var tgz string
+	// switch form.ChartTemplateForm.TemplateName {
+	// case "redis":
+	// 	tgz = "redis-0.0.1.tgz"
+	// }
+
+	// // Output values.yaml string
+	// _, err = agent.InstallChart(
+	// 	"./internal/local_templates/"+tgz,
+	// 	v,
+	// 	form.ChartTemplateForm.Name,
+	// 	form.ReleaseForm.Form.Namespace,
+	// )
+
+	// if err != nil {
+	// 	app.sendExternalError(err, http.StatusInternalServerError, HTTPError{
+	// 		Code:   ErrReleaseDeploy,
+	// 		Errors: []string{"error installing a new chart: " + err.Error()},
+	// 	}, w)
+
+	// 	return
+	// }
+
+	// w.WriteHeader(http.StatusOK)
 }