diff --git a/pkg/burner/create.go b/pkg/burner/create.go index ff43a08c4..e19e225e6 100644 --- a/pkg/burner/create.go +++ b/pkg/burner/create.go @@ -46,7 +46,6 @@ func setupCreateJob(jobConfig config.Job) Executor { var f io.Reader var err error log.Infof("Preparing create job: %s", jobConfig.Name) - var empty interface{} selector := util.NewSelector() selector.Configure("", fmt.Sprintf("kube-burner-job=%s", jobConfig.Name), "") ex := Executor{ @@ -72,15 +71,19 @@ func setupCreateJob(jobConfig config.Job) Executor { } // Deserialize YAML uns := &unstructured.Unstructured{} - renderedObj := renderTemplate(t, empty, missingKeyDefault) - _, gvk := yamlToUnstructured(renderedObj, uns) + cleanTemplate, err := prepareTemplate(t) + if err != nil { + log.Fatalf("Error preparing template %s: %s", o.ObjectTemplate, err) + } + _, gvk := yamlToUnstructured(cleanTemplate, uns) gvr, _ := meta.UnsafeGuessKindToResource(*gvk) obj := object{ - gvr: gvr, - objectSpec: t, - replicas: o.Replicas, - unstructured: uns, - inputVars: o.InputVars, + gvr: gvr, + objectSpec: t, + objectTemplate: o.ObjectTemplate, + replicas: o.Replicas, + unstructured: uns, + inputVars: o.InputVars, } log.Infof("Job %s: %d iterations with %d %s replicas", jobConfig.Name, jobConfig.JobIterations, obj.replicas, gvk.Kind) ex.objects = append(ex.objects, obj) @@ -163,7 +166,10 @@ func (ex *Executor) replicaHandler(objectIndex int, obj object, ns string, itera for r := 1; r <= obj.replicas; r++ { newObject := &unstructured.Unstructured{} templateData[replica] = r - renderedObj := renderTemplate(obj.objectSpec, templateData, missingKeyError) + renderedObj, err := renderTemplate(obj.objectSpec, templateData, missingKeyError) + if err != nil { + log.Fatalf("Template error in %s: %s", obj.objectTemplate, err) + } // Re-decode rendered object yamlToUnstructured(renderedObj, newObject) for k, v := range newObject.GetLabels() { diff --git a/pkg/burner/job.go b/pkg/burner/job.go index 2c25a7fb3..045ad5645 100644 --- a/pkg/burner/job.go +++ b/pkg/burner/job.go @@ -30,12 +30,13 @@ import ( ) type object struct { - gvr schema.GroupVersionResource - objectSpec []byte - replicas int - unstructured *unstructured.Unstructured - inputVars map[string]string - labelSelector map[string]string + gvr schema.GroupVersionResource + objectTemplate string + objectSpec []byte + replicas int + unstructured *unstructured.Unstructured + inputVars map[string]string + labelSelector map[string]string } // Executor contains the information required to execute a job diff --git a/pkg/burner/utils.go b/pkg/burner/utils.go index 9698b4c1d..ca66ef221 100644 --- a/pkg/burner/utils.go +++ b/pkg/burner/utils.go @@ -18,6 +18,8 @@ import ( "bytes" "context" "fmt" + "regexp" + "strings" "text/template" "time" @@ -38,21 +40,34 @@ const ( retryBackoffFactor = 3 retryBackoffJitter = 0 retryBackoffSteps = 3 - missingKeyDefault templateOption = "missingkey=default" missingKeyError templateOption = "missingkey=error" ) -func renderTemplate(original []byte, data interface{}, options templateOption) []byte { +func prepareTemplate(original []byte) ([]byte, error) { + // Removing all placeholder from template. + // This needs to be done due to placeholders not being valid yaml. + if isEmpty(original) { + return nil, fmt.Errorf("template is empty") + } + r, err := regexp.Compile(`\{\{.*\}\}`) + if err != nil { + return nil, fmt.Errorf("regexp creation error: %v", err) + } + original = r.ReplaceAll(original, []byte{}) + return original, nil +} + +func renderTemplate(original []byte, data interface{}, options templateOption) ([]byte, error) { var rendered bytes.Buffer t, err := template.New("").Option(string(options)).Parse(string(original)) if err != nil { - log.Fatalf("Error parsing template: %s", err) + return nil, fmt.Errorf("Parsing error: %s", err) } err = t.Execute(&rendered, data) if err != nil { - log.Fatalf("Error rendering template: %s", err) + return nil, fmt.Errorf("Rendering error: %s", err) } - return rendered.Bytes() + return rendered.Bytes(), nil } func yamlToUnstructured(y []byte, uns *unstructured.Unstructured) (runtime.Object, *schema.GroupVersionKind) { @@ -113,3 +128,7 @@ func RetryWithExponentialBackOff(fn wait.ConditionFunc) error { } return wait.ExponentialBackoff(backoff, fn) } + +func isEmpty(raw []byte) bool { + return strings.TrimSpace(string(raw)) == "" +}