Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

nodejs templating yaml files

Tags:

node.js

yaml

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?

like image 233
Dor Alteresku Avatar asked Mar 21 '18 11:03

Dor Alteresku


3 Answers

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.

like image 139
Matt Avatar answered Nov 17 '22 01:11

Matt


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}}
like image 31
Dor Alteresku Avatar answered Nov 17 '22 00:11

Dor Alteresku


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 "'").

like image 1
Nathan Avatar answered Nov 16 '22 23:11

Nathan