ソースを参照

get release handler updated

Alexander Belanger 5 年 前
コミット
dbeab5fbb5

+ 18 - 0
internal/kubernetes/config.go

@@ -14,6 +14,7 @@ import (
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/cli-runtime/pkg/genericclioptions"
 	"k8s.io/client-go/discovery"
 	"k8s.io/client-go/discovery"
 	diskcached "k8s.io/client-go/discovery/cached/disk"
 	diskcached "k8s.io/client-go/discovery/cached/disk"
+	"k8s.io/client-go/dynamic"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/kubernetes"
 	"k8s.io/client-go/kubernetes/fake"
 	"k8s.io/client-go/kubernetes/fake"
 	"k8s.io/client-go/rest"
 	"k8s.io/client-go/rest"
@@ -28,6 +29,23 @@ import (
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
 	_ "k8s.io/client-go/plugin/pkg/client/auth"
 )
 )
 
 
+// GetDynamicClientOutOfClusterConfig creates a new dynamic client using the OutOfClusterConfig
+func GetDynamicClientOutOfClusterConfig(conf *OutOfClusterConfig) (dynamic.Interface, error) {
+	restConf, err := conf.ToRESTConfig()
+
+	if err != nil {
+		return nil, err
+	}
+
+	client, err := dynamic.NewForConfig(restConf)
+
+	if err != nil {
+		return nil, err
+	}
+
+	return client, nil
+}
+
 // GetAgentOutOfClusterConfig creates a new Agent using the OutOfClusterConfig
 // GetAgentOutOfClusterConfig creates a new Agent using the OutOfClusterConfig
 func GetAgentOutOfClusterConfig(conf *OutOfClusterConfig) (*Agent, error) {
 func GetAgentOutOfClusterConfig(conf *OutOfClusterConfig) (*Agent, error) {
 	restConf, err := conf.ToRESTConfig()
 	restConf, err := conf.ToRESTConfig()

+ 36 - 13
internal/templater/parser/parser.go

@@ -21,7 +21,6 @@ import (
 
 
 type ClientConfigDefault struct {
 type ClientConfigDefault struct {
 	DynamicClient dynamic.Interface
 	DynamicClient dynamic.Interface
-	DynamicObject *td.Object
 
 
 	HelmAgent   *helm.Agent
 	HelmAgent   *helm.Agent
 	HelmRelease *release.Release
 	HelmRelease *release.Release
@@ -127,18 +126,33 @@ func formToLookupTable(def *ClientConfigDefault, form *models.FormYAML) map[*mod
 					lookup[content.Context] = formContextToContextConfig(def, content.Context)
 					lookup[content.Context] = formContextToContextConfig(def, content.Context)
 				}
 				}
 
 
-				// TODO -- case on whether value is proper query string, if not resolve it to a
-				// proper query string
-				query, err := utils.NewQuery(
-					fmt.Sprintf("tabs[%d].sections[%d].contents[%d]", i, j, k),
-					fmt.Sprintf("%v", content.Value),
-				)
-
-				if err != nil {
-					continue
+				if content.Value != "" {
+					// TODO -- case on whether value is proper query string, if not resolve it to a
+					// proper query string
+					query, err := utils.NewQuery(
+						fmt.Sprintf("tabs[%d].sections[%d].contents[%d]", i, j, k),
+						fmt.Sprintf("%v", content.Value),
+					)
+
+					if err != nil {
+						continue
+					}
+
+					lookup[content.Context].TemplateReader.RegisterQuery(query)
+				} else if content.Variable != "" {
+					// if variable field set without value field set, make variable field into jsonpath
+					// query
+					query, err := utils.NewQuery(
+						fmt.Sprintf("tabs[%d].sections[%d].contents[%d]", i, j, k),
+						fmt.Sprintf("{ .%v }", content.Variable),
+					)
+
+					if err != nil {
+						continue
+					}
+
+					lookup[content.Context].TemplateReader.RegisterQuery(query)
 				}
 				}
-
-				lookup[content.Context].TemplateReader.RegisterQuery(query)
 			}
 			}
 		}
 		}
 	}
 	}
@@ -187,7 +201,16 @@ func formContextToContextConfig(def *ClientConfigDefault, context *models.FormCo
 
 
 		res.Capabilities = []string{"read"}
 		res.Capabilities = []string{"read"}
 
 
-		res.TemplateReader = td.NewDynamicTemplateReader(def.DynamicClient, def.DynamicObject)
+		// identify object based on passed config
+		obj := &td.Object{
+			Group:     context.Config["Group"],
+			Version:   context.Config["Version"],
+			Resource:  context.Config["Resource"],
+			Namespace: context.Config["Namespace"],
+			Name:      context.Config["Name"],
+		}
+
+		res.TemplateReader = td.NewDynamicTemplateReader(def.DynamicClient, obj)
 	default:
 	default:
 		return nil
 		return nil
 	}
 	}

+ 60 - 0
server/api/release_handler.go

@@ -5,6 +5,11 @@ import (
 	"net/http"
 	"net/http"
 	"net/url"
 	"net/url"
 	"strconv"
 	"strconv"
+	"strings"
+
+	"github.com/porter-dev/porter/internal/models"
+	"github.com/porter-dev/porter/internal/templater/parser"
+	"helm.sh/helm/v3/pkg/release"
 
 
 	"github.com/go-chi/chi"
 	"github.com/go-chi/chi"
 	"github.com/porter-dev/porter/internal/forms"
 	"github.com/porter-dev/porter/internal/forms"
@@ -60,6 +65,11 @@ func (app *App) HandleListReleases(w http.ResponseWriter, r *http.Request) {
 	}
 	}
 }
 }
 
 
+type PorterRelease struct {
+	*release.Release
+	Form *models.FormYAML `json:"form"`
+}
+
 // HandleGetRelease retrieves a single release based on a name and revision
 // HandleGetRelease retrieves a single release based on a name and revision
 func (app *App) HandleGetRelease(w http.ResponseWriter, r *http.Request) {
 func (app *App) HandleGetRelease(w http.ResponseWriter, r *http.Request) {
 	name := chi.URLParam(r, "name")
 	name := chi.URLParam(r, "name")
@@ -98,6 +108,56 @@ func (app *App) HandleGetRelease(w http.ResponseWriter, r *http.Request) {
 		return
 		return
 	}
 	}
 
 
+	// get the filter options
+	k8sForm := &forms.K8sForm{
+		OutOfClusterConfig: &kubernetes.OutOfClusterConfig{
+			Repo: app.repo,
+		},
+	}
+
+	vals, err := url.ParseQuery(r.URL.RawQuery)
+
+	if err != nil {
+		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
+		return
+	}
+
+	k8sForm.PopulateK8sOptionsFromQueryParams(vals, app.repo.Cluster)
+
+	// validate the form
+	if err := app.validator.Struct(k8sForm); err != nil {
+		app.handleErrorFormValidation(err, ErrK8sValidate, w)
+		return
+	}
+
+	// create a new dynamic client
+	dynClient, err := kubernetes.GetDynamicClientOutOfClusterConfig(k8sForm.OutOfClusterConfig)
+
+	if err != nil {
+		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
+		return
+	}
+
+	parserDef := &parser.ClientConfigDefault{
+		DynamicClient: dynClient,
+		HelmChart:     release.Chart,
+		HelmRelease:   release,
+	}
+
+	res := &PorterRelease{release, nil}
+
+	for _, file := range release.Chart.Files {
+		if strings.Contains(file.Name, "form.yaml") {
+			formYAML, _ := parser.FormYAMLFromBytes(parserDef, file.Data)
+			if err != nil {
+				break
+			}
+
+			res.Form = formYAML
+			break
+		}
+	}
+
 	if err := json.NewEncoder(w).Encode(release); err != nil {
 	if err := json.NewEncoder(w).Encode(release); err != nil {
 		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
 		app.handleErrorFormDecoding(err, ErrReleaseDecode, w)
 		return
 		return