Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose custom funcs to template #638

Merged
merged 1 commit into from
Aug 26, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 of 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 {
Copy link
Member Author

@chrisdoherty4 chrisdoherty4 Aug 26, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we OK with this name? I originally had formatDevicePartition, and @displague called out the formatting produced is specific to Linux.

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