Skip to content

Commit

Permalink
[Fleet] add escapeMultilineString Handlebar helper (elastic#195159)
Browse files Browse the repository at this point in the history
## Summary

Adding a handlebar helper to escape multiline strings. It has the same
function as `escapeStringHelper`, but does not wrap strings in single
quotes, allowing concatenation of escaped variables in the `hbs`
template such as this example:

```hbs
audit_rules: "{{escape_multiline_string audit_rules}}
  {{escape_multiline_string "
  # Session data audit rules
  -a always,exit -F arch=b64 -S execve,execveat -k exec
  -a always,exit -F arch=b64 -S exit_group
  -a always,exit -F arch=b64 -S setsid"}}"
{{else}}
  {{#if audit_rules}}
audit_rules: {{escape_string audit_rules}}
  {{/if}}
{{/if}}
```

The above would not be possible using only `escape_string` as
`audit_rules` would be wrapped in single quotes.

## Screenshots

The example above illustrates how this option allows the Auditd manager
integration to append Session data audit rules to the `audit_rules`
field when Session data is enabled in the integration
([PR](elastic/integrations#11336)).

<img width="872" alt="image"
src="https://github.com/user-attachments/assets/325d784d-26a4-4dfe-9d0e-54d51c3ed060">

<img width="801" alt="image"
src="https://github.com/user-attachments/assets/ebd521c0-4471-48f9-ba8d-94630ea0efd2">
  • Loading branch information
opauloh authored Oct 8, 2024
1 parent 2d68749 commit 407137a
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 0 deletions.
74 changes: 74 additions & 0 deletions x-pack/plugins/fleet/server/services/epm/agent/agent.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,80 @@ New lines and \\n escaped values.`,
});
});

describe('escape_multiline_string helper', () => {
it('should escape new lines', () => {
const streamTemplate = `
input: log
multiline_text: "{{escape_multiline_string multiline_text}}"
`;

const vars = {
multiline_text: {
type: 'textarea',
value: `This is a text with
New lines and \n escaped values.`,
},
};

const output = compileTemplate(vars, streamTemplate);
expect(output).toEqual({
input: 'log',
multiline_text: `This is a text with
New lines and
escaped values.`,
});
});

it('should escape single quotes', () => {
const streamTemplate = `
input: log
multiline_text: "{{escape_multiline_string multiline_text}}"
`;

const vars = {
multiline_text: {
type: 'textarea',
value: `This is a multiline text with
'escaped values.'`,
},
};

const output = compileTemplate(vars, streamTemplate);
expect(output).toEqual({
input: 'log',
multiline_text: `This is a multiline text with
''escaped values.''`,
});
});

it('should allow concatenation of multiline strings', () => {
const streamTemplate = `
input: log
multiline_text: "{{escape_multiline_string multiline_text}}{{escape_multiline_string "
This is a concatenated text
with new lines"}}"
`;

const vars = {
multiline_text: {
type: 'textarea',
value: `This is a text with
New lines and\nescaped values.`,
},
};

const output = compileTemplate(vars, streamTemplate);
expect(output).toEqual({
input: 'log',
multiline_text: `This is a text with
New lines and
escaped values.
This is a concatenated text
with new lines`,
});
});
});

describe('to_json helper', () => {
const streamTemplate = `
input: log
Expand Down
12 changes: 12 additions & 0 deletions x-pack/plugins/fleet/server/services/epm/agent/agent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,18 @@ function escapeStringHelper(str: string) {
}
handlebars.registerHelper('escape_string', escapeStringHelper);

/**
* escapeMultilineStringHelper will escape a multiline string by doubling the newlines
* and escaping single quotes.
* This is useful when the string is multiline and needs to be escaped in a yaml file
* without wrapping it in single quotes.
*/
function escapeMultilineStringHelper(str: string) {
if (!str) return undefined;
return str.replace(/\'/g, "''").replace(/\n/g, '\n\n');
}
handlebars.registerHelper('escape_multiline_string', escapeMultilineStringHelper);

// toJsonHelper will convert any object to a Json string.
function toJsonHelper(value: any) {
if (typeof value === 'string') {
Expand Down

0 comments on commit 407137a

Please sign in to comment.