Selaa lähdekoodia

updated template routes

Alexander Belanger 5 vuotta sitten
vanhempi
sitoutus
cbc80e3544
4 muutettua tiedostoa jossa 155 lisäystä ja 57 poistoa
  1. 87 8
      cli/cmd/test.go
  2. 13 3
      internal/models/templates.go
  3. 9 10
      server/api/template_handler.go
  4. 46 36
      server/api/template_handler_test.go

+ 87 - 8
cli/cmd/test.go

@@ -1,28 +1,86 @@
 package cmd
 
 import (
+	"encoding/json"
 	"fmt"
 	"os"
 
 	"github.com/fatih/color"
-	"github.com/porter-dev/porter/internal/helm/loader"
+	"github.com/porter-dev/porter/internal/models"
 	"github.com/spf13/cobra"
-	"sigs.k8s.io/yaml"
 )
 
 var testCmd = &cobra.Command{
 	Use:   "test",
 	Short: "Testing",
 	Run: func(cmd *cobra.Command, args []string) {
-		chart, err := loader.LoadChart("https://porter-dev.github.io/chart-repo", "docker", "0.0.1")
+		// chart, err := loader.LoadChart("https://porter-dev.github.io/chart-repo", "docker", "0.0.1")
 
-		if err != nil {
-			red := color.New(color.FgRed)
-			red.Println("Error running test:", err.Error())
-			os.Exit(1)
+		// if err != nil {
+		// 	red := color.New(color.FgRed)
+		// 	red.Println("Error running test:", err.Error())
+		// 	os.Exit(1)
+		// }
+
+		// bytes, err := yaml.Marshal(chart)
+
+		// if err != nil {
+		// 	red := color.New(color.FgRed)
+		// 	red.Println("Error running test:", err.Error())
+		// 	os.Exit(1)
+		// }
+
+		// fmt.Println(string(bytes))
+
+		form := &models.FormYAML{
+			Tabs: []*models.FormTab{
+				&models.FormTab{
+					Context: &models.FormContext{
+						Type: "helm/values",
+					},
+					Name:  "main",
+					Label: "Main Settings",
+					Sections: []*models.FormSection{
+						&models.FormSection{
+							Name: "section_one",
+							Contents: []*models.FormContent{
+								&models.FormContent{
+									Type:  "number-input",
+									Value: "service.targetPort",
+									Label: "Target Port",
+									Settings: struct {
+										Default interface{} `yaml:"default,omitempty" json:"default,omitempty"`
+										Unit    interface{} `yaml:"unit,omitempty" json:"unit,omitempty"`
+									}{
+										Default: 8000,
+									},
+								},
+							},
+						},
+					},
+				},
+				&models.FormTab{
+					Context: &models.FormContext{
+						Type: "cluster",
+					},
+					Name:  "crd",
+					Label: "CRDs",
+					Sections: []*models.FormSection{
+						&models.FormSection{
+							Name: "section_one",
+							Contents: []*models.FormContent{
+								&models.FormContent{
+									Type:  "resourcelist",
+									Value: `[{"name": "resource_1"}]`,
+								},
+							},
+						},
+					},
+				},
+			},
 		}
 
-		bytes, err := yaml.Marshal(chart)
+		bytes, err := json.Marshal(form)
 
 		if err != nil {
 			red := color.New(color.FgRed)
@@ -37,3 +95,24 @@ var testCmd = &cobra.Command{
 func init() {
 	rootCmd.AddCommand(testCmd)
 }
+
+// // FormSection is a section of a form
+// type FormSection struct {
+// 	Context  *FormContext   `yaml:"context" json:"context"`
+// 	Name     string         `yaml:"name" json:"name"`
+// 	ShowIf   string         `yaml:"show_if" json:"show_if"`
+// 	Contents []*FormContent `yaml:"contents" json:"contents,omitempty"`
+// }
+
+// // FormContent is a form's atomic unit
+// type FormContent struct {
+// 	Context  *FormContext `yaml:"context" json:"context"`
+// 	Type     string       `yaml:"type" json:"type"`
+// 	Label    string       `yaml:"label" json:"label"`
+// 	Name     string       `yaml:"name,omitempty" json:"name,omitempty"`
+// 	Value    interface{}  `yaml:"value,omitempty" json:"value,omitempty"`
+// 	Settings struct {
+// 		Default interface{} `yaml:"default,omitempty" json:"default,omitempty"`
+// 		Unit    interface{} `yaml:"unit,omitempty" json:"unit,omitempty"`
+// 	} `yaml:"settings,omitempty" json:"settings,omitempty"`
+// }

+ 13 - 3
internal/models/templates.go

@@ -1,5 +1,7 @@
 package models
 
+import "helm.sh/helm/v3/pkg/chart"
+
 // IndexYAML represents a chart repo's index.yaml
 type IndexYAML struct {
 	APIVersion string                    `yaml:"apiVersion"`
@@ -21,12 +23,20 @@ type ChartYAML []struct {
 	Version     string   `yaml:"version"`
 }
 
-// PorterChart represents a bundled Porter template
-type PorterChart struct {
+// PorterChartList is how a chart gets displayed when listed
+type PorterChartList struct {
 	Name        string `json:"name"`
+	Version     string `json:"version"`
 	Description string `json:"description"`
 	Icon        string `json:"icon"`
-	Markdown    string `json:"markdown"`
+}
+
+// PorterChartRead is a chart with detailed information and a form for reading
+type PorterChartRead struct {
+	Markdown string                 `json:"markdown"`
+	Metadata *chart.Metadata        `json:"metadata"`
+	Values   map[string]interface{} `json:"values"`
+	Form     *FormYAML              `json:"form"`
 }
 
 // FormContext is the target context

+ 9 - 10
server/api/template_handler.go

@@ -10,7 +10,6 @@ import (
 	"github.com/porter-dev/porter/internal/forms"
 	"github.com/porter-dev/porter/internal/helm/loader"
 	"github.com/porter-dev/porter/internal/templater/parser"
-	"helm.sh/helm/v3/pkg/chart"
 
 	"github.com/porter-dev/porter/internal/models"
 )
@@ -27,12 +26,12 @@ func (app *App) HandleListTemplates(w http.ResponseWriter, r *http.Request) {
 	}
 
 	// Loop over charts in index.yaml
-	porterCharts := []models.PorterChart{}
+	porterCharts := []models.PorterChartList{}
 
 	for _, entry := range repoIndex.Entries {
 		indexChart := entry[0]
 
-		porterChart := models.PorterChart{}
+		porterChart := models.PorterChartList{}
 		porterChart.Name = indexChart.Name
 		porterChart.Description = indexChart.Description
 		porterChart.Icon = indexChart.Icon
@@ -43,12 +42,6 @@ func (app *App) HandleListTemplates(w http.ResponseWriter, r *http.Request) {
 	json.NewEncoder(w).Encode(porterCharts)
 }
 
-// ChartWithForm is a base helm chart with the form yaml appended
-type ChartWithForm struct {
-	*chart.Chart
-	Form *models.FormYAML `json:"form"`
-}
-
 // HandleReadTemplate reads a given template with name and version field
 func (app *App) HandleReadTemplate(w http.ResponseWriter, r *http.Request) {
 	name := chi.URLParam(r, "name")
@@ -86,7 +79,9 @@ func (app *App) HandleReadTemplate(w http.ResponseWriter, r *http.Request) {
 		HelmChart: chart,
 	}
 
-	res := &ChartWithForm{chart, nil}
+	res := &models.PorterChartRead{}
+	res.Metadata = chart.Metadata
+	res.Values = chart.Values
 
 	for _, file := range chart.Files {
 		if strings.Contains(file.Name, "form.yaml") {
@@ -97,6 +92,10 @@ func (app *App) HandleReadTemplate(w http.ResponseWriter, r *http.Request) {
 			}
 
 			res.Form = formYAML
+		} else if strings.Contains(file.Name, "README.md") {
+			res.Markdown = string(file.Data)
 		}
 	}
+
+	json.NewEncoder(w).Encode(res)
 }

+ 46 - 36
server/api/template_handler_test.go

@@ -6,12 +6,13 @@ import (
 	"strings"
 	"testing"
 
-	"github.com/porter-dev/porter/internal/kubernetes"
+	"github.com/go-test/deep"
+	"github.com/porter-dev/porter/internal/models"
 )
 
 // ------------------------- TEST TYPES AND MAIN LOOP ------------------------- //
 
-type templatesTest struct {
+type templateTest struct {
 	initializers []func(tester *tester)
 	msg          string
 	method       string
@@ -20,10 +21,10 @@ type templatesTest struct {
 	expStatus    int
 	expBody      string
 	useCookie    bool
-	validators   []func(c *templatesTest, tester *tester, t *testing.T)
+	validators   []func(c *templateTest, tester *tester, t *testing.T)
 }
 
-func testTemplatesRequests(t *testing.T, tests []*templatesTest, canQuery bool) {
+func testTemplatesRequests(t *testing.T, tests []*templateTest, canQuery bool) {
 	for _, c := range tests {
 		// create a new tester
 		tester := newTester(canQuery)
@@ -67,47 +68,56 @@ func testTemplatesRequests(t *testing.T, tests []*templatesTest, canQuery bool)
 
 // ------------------------- TEST FIXTURES AND FUNCTIONS  ------------------------- //
 
-// var listTemplatesTests = []*templatesTest{
-// 	&templatesTest{
-// 		initializers: []func(tester *tester){
-// 			initDefaultTemplates,
-// 		},
-// 		msg:       "List templates",
-// 		method:    "GET",
-// 		endpoint:  "/api/templates",
-// 		body:      "",
-// 		expStatus: http.StatusOK,
-// 		expBody:   "unimplemented",
-// 		useCookie: true,
-// 		validators: []func(c *templatesTest, tester *tester, t *testing.T){
-// 			templatesListValidator,
-// 		},
-// 	},
-// }
-
-// func TestHandleListTemplates(t *testing.T) {
-// 	testTemplatesRequests(t, listTemplatesTests, true)
-// }
+var listTemplatesTests = []*templateTest{
+	&templateTest{
+		initializers: []func(tester *tester){
+			initUserDefault,
+		},
+		msg:       "List templates",
+		method:    "GET",
+		endpoint:  "/api/templates",
+		body:      "",
+		expStatus: http.StatusOK,
+		expBody:   `[{"name":"Docker","description":"Template to deploy any Docker container on Porter.","icon":"https://cdn4.iconfinder.com/data/icons/logos-and-brands/512/97_Docker_logo_logos-512.png"},{"name":"redis","description":"DEPRECATED Open source, advanced key-value store. It is often referred to as a data structure server since keys can contain strings, hashes, lists, sets and sorted sets.","icon":"https://bitnami.com/assets/stacks/redis/img/redis-stack-220x234.png"}]`,
+		useCookie: true,
+		validators: []func(c *templateTest, tester *tester, t *testing.T){
+			templatesListValidator,
+		},
+	},
+}
+
+func TestHandleListTemplates(t *testing.T) {
+	testTemplatesRequests(t, listTemplatesTests, true)
+}
 
 // ------------------------- INITIALIZERS AND VALIDATORS ------------------------- //
 
-func initDefaultTemplates(tester *tester) {
-	initUserDefault(tester)
+func templatesListValidator(c *templateTest, tester *tester, t *testing.T) {
+	gotBody := make([]*models.PorterChartList, 0)
+	expBody := make([]*models.PorterChartList, 0)
 
-	agent := kubernetes.GetAgentTesting(defaultObjects...)
+	json.Unmarshal(tester.rr.Body.Bytes(), &gotBody)
+	json.Unmarshal([]byte(c.expBody), &expBody)
 
-	// overwrite the test agent with new resources
-	tester.app.TestAgents.K8sAgent = agent
+	if diff := deep.Equal(gotBody, expBody); diff != nil {
+		t.Errorf("handler returned wrong body:\n")
+		t.Error(diff)
+	}
 }
 
-func templatesListValidator(c *templatesTest, tester *tester, t *testing.T) {
-	var gotBody map[string]interface{}
-	var expBody map[string]interface{}
+func templateBodyValidator(c *templateTest, tester *tester, t *testing.T) {
+	gotBody := models.PorterChartRead{}
+	expBody := models.PorterChartRead{}
 
-	json.Unmarshal(tester.rr.Body.Bytes(), &gotBody)
+	bytes := tester.rr.Body.Bytes()
+
+	t.Errorf(string(bytes))
+
+	json.Unmarshal(bytes, &gotBody)
 	json.Unmarshal([]byte(c.expBody), &expBody)
 
-	if string(tester.rr.Body.Bytes()) != c.expBody {
-		t.Errorf("Mismatch")
+	if diff := deep.Equal(gotBody, expBody); diff != nil {
+		t.Errorf("handler returned wrong body:\n")
+		t.Error(diff)
 	}
 }