Skip to content

Conversation

@teresaromero
Copy link
Contributor

@teresaromero teresaromero commented Nov 28, 2025

What does this PR do?

Includes a validation rule for verifying the .hbs files used at input tempate and stream template are correct.
Also adds more information on the spec regarding the format of these templates and the helpers that are available at fleet when rendering them.
Linked file are also verified .hbs.link

Why is it important?

If a template arrives fleet without being checked, the can be errors when fleet renders the template. This is a way to prevent this before the package is installed.

Checklist

Added unit tests and validation test with test packages

Related issues

Relates #21

@teresaromero teresaromero requested a review from a team as a code owner November 28, 2025 09:19
@teresaromero
Copy link
Contributor Author

test integrations

Comment on lines 69 to 72
pkgEntries, err := fs.Glob(fsys, "agent/**/*.hbs")
if err != nil && !errors.Is(err, fs.ErrNotExist) {
return nil, err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

According to the spec, this files could also be links.
Would this catch even the links thanks to the filesystem ? Or is it needed to add a special case for link files?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i've updated the PR to include the linked files. For this i've changed the aproach of glob and used nested readDirs to get into the files.
i've added tests and test packages to check this works as expected with the links 👍🏻


// validateFile validates a single Handlebars file located at filePath.
// it parses the file using the raymond library to check for syntax errors.
func validateFile(filePath string) error {
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd rename this to be more specific, what about validateHandlebarTemplateFile or validateHandlebarTemplate?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yup, i've gone around this one :D as the "parent" function is very similar... i will think around this

@teresaromero teresaromero marked this pull request as draft December 1, 2025 14:09
@teresaromero teresaromero marked this pull request as ready for review December 1, 2025 15:56
@teresaromero
Copy link
Contributor Author

test integrations

@elastic-vault-github-plugin-prod

Created or updated PR in integrations repository to test this version. Check elastic/integrations#16224

Comment on lines +103 to +108
// If fs.ReadFile fails (likely due to linked file path outside filesystem boundary),
// fall back to absolute path approach like linkedfiles.FS does
absolutePath := fsys.Path(filePath)
if content, err = os.ReadFile(absolutePath); err != nil {
return err
}
Copy link
Contributor

Choose a reason for hiding this comment

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

According to the comment, is this already done by the linkedfiles.FS ? If so, maybe it could be removed from here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

this refers to the logic at getLinkedFileChecksum where the file content is read to get the checksum. If the file is not within fsys fs.ReadFile fails, as is not in its scope. If this happens, we use os.ReadFile (like in getLinkedFileChecksum) to read the file with the absolute path of it

Comment on lines +14 to +19
Available Handlebars helpers include:
- `contains` (checks if item is in array/string),
- `escape_string` (wraps string in single quotes and escapes them),
- `escape_multiline_string` (escapes multiline strings without wrapping),
- `to_json` (converts object to JSON string), and
- `url_encode` (URI encodes string).
Copy link
Contributor

Choose a reason for hiding this comment

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

These helpers are defined in Fleet (Kibana), it could be added a reference here in the description that the full list of helpers is in Fleet Kibana.

At least, I've found that they are defined here:
https://github.com/elastic/kibana/blob/70749d9216d7a5de6ce1e7a028d153d5390ad3ac/x-pack/platform/plugins/shared/fleet/server/services/epm/agent/agent.ts#L226
But not sure about adding this link since it could be outdated in the future.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

i took a list from that file and created the text with it, i will add the permlink to the file as a warning that these list can be updated so they can check the fleet code also

}
err = validateHandlebarsEntry(fsys, dir, linkFile.IncludedFilePath)
if err != nil {
return err
Copy link
Contributor

Choose a reason for hiding this comment

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

Could it be defined a specerrors.ValidationErrors here in this function and add all the errors found in a given folder?
I was thinking if it could be possible to show all the errors at once to the user.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

fixed this and adding more context to the error 👍🏻

an example of the output when testing one of the failed integration:

Error: building package failed: invalid content found in built zip package: found 1 validation error:
   1. invalid handlebars template: error validating data_stream/alerts_events_v2/agent/stream/gcs.yml.hbs: Parse error on line 49:
Expecting OpenEndBlock, got: 'EOF'

@elasticmachine
Copy link

💚 Build Succeeded

History

@teresaromero
Copy link
Contributor Author

after running the test against the current integrations, two of them had errors regarding some template parsing.
I opened a draft elastic/integrations#16230 to solve this. pending to test this changes

Config template file for inputs defined in the policy_templates section of the top level manifest.
The template should use standard Handlebars syntax (e.g., `{{vars.key}}`, `{{#if vars.condition}}`, `{{#each vars.items}}`)
and must compile to valid YAML.
Available Handlebars helpers include:
Copy link
Member

Choose a reason for hiding this comment

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

Can you please document the metadata variables that are available in templates too. See elastic/kibana#241140

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants