|
|
@@ -4,6 +4,7 @@ import (
|
|
|
"archive/tar"
|
|
|
"bytes"
|
|
|
"compress/gzip"
|
|
|
+ "encoding/json"
|
|
|
"errors"
|
|
|
"fmt"
|
|
|
"io"
|
|
|
@@ -15,15 +16,80 @@ import (
|
|
|
"gopkg.in/yaml.v2"
|
|
|
)
|
|
|
|
|
|
+// DeployTemplateForm describes the parameters of a deploy template request
|
|
|
+type DeployTemplateForm struct {
|
|
|
+ TemplateName string
|
|
|
+ ClusterID int
|
|
|
+ ImageURL string
|
|
|
+ FormValues map[string]interface{}
|
|
|
+}
|
|
|
+
|
|
|
// HandleDeployTemplate triggers a chart deployment from a template
|
|
|
func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
|
|
|
- tgt := "hello-porter"
|
|
|
+
|
|
|
+ // TODO: use create form
|
|
|
+ requestForm := make(map[string]interface{})
|
|
|
+
|
|
|
+ // decode from JSON to form value
|
|
|
+ if err := json.NewDecoder(r.Body).Decode(&requestForm); err != nil {
|
|
|
+ app.handleErrorFormDecoding(err, ErrProjectDecode, w)
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // TODO: use create form
|
|
|
+ params := DeployTemplateForm{}
|
|
|
+ params.TemplateName = requestForm["templateName"].(string)
|
|
|
+ params.ClusterID = int(requestForm["clusterID"].(float64))
|
|
|
+ params.ImageURL = requestForm["imageURL"].(string)
|
|
|
+ params.FormValues = requestForm["formValues"].(map[string]interface{})
|
|
|
|
|
|
baseURL := "https://porter-dev.github.io/chart-repo/"
|
|
|
+ defaultValues, err := getDefaultValues(params.TemplateName, baseURL)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // Loop through form params to override
|
|
|
+ for k := range params.FormValues {
|
|
|
+ switch v := interface{}(k).(type) {
|
|
|
+ case string:
|
|
|
+ splits := strings.Split(v, ".")
|
|
|
+
|
|
|
+ // Validate that the field to override exists
|
|
|
+ currentLoc := *defaultValues
|
|
|
+ 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 := params.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")
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ d, err := yaml.Marshal(defaultValues)
|
|
|
+ if err != nil {
|
|
|
+ return
|
|
|
+ }
|
|
|
+
|
|
|
+ // Output values.yaml string
|
|
|
+ fmt.Println(string(d))
|
|
|
+}
|
|
|
+
|
|
|
+func getDefaultValues(templateName string, baseURL string) (*map[interface{}]interface{}, error) {
|
|
|
resp, err := http.Get(baseURL + "index.yaml")
|
|
|
if err != nil {
|
|
|
fmt.Println(err)
|
|
|
- return
|
|
|
+ return nil, err
|
|
|
}
|
|
|
|
|
|
defer resp.Body.Close()
|
|
|
@@ -32,7 +98,7 @@ func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
|
|
|
form := models.IndexYAML{}
|
|
|
if err := yaml.Unmarshal([]byte(body), &form); err != nil {
|
|
|
fmt.Println(err)
|
|
|
- return
|
|
|
+ return nil, err
|
|
|
}
|
|
|
|
|
|
// Loop over charts in index.yaml
|
|
|
@@ -47,25 +113,20 @@ func (app *App) HandleDeployTemplate(w http.ResponseWriter, r *http.Request) {
|
|
|
}
|
|
|
|
|
|
// Unpack the target chart and retrieve values.yaml
|
|
|
- if strAcc == tgt {
|
|
|
+ if strAcc == templateName {
|
|
|
tgtURL := baseURL + tarURL
|
|
|
values, err := processValues(tgtURL)
|
|
|
if err != nil {
|
|
|
fmt.Println(err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- defaultValues := *values
|
|
|
- defaultValues["replicaCount"] = 87
|
|
|
- fmt.Println(defaultValues["replicaCount"])
|
|
|
- for k := range *values {
|
|
|
- fmt.Println(k)
|
|
|
+ return nil, err
|
|
|
}
|
|
|
+ return values, nil
|
|
|
}
|
|
|
}
|
|
|
+ return nil, errors.New("no values.yaml found")
|
|
|
}
|
|
|
|
|
|
-func processValues(tgtURL string) (*map[string]interface{}, error) {
|
|
|
+func processValues(tgtURL string) (*map[interface{}]interface{}, error) {
|
|
|
resp, err := http.Get(tgtURL)
|
|
|
if err != nil {
|
|
|
fmt.Println(err)
|
|
|
@@ -110,7 +171,7 @@ func processValues(tgtURL string) (*map[string]interface{}, error) {
|
|
|
}
|
|
|
|
|
|
// Unmarshal yaml byte buffer
|
|
|
- form := make(map[string]interface{})
|
|
|
+ form := make(map[interface{}]interface{})
|
|
|
if err := yaml.Unmarshal(bufForm.Bytes(), &form); err != nil {
|
|
|
fmt.Println(err)
|
|
|
return nil, err
|