Expandybird now expands a chart. Also fixed validation (broken in templates too).

pull/393/head
Dave Cunningham 10 years ago
parent 51df379c66
commit ad787b9085

@ -19,6 +19,7 @@ package expander
import ( import (
"bytes" "bytes"
"fmt" "fmt"
"encoding/base64"
"encoding/json" "encoding/json"
"log" "log"
"os/exec" "os/exec"
@ -118,9 +119,24 @@ func (eResponse *ExpansionResponse) Unmarshal() (*ExpansionResult, error) {
// ExpandTemplate passes the given configuration to the expander and returns the // ExpandTemplate passes the given configuration to the expander and returns the
// expanded configuration as a string on success. // expanded configuration as a string on success.
func (e *expander) ExpandTemplate(template *common.Template) (string, error) { func (e *expander) ExpandTemplate(request *common.Template) (string, error) {
chartInv := template.ChartInvocation if request.ChartInvocation == nil {
chart := template.Chart message := fmt.Sprintf("Request does not have invocation field")
return "", fmt.Errorf("error processing request: %s", message)
}
if request.Chart == nil {
message := fmt.Sprintf("Request does not have chart field")
return "", fmt.Errorf("error processing request: %s", message)
}
chartInv := request.ChartInvocation
chart := request.Chart
schemaName := chartInv.Type + ".schema"
if chart.Expander == nil {
message := fmt.Sprintf("Chart JSON does not have expander field")
return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message)
}
if chart.Expander.Name != "Expandybird" { if chart.Expander.Name != "Expandybird" {
message := fmt.Sprintf("Expandybird cannot do this kind of expansion: ", chart.Expander) message := fmt.Sprintf("Expandybird cannot do this kind of expansion: ", chart.Expander)
@ -132,15 +148,25 @@ func (e *expander) ExpandTemplate(template *common.Template) (string, error) {
return "", fmt.Errorf("error expanding chart %s: %s", chartInv.Name, message) return "", fmt.Errorf("error expanding chart %s: %s", chartInv.Name, message)
} }
if len(chart.Files) != 1 { entrypointIndex := -1
message := fmt.Sprintf("Expandybird can only process a chart containing 1 file, got %d", len(chart.Files)) for i, f := range chart.Files {
if f.Path == chart.Expander.Entrypoint {
entrypointIndex = i
}
}
if entrypointIndex == -1 {
message := fmt.Sprintf("The entrypoint in the chart.yaml cannot be found: %s", chart.Expander.Entrypoint)
return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message) return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message)
} }
entrypoint_file := chart.Files[0] schemaIndex := -1
for i, f := range chart.Files {
if entrypoint_file.Path != chart.Expander.Entrypoint { if f.Path == chart.Schema {
message := fmt.Sprintf("The entrypoint in the chart.yaml canont be found %s", chart.Expander.Entrypoint) schemaIndex = i
}
}
if schemaIndex == -1 {
message := fmt.Sprintf("The schema in the chart.yaml cannot be found: %s", chart.Schema)
return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message) return "", fmt.Errorf("error expanding template %s: %s", chartInv.Name, message)
} }
@ -161,24 +187,30 @@ func (e *expander) ExpandTemplate(template *common.Template) (string, error) {
Path: e.ExpansionBinary, Path: e.ExpansionBinary,
// Note, that binary name still has to be passed argv[0]. // Note, that binary name still has to be passed argv[0].
Args: []string{e.ExpansionBinary, content}, Args: []string{e.ExpansionBinary, content},
// TODO(vagababov): figure out whether do we even need "PROJECT" and
// "DEPLOYMENT_NAME" variables here.
// [dcunnin]: Assuming we won't need this, at least for now.
// Env: append(os.Environ(), "PROJECT="+chartInv.Name, "DEPLOYMENT_NAME="+chartInv.Name),
Stdout: &stdout, Stdout: &stdout,
Stderr: &stderr, Stderr: &stderr,
} }
// Add entrypoint file (currently only 1 is supported). if chart.Schema != "" {
cmd.Args = append(cmd.Args, chart.Name, entrypoint_file.Path, entrypoint_file.Content) cmd.Env = []string{"VALIDATE_SCHEMA=1"}
}
// Add schema file for i, f := range chart.Files {
schema_name := chart.Name + ".schema" name := f.Path
schemaJson, err := json.Marshal(chart.Schema) path := f.Path
if i == entrypointIndex {
// This is how expandybird identifies the entrypoint.
name = chartInv.Type
} else if i == schemaIndex {
// Doesn't matter what it was originally called, expandybird expects to find it here.
name = schemaName
}
bytes, err := base64.StdEncoding.DecodeString(f.Content)
if err != nil { if err != nil {
return "", fmt.Errorf("error marshalling schema %s: %s", chartInv.Name, err) return "", err
}
cmd.Args = append(cmd.Args, name, path, string(bytes))
} }
cmd.Args = append(cmd.Args, schema_name, schema_name, string(schemaJson))
if err := cmd.Start(); err != nil { if err := cmd.Start(); err != nil {
log.Printf("error starting expansion process: %s", err) log.Printf("error starting expansion process: %s", err)

@ -380,8 +380,8 @@ def main():
idx += 3 idx += 3
env = {} env = {}
env['deployment'] = os.environ['DEPLOYMENT_NAME'] # env['deployment'] = os.environ['DEPLOYMENT_NAME']
env['project'] = os.environ['PROJECT'] # env['project'] = os.environ['PROJECT']
validate_schema = 'VALIDATE_SCHEMA' in os.environ validate_schema = 'VALIDATE_SCHEMA' in os.environ

@ -128,7 +128,7 @@ def Validate(properties, schema_name, template_name, imports):
if properties is None: if properties is None:
properties = {} properties = {}
schema = yaml.safe_load(raw_schema) schema = yaml.safe_load(raw_schema['content'])
# If the schema is empty, do nothing. # If the schema is empty, do nothing.
if not schema: if not schema:

@ -110,7 +110,7 @@ type ChartFile struct {
type Chart struct { type Chart struct {
Name string `json:"name"` Name string `json:"name"`
Expander *Expander `json:"expander"` Expander *Expander `json:"expander"`
Schema interface{} `json:"schema"` Schema string `json:"schema"`
Files []*ChartFile `json:"files"` Files []*ChartFile `json:"files"`
} }
@ -119,17 +119,9 @@ type Chart struct {
// describes the set in a form that can be instantiated. // describes the set in a form that can be instantiated.
type Template struct { type Template struct {
ChartInvocation *Resource `json:"chart_invocation"` ChartInvocation *Resource `json:"chart_invocation"`
Chart Chart `json:"chart"` Chart *Chart `json:"chart"`
} }
/*
// ImportFile describes a base64 encoded file imported by a Template.
type ImportFile struct {
Name string `json:"name,omitempty"`
Chart Chart `json:"chart"`
}
*/
// Configuration describes a set of resources in a form // Configuration describes a set of resources in a form
// that can be instantiated. // that can be instantiated.
type Configuration struct { type Configuration struct {

Loading…
Cancel
Save