Skip to content

Commit

Permalink
Expose custom funcs to template
Browse files Browse the repository at this point in the history
Additional helper functions have proven useful to consumers when
rendering templates with hardware data. The concrete use-case is
formatting of partitions where nvme uses a different format to the
historical block device.
  • Loading branch information
chrisdoherty4 committed Aug 25, 2022
1 parent a0e9350 commit f8f1f8d
Show file tree
Hide file tree
Showing 4 changed files with 387 additions and 11 deletions.
15 changes: 8 additions & 7 deletions pkg/controllers/workflow/controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,12 +90,11 @@ func (c *Controller) processNewWorkflow(ctx context.Context, logger logr.Logger,
}

data := make(map[string]interface{})

for key, val := range stored.Spec.HardwareMap {
data[key] = val
}
var hardware v1alpha1.Hardware

var hardware v1alpha1.Hardware
err := c.kubeClient.Get(ctx, client.ObjectKey{Name: stored.Spec.HardwareRef, Namespace: stored.Namespace}, &hardware)
if err != nil && !errors.IsNotFound(err) {
logger.Error(err, "error getting Hardware object in processNewWorkflow function")
Expand All @@ -112,8 +111,7 @@ func (c *Controller) processNewWorkflow(ctx context.Context, logger logr.Logger,
}

if err == nil {
// convert between hardware and hardwareTemplate type
contract := toTemplateHardware(hardware)
contract := toTemplateHardwareData(hardware)
data["Hardware"] = contract
}

Expand All @@ -129,12 +127,15 @@ func (c *Controller) processNewWorkflow(ctx context.Context, logger logr.Logger,
return reconcile.Result{}, nil
}

type hardwareTemplate struct {
// templateHardwareData defines the data exposed for a Hardware instance to a Template.
type templateHardwareData struct {
Disks []string
}

func toTemplateHardware(hardware v1alpha1.Hardware) hardwareTemplate {
var contract hardwareTemplate
// toTemplateHardwareData converts a Hardware instance fo templateHardwareData for use in template
// rendering.
func toTemplateHardwareData(hardware v1alpha1.Hardware) templateHardwareData {
var contract templateHardwareData
for _, disk := range hardware.Spec.Disks {
contract.Disks = append(contract.Disks, disk.Device)
}
Expand Down
30 changes: 30 additions & 0 deletions workflow/funcs.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package workflow

import (
"fmt"
"strings"
)

// templateFuncs defines the custom functions available to workflow templates.
var templateFuncs = map[string]interface{}{
"contains": strings.Contains,
"hasPrefix": strings.HasPrefix,
"hasSuffix": strings.HasSuffix,
"formatPartition": formatPartition,
}

// formatPartition formats a device path with partition for the device type. If it receives an
// unidentifiable device path it returns the dev.
//
// Examples
// formatPartition("/dev/nvme0n1", 0) -> /dev/nvme0n1p1
// formatPartition("/dev/sda", 1) -> /dev/sda1
func formatPartition(dev string, partition int) string {
switch {
case strings.HasPrefix(dev, "/dev/nvme"):
return fmt.Sprintf("%vp%v", dev, partition)
case strings.HasPrefix(dev, "/dev/sd"):
return fmt.Sprintf("%v%v", dev, partition)
}
return dev
}
8 changes: 4 additions & 4 deletions workflow/template_validator.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,17 +78,17 @@ func RenderTemplate(templateID, templateData string, devices []byte) (string, er

// RenderTemplateHardware renders the workflow template and returns the Workflow and the interpolated bytes.
func RenderTemplateHardware(templateID, templateData string, hardware map[string]interface{}) (*Workflow, *bytes.Buffer, error) {
t := template.New("workflow-template").Option("missingkey=error")
t := template.New("workflow-template").
Option("missingkey=error").
Funcs(templateFuncs)
_, err := t.Parse(templateData)
if err != nil {
err = errors.Wrapf(err, errTemplateParsing, templateID)
return nil, nil, err
}

// introduces hardware to the template rendering
buf := new(bytes.Buffer)
err = t.Execute(buf, hardware)
if err != nil {
if err = t.Execute(buf, hardware); err != nil {
err = errors.Wrapf(err, errTemplateParsing, templateID)
return nil, nil, err
}
Expand Down
Loading

0 comments on commit f8f1f8d

Please sign in to comment.