I looking for node module (or something else) that can parse in runtime parameters from my program into yaml files.
for example in kubernetes yamls
metadata:
name: $PROJECT_NAME
labels:
service: $SERVICE_NAME
system: $SYSTEM_ID
app_version: $PROJECT_VERSION
tier: app
There is a nice way to build new yaml or change the exist one that contain all my parameters values?
I decided to use Handlebars module
just give to the function a template with the parameters that i want to parse and the function will create new file contain all my changes
const Handlebars = require('handlebars');
const source = fs.readFileSync(`${cwd}/${file}`).toString();
const template = Handlebars.compile(source);
const contents = template({ PROJECT_NAME: `${name}`, PROJECT_VERSION: `${version}`, DOCKER_IMAGE: `${image}` });
fs.writeFileSync(`${cwd}/target/${file}`, contents);
console.log(`${file} -- Finish parsing YAML.`);
and the JSON look like
spec:
containers:
- name: {{PROJECT_NAME}}:{{PROJECT_VERSION}}
resources:
limits:
memory: "1Gi"
cpu: "1"
image: {{DOCKER_IMAGE}}
YAML doesn't always need a template as it is structured data. As long as you don't need formatting/comments, objects can be read or dumped with js-yaml.
const yaml = require('js-yaml')
const fs = require('fs')
const kyaml = {
metadata: {
name: project_name,
service: service_name,
system: system_id,
app_version: project_version,
tier: 'app',
}
}
fs.writeFile('new.yaml', yaml.safeDump(kyaml), 'utf8', err => {
if (err) console.log(err)
})
Also you could possibly be doing things that helm can already do for you with templates.
Any template engine should work but the templated values should be escaped appropriately if there is a chance the values will produce encoding errors. Because YAML is a superset of JSON, JSON.stringify can be safely used as a valid YAML escape function.
Using Mustache templates, we ensure all templated values are escaped by setting the escape function:
const mustache = require('mustache')
mustache.escape = JSON.stringify
mustache.render(template, vars)
Using Handlebars we can produce valid YAML by disabling the default escaping and providing a "json" helper:
const handlebars = require('handlebars')
const render = handlebars.compile(template, { noEscape: true })
render(vars, {helpers: { json: JSON.stringify }}))
The json helper needs to be used in the YAML template any time a value may require escaping:
metadata:
name: {{json projectName}}
labels:
version: {{buildId}}
tier: app
Without appropriate YAML escaping there could be encoding errors in the generated YAML document if values contain newlines or YAML special characters like "|". Some templating engines (eg Mustache and Handlebars) will escape values with HTML encoding by default which will also produce encoding errors if HTML special characters are present in values (eg quote which is escaped as "'").
Related
The ec2 launch tempate userdata definition using the template provider is about to be replaced with a templatefile function as it is deprecated.
The definition itself can be done without any problems, but an error occurs during the planning process saying that the processing variables for getting instance metadata etc. are undefined, is there any way to avoid this?
$ terraform version
Terraform v0.13.5
data "template_file" "userdata" {
template = templatefile("${path.module}/userdata.sh.tpl",
vars....
)
}
resource "aws_launch_template" "sample" {
....
user_data = base64encode(data.template_file.userdata.rendered)
....
}
The following definitions are applicable processing
export LOCAL_IP=$(ec2metadata --local-ipv4)
export GLOBAL_IP=$(ec2metadata --public-ipv4)
export REGION=$(curl -s http://169.254.169.254/latest/meta-data/placement/availability-zone | sed 's/[a-z]$//')
export AWS_DEFAULT_REGION="$${REGION}"
$ terraform plan
Error: failed to render : <template_file>:13,30-36: Unknown variable; There is no variable named "REGION"., and 4 other diagnostic(s)
thanks
It doesn't make sense to use the template_file data source and the templatefile function together, because these both do the same thing: render a template.
In your current configuration, you have the templatefile function rendering the template to produce a string, and then the template_file function interpreting that result as if it were a template, and so your template is being evaluated twice.
The first evaluation will turn $${REGION} into ${REGION} as expected, and then the second evaluation will try to handle ${REGION} as a template interpolation.
Instead, remove the template_file data source altogether (it's deprecated) and just use the templatefile function:
user_data = templatefile("${path.module}/userdata.sh.tpl, {
# ...
})
(I removed the base64encode function here because user_data expects an unencoded string value where the provider itself will do the base64 encoding. If you call base64encode yourself here then you'll end up with two levels of base64 encoding, which I imagine is not what you intended.)
I have a YAML file ('config.yaml') with this content:
egress:
hostName: example.com
tls:
- hosts:
- example.com
How can I extend this file in groovy?
Result must be like this:
egress:
hostName: example.com
tls:
- hosts:
- example.com
tag: 1.1.1
Thanks!
It depends.
If you want to treat config.yaml just as an ordinary text file, then you can just use common Groovy ways to work with IO:
String path = 'path/to/file'
File cfgFile = new File(path, 'config.yml')
cfgFile.withWriterAppend() { writer ->
writer.writeLine('\ntag: 1.1.1')
}
or just
new File(path, 'config.yml') << '\ntag: 1.1.1'
But if you want to build something more sophisticated and aware of YAML format of this file, then you can use SnakeYaml library:
#Grapes([
#Grab(group='org.yaml', module='snakeyaml', version='1.25')
])
import org.yaml.snakeyaml.Yaml
String path = '../data/'
File cfgFile = new File(path, 'config.yaml')
Yaml yaml = new Yaml()
Map content = [:]
cfgFile.withReader { reader ->
content = yaml.load(reader)
}
content.put('tag', '1.1.1')
cfgFile.withWriter { writer ->
yaml.dump(content, writer)
}
If you use Groovy 3.0+ then you can use built-in YamlSlurper and YamlBuilder instead.
(Groovy 3.0 is not released yet at the time of writing this answer)
One disadvantage here is that parsing and re-writing yaml file will get rid of comments and will reformat entire file.
I seem to be having an issue accessing a value from a mixin when trying to use bracket notation. I have the following setup:
// in webpack plugins
new HtmlWebpackPlugin({
hash: true,
template: './assets/template/about.pug',
filename: 'about-us.html',
inject: true,
page: 'about',
locals: require('./assets/data.json'),
chunks: ['about']
}),
The json
// data.json (snippet)
{
"pages" : {
"about" : {"title" : "About Us","metaDesc" : ""},
}
}
Pug mixin
mixin pageTitle(thePage)
title= htmlWebpackPlugin.options.locals.pages[thePage].title
Using pug mixin
+pageTitle(htmlWebpackPlugin.options.page)
I get an error Cannot read property 'title' of undefined.
If I change that to htmlWebpackPlugin.options.locals.pages.about.title it will parse just fine.
If I change that to htmlWebpackPlugin.options.locals.pages[thePage] it will return [object Object] but I can't access any properties.
If I change that to htmlWebpackPlugin.options.page or just use thePage then "about" will be rendered.
I've done a typeof to check if it's a string. It is. I've tried putting it into a variable first. Same issue.
Any thoughts?
Why do you need notation in brackets? What is the purpose of this?
This record works title = thePage.pages.about['title']
I prefer the following entry ;)
In the file about.pug, make an entry at the very top.
block variables
- var path = self.htmlWebpackPlugin.options
You pass on to the function
// locals is the path to your json file
+pageTitle(path.locals)
Mixin should look like this
mixin pageTile(thePage)
title = thePage.pages.about.title
Here you have the whole example in addition with generating multiple subpages with pug-loader → photoBlog
I want to use trancate filter in twig but i have the error:
The file "D:\projets\dzairdeals\config/services.yaml" does not contain valid YAML: Indentation problem in "D:\\projets\\dzairdeals\\config/services.yaml" at line 30 (near " twig.extension.text:") in D:\projets\dzairdeals\config/services.yaml (which is loaded in resource "D:\projets\dzairdeals\config/services.yaml").
When I try to add this lines to my services.yaml
twig.extension.text:
class: Twig_Extensions_Extension_Text
tags: - { name: twig.extension }
For anyone coming to this for Symfony 5:
composer require twig/string-extra
composer require twig/extra-bundle
Then you can use the truncate filter like so:
{{ project.title|u.truncate(30, '...') }}
Truncate filter is passed a length and an optional string to append to the end if truncated.
u. meaning the string on the left is encapsulated in a Unicode object, see https://twig.symfony.com/doc/2.x/filters/u.html
Make sure twig/extensions is installed:composer require twig/extensions, if so, you should see a config file auto-generated containing:
#config/packages/twig_extensions.yaml
services:
_defaults:
public: false
autowire: true
autoconfigure: true
# Uncomment any lines below to activate that Twig extension
#Twig\Extensions\ArrayExtension: null
#Twig\Extensions\DateExtension: null
#Twig\Extensions\IntlExtension: null
#Twig\Extensions\TextExtension: null
A correct indentation for your yaml file could be :
twig.extension.text:
class: Twig_Extensions_Extension_Text
tags:
- { name: twig.extension }
or
twig.extension.text:
class: Twig_Extensions_Extension_Text
tags: [twig.extension]
So in my js-code I have this line:
var _script = {
_script: {
script: {
lang: 'painless',
source: `
"""
if(1>2){
params._source.id;
}
else{
params._source.id;
}
"""
`
},
type: 'string',
order: params._source.id
}
}
This will fail. I see in the log this error message:
,\"reason\":\"unexpected token ['\\\"\\\\n if(1>2){\\\\n params._source.id;\\\\n }\\\\n else{\\\\n params._source.id;\\\\n }\\\\n \\\"'] was expecting one of [{<EOF>, ';'}].\"}}}]},
I have tried first to have without tilde-character. And then it also fails.
I then tried to have tilde at the beginning, something like:
var _script = `{
Thing is that the final json that will be sent to elastic is not shown in the code above. So "_script" is only a little part of all the json.
I was wondering if I added the tilde at the very beginning and end of the whole json. Maybe it could work? I need to work it out where it is.
But just in theory: do you think the problem is there? Putting the tilde around all the json? Or is it something else?
The triple " is not valid JSON, it only works internally to the Elastic stack (i.e. from Kibana Dev Tools to ES).
The way I usually do it from Node.js is to add each line to an array and then I join that array, like this:
const code = [];
code.push("if(1>2){");
code.push("params._source.id;");
code.push("} else {");
code.push("params._source.id;");
code.push("}");
source = code.join(" ");
It's not super legible, I admit. Another way is to use stored scripts so you can simple reference your script by ID in Node.js.