GithubHelp home page GithubHelp logo

virtuslab / render Goto Github PK

View Code? Open in Web Editor NEW
139.0 14.0 23.0 4.99 MB

Universal data-driven template for generating textual output, as a static binary and a library

License: Apache License 2.0

Go 69.56% Makefile 7.33% Makefile 7.34% Makefile 7.34% Makefile 8.42%
golang kubernetes renderer helm text cli

render's Introduction

render

Version Travis CI Github All Releases Go Report Card GoDoc

Universal data-driven templates for generating textual output. Can be used as a single static binary (no dependencies) or as a golang library.

Just some of the things to render:

  • configuration files
  • Infrastructure as Code files (e.g. CloudFormation templates)
  • Kubernetes manifests

The renderer extends go-template and Sprig functions.

If you are interested in one of the use cases, take a look at this blog post about Kubernetes resources rendering. Also see Helm compatibility.

Installation

Official binary releases

For binaries please visit the Releases Page.

The binaries are statically compiled and does not require any dependencies.

Usage

$ render --help
NAME:
   render - Universal file renderer

USAGE:
   render [global options] command [command options] [arguments...]

VERSION:
   v0.3.0

AUTHOR:
   VirtusLab

COMMANDS:
     help, h  Shows a list of commands or help for one command

GLOBAL OPTIONS:
   --debug, -d                   run in debug mode
   --silent, -s                  run in silent mode
   --indir value                 the input directory, can't be used with --out
   --outdir value                the output directory, the same as --outdir if empty, can't be used with --in
   --in value                    the input template file, stdin if empty, can't be used with --outdir
   --out value                   the output file, stdout if empty, can't be used with --indir
   --config value                optional configuration YAML file, can be used multiple times
   --set value, --var value      additional parameters in key=value format, can be used multiple times
   --unsafe-ignore-missing-keys  do not fail on missing map key and print '<no value>' ('missingkey=invalid')
   --help, -h                    show help
   --version, -v                 print the version

Notes:

  • --in, --out take only files (not directories), --in will consume any file as long as it can be parsed
  • stdin and stdout can be used instead of --in and --out
  • --config accepts any YAML file, can be used multiple times, the values of the configs will be merged
  • --set, --var are the same (one is used in Helm, the other in Terraform), we provide both for convenience, any values set here will override values form configuration files

Command line

Example usage of render with stdin, stdout and --var:

$ echo "something {{ .value }}" | render --var "value=new"
something new

Example usage of render with --in, --out and --config:

$ echo "something {{ .value }}" > test.txt.tmpl
$ echo "value: new" > test.config.yaml
$ ./render --in test.txt.tmpl --out test.txt --config test.config.yaml
$ cat test.txt
something new

Also see a more advanced template example.

As a library

package example

import (
    "github.com/VirtusLab/render/renderer"
    "github.com/VirtusLab/render/renderer/parameters"
)

func CustomRender(template string, opts []string, params parameters.Parameters) (string, error) {
    return renderer.New(
    	renderer.WithOptions(opts...),
        renderer.WithParameters(params),
        renderer.WithSprigFunctions(),
        renderer.WithExtraFunctions(),
        renderer.WithCryptFunctions(),
    ).Render(template)
}

See also other functions.

Also see tests for more usage examples.

Notable standard and sprig functions

All syntax and functions:

Custom functions

  • render - calls the render from inside of the template, making the renderer recursive (also accepts an optional template parameters override)
  • toYaml - provides a configuration data structure fragment as a YAML format
  • fromYaml - marshalls YAML data to a data structure (supports multi-documents)
  • fromJson - marshalls JSON data to a data structure
  • jsonPath - provides data structure manipulation with JSONPath (kubectl dialect)
  • n - used with range to allow easy iteration over integers form the given start to end (inclusive)
  • gzip, ungzip - use gzip compression and extraction inside the templates, for best results use with b64enc and b64dec
  • readFile - reads a file from a path, relative paths are translated to absolute paths, based on root function or property
  • writeFile - writes a file to a path, relative paths are translated to absolute paths, based on root function or property
  • root - the root path, used for relative to absolute path translation in any file based operations; by default PWD is used
  • cidrHost - calculates a full host IP address for a given host number within a given IP network address prefix
  • cidrNetmask - converts an IPv4 address prefix given in CIDR notation into a subnet mask address
  • cidrSubnets - calculates a subnet address within given IP network address prefix
  • cidrSubnetSizes - calculates a sequence of consecutive IP address ranges within a particular CIDR prefix

See also examples and a more detailed documentation.

Cloud KMS (AWS, Amazon, Google) based cryptography functions form crypt:

  • encryptAWS - encrypts data using AWS KMS, for best results use with gzip and b64enc
  • decryptAWS - decrypts data using AWS KMS, for best results use with ungzip and b64dec
  • encryptGCP - encrypts data using GCP KMS, for best results use with gzip and b64enc
  • decryptGCP - decrypts data using GCP KMS, for best results use with ungzip and b64dec
  • encryptAzure - encrypts data using Azure Key Vault, for best results use with gzip and b64enc
  • decryptAzure - decrypts data using Azure Key Vault, for best results use with ungzip and b64dec

Helm compatibility

As of now, there is a limited Helm 2 Chart compatibility, simple Charts will render just fine.

To mimic Helm behaviour regarding to missing keys use --unsafe-ignore-missing-keys option.

There is no plan to implement full compatibility with Helm, because of unnecessary complexity that would bring.

If you need full Helm compatilble rendering see: helm-nomagic.

Limitations and future work

Planned new features

  • .renderignore files #12

Operating system support

We provide cross-compiled binaries for most platforms, but is currently used mainly with linux/amd64.

Community & Contribution

There is a dedicated channel #render on virtuslab-oss.slack.com (Invite form)

Feel free to file issues or pull requests.

Before any big pull request please consult the maintainers to ensure a common direction.

Development

git clone [email protected]:VirtusLab/render.git
cd render

make init
make all

The name

We believe in obvious names. It renders. It's a verb. It's render.

render's People

Contributors

antoniaklja avatar bartoszj avatar dependabot[bot] avatar jdziat avatar mathiasgr avatar pawelprazak avatar pdolega avatar placydo avatar skatsaounis avatar sokoow avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

render's Issues

How to Evaluate If condition in Template generation ??

How to Evaluate If condition in Template generation ??

{{- if .policy.Cond.Operator == "equals" }}
{{$policy.Cond.LeftOperand}} == {{$policy.Cond.RightOperand}}
{{- if .policy.Cond.Operator == "notequals" }}
{{$policy.Cond.LeftOperand}} != {{$policy.Cond.RightOperand}}
{{- if .policy.Cond.Operator == "exists" }}
{{$policy.Cond.LeftOperand}} == {{$policy.Cond.RightOperand}}
{{- end}}

It is providing me "=" in operand, I have tried it exist by following line which is working , but how to match this condition with something ?

{{- if .policy.Cond.Operator}}
writesomething

ERRO Unexpected error: error (ExecError)

Hi, I'm attempting to generate --var flags from a file before invoking render but am hitting a strange error.

I have a source kubernetes volume.yaml file with one template replacement {{ .main_volume }}:

---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: myVolume
spec:
  awsElasticBlockStore:
    fsType: ext4
    volumeID: {{ .main_volume }}
---

I'm sourcing the variable replacement from a file called vars.env

main_volume=vol-xxxxxxxxx
secondary_volume=vol-yyyyyyyy

I'm using awk to convert this file into --var flags for render:

cat vars.env | awk '{printf " --var \"%s=%s\"", $1, $3}'
 --var "main_volume=vol-xxxxxxxxx" --var "secondary_volume=vol-yyyyyyyy"

All together:

render --in volume.yaml $(cat vars.env | awk '{printf " --var \"%s=%s\"", $1, $3}')
INFO Version unknown-unknown
INFO Variables:
	"main_volume=vol-0534a398c42265a31"
	"secondary_volume=vol-333333534a398c42265a31"
INFO Rendering 'volume.yaml' -> 'stdout'
ERRO Unexpected error: error (ExecError) evaluating the template named 'volume.yaml': template: volume.yaml:16:17: executing "volume.yaml" at <.main_volume>: map has no entry for key "main_volume"; hint: go templates does not evaluate missing keys in dot notation, for more details see: https://github.com/VirtusLab/render/issues/11

Any help would be appreciated!

render --version
render version unknown-unknown

Not sure what's up with the version, I just did a fresh install on a go 1.13.1 machine with go get -u github.com/VirtusLab/render

Indentation spacing when using `toYaml`

Hey! Thank you so much for making this tool available.

Is there a way to specify the number of spaces used for indentation in the output of toYaml? I had been using version v0.1.3 for a while, which outputs 2 spaces per indentation level, but when I recently tried a newer version (version 0.1.4 and up) 4 spaces are used.

Thanks!

Errors you may encounter when upgrading the library

(The purpose of this report is to alert VirtusLab/render to the possible problems when VirtusLab/render try to upgrade the following dependencies)

An error will happen when upgrading library Masterminds/sprig:

github.com/Masterminds/sprig

-Latest Version: v3.1.0 (Latest commit 273d1b8 on 17 Apr)
-Where did you use it:
https://github.com/VirtusLab/render/search?q=Masterminds%2Fsprig&unscoped_q=Masterminds%2Fsprig
-Detail:

github.com/Masterminds/sprig/go.mod

module github.com/Masterminds/sprig/v3
go 1.13
require (
	github.com/Masterminds/goutils v1.1.0
	github.com/Masterminds/semver/v3 v3.1.0
	…
)

github.com/Masterminds/sprig/semver.go

package sprig
import (
	sv2 "github.com/Masterminds/semver/v3"
)

This problem was introduced since _ Masterminds/sprig v3.0.0(committed 0e09f04 on 3 Oct 2019)_ .Now you used version v2.22.0. If you try to upgrade Masterminds/sprig to version v3.0.0 and above, you will get an error--- no package exists at "github.com/Masterminds/semver/v3"

I investigated the libraries (Masterminds/sprig >= v3.0.0) release information and found the root cause of this issue is that----

  1. These dependencies all added Go modules in the recent versions.

  2. They all comply with the specification of "Releasing Modules for v2 or higher" available in the Modules documentation. Quoting the specification:

A package that has migrated to Go Modules must include the major version in the import path to reference any v2+ modules. For example, Repo github.com/my/module migrated to Modules on version v3.x.y. Then this repo should declare its module path with MAJOR version suffix "/v3" (e.g., module github.com/my/module/v3), and its downstream project should use "github.com/my/module/v3/mypkg" to import this repo’s package.

  1. This "github.com/my/module/v3/mypkg" is not the physical path. So Go versions older than 1.9.7 and 1.10.3 plus all third-party dependency management tools (like dep, glide, govendor, etc) don't have minimal module awareness as of now and therefore don't handle import paths correctly.

Note: creating a new branch is not required. If instead you have been previously releasing on master and would prefer to tag v3.0.0 on master, that is a viable option. (However, be aware that introducing an incompatible API change in master can cause issues for non-modules users who issue a go get -u given the go tool is not aware of semver prior to Go 1.11 or when module mode is not enabled in Go 1.11+).
Pre-existing dependency management solutions such as dep currently can have problems consuming a v2+ module created in this way. See for example dep#1962.
https://github.com/golang/go/wiki/Modules#releasing-modules-v2-or-higher

Solution

1. Migrate to Go Modules.

Go Modules is the general trend of ecosystem, if you want a better upgrade package experience, migrating to Go Modules is a good choice.

Migrate to modules will be accompanied by the introduction of virtual paths(It was discussed above).

This "github.com/my/module/v3/mypkg" is not the physical path. So Go versions older than 1.9.7 and 1.10.3 plus all third-party dependency management tools (like dep, glide, govendor, etc) don't have minimal module awareness as of now and therefore don't handle import paths correctly.

Then the downstream projects might be negatively affected in their building if they are module-unaware (Go versions older than 1.9.7 and 1.10.3; Or use third-party dependency management tools, such as: Dep, glide, govendor…).

2. Maintaining v2+ libraries that use Go Modules in Vendor directories.

If VirtusLab/render want to keep using the dependency manage tools (like dep, glide, govendor, etc), and still want to upgrade the dependencies, can choose this fix strategy.
Manually download the dependencies into the vendor directory and do compatibility dispose(materialize the virtual path or delete the virtual part of the path). Avoid fetching the dependencies by virtual import paths. This may add some maintenance overhead compared to using modules.

As the import paths have different meanings between the projects adopting module repos and the non-module repos, materialize the virtual path is a better way to solve the issue, while ensuring compatibility with downstream module users. A textbook example provided by repo github.com/moby/moby is here:
https://github.com/moby/moby/blob/master/VENDORING.md
https://github.com/moby/moby/blob/master/vendor.conf
In the vendor directory, github.com/moby/moby adds the /vN subdirectory in the corresponding dependencies.
This will help more downstream module users to work well with your package.

3. Request upstream to do compatibility processing.

The Masterminds/sprig have 29 module-unaware users in github, such as: LLParse/rivapi, gitlawr/alertmanager-webhook-adapter, ednaganon/linuxkittry…
https://github.com/search?q=Masterminds%2Fsprig+filename%3Avendor.conf+filename%3Avendor.json+filename%3Aglide.toml+filename%3AGodep.toml+filename%3AGodep.json

Summary

You can make a choice when you meet this DM issues by balancing your own development schedules/mode against the affects on the downstream projects.

For this issue, Solution 1 can maximize your benefits and with minimal impacts to your downstream projects the ecosystem.

References

Do you plan to upgrade the libraries in near future?
Hope this issue report can help you ^_^
Thank you very much for your attention.

Best regards,
Kate

Replace does not working inside range

It does not work

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  {{- range $i, $value := .Regions }}
  - {{ .AppName }}/{{ $value }}/argo-application.yaml
  {{- end }}
ERRO[0000] error (ExecError) evaluating the template named 'kustomization.yaml': template: kustomization.yaml:5:7: executing "kustomization.yaml" at <.AppName>: can't evaluate field AppName in type string

It is working fine

apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
  {{- range $i, $value := .Regions }}
  - /{{ $value }}/argo-application.yaml
  {{- end }}
{{ .AppName }}

is it possible to add a function via an external configuration file?

Hello all!

spring library only supports int64 multiplication and division operations.

  1. if I need operations with float I need to add a new function?
  2. this is only possible by making changes to the repository code?
  3. is it possible to add a function via an external configuration file?

can't install via go

I've tried to install render via go and it is giving me this error:

$ go get github.com/VirtusLab/render
# github.com/VirtusLab/render/renderer
../../../../go/src/github.com/VirtusLab/render/renderer/render.go:108:27: undefined: crypto.TemplateFunctions

Space after colon renders map structure

Consider this template:

{{- range $i, $value := .cdn.steps }}
{{ $value }}
{{- end }}

and this config:

cdn:
  steps:
    - sh "docker create -it --name ${repository_short}-${branch}-${env.BUILD_NUMBER}-source ${image_repository}/${image_name}:${branch}-${commit_id} sh"
    - sh "docker cp ${repository_short}-${branch}-${env.BUILD_NUMBER}-source:/usr/share/nginx/html/ source"
    - sh "docker rm ${repository_short}-${branch}-${env.BUILD_NUMBER}-source"
    - sh "gsutil -m cp -z 'html,css,js,map,svg,json' -r source/** gs://${cdn_bucket}/${repository_short}/"
    - sh "gsutil -m acl set -R public-read gs://${cdn_bucket}/"
    - sh "gsutil -m setmeta -h 'Cache-Control:public, max-age=3600' gs://${cdn_bucket}/${repository_short}/**"

Render will work fine

./render --in issue.template --config issue.config --out issue.final

cat issue.final

sh "docker create -it --name ${repository_short}-${branch}-${env.BUILD_NUMBER}-source ${image_repository}/${image_name}:${branch}-${commit_id} sh"
sh "docker cp ${repository_short}-${branch}-${env.BUILD_NUMBER}-source:/usr/share/nginx/html/ source"
sh "docker rm ${repository_short}-${branch}-${env.BUILD_NUMBER}-source"
sh "gsutil -m cp -z 'html,css,js,map,svg,json' -r source/** gs://${cdn_bucket}/${repository_short}/"
sh "gsutil -m acl set -R public-read gs://${cdn_bucket}/"
sh "gsutil -m setmeta -h 'Cache-Control:public, max-age=3600' gs://${cdn_bucket}/${repository_short}/**"

BUT if we make space after colon in one of steps like

Cache-Control: public

so in the end config looks like this

cdn:
  steps:
    - sh "docker create -it --name ${repository_short}-${branch}-${env.BUILD_NUMBER}-source ${image_repository}/${image_name}:${branch}-${commit_id} sh"
    - sh "docker cp ${repository_short}-${branch}-${env.BUILD_NUMBER}-source:/usr/share/nginx/html/ source"
    - sh "docker rm ${repository_short}-${branch}-${env.BUILD_NUMBER}-source"
    - sh "gsutil -m cp -z 'html,css,js,map,svg,json' -r source/** gs://${cdn_bucket}/${repository_short}/"
    - sh "gsutil -m acl set -R public-read gs://${cdn_bucket}/"
    - sh "gsutil -m setmeta -h 'Cache-Control: public, max-age=3600' gs://${cdn_bucket}/${repository_short}/**"

end result is rendered with map[]:

cat issue.final

sh "docker create -it --name ${repository_short}-${branch}-${env.BUILD_NUMBER}-source ${image_repository}/${image_name}:${branch}-${commit_id} sh"
sh "docker cp ${repository_short}-${branch}-${env.BUILD_NUMBER}-source:/usr/share/nginx/html/ source"
sh "docker rm ${repository_short}-${branch}-${env.BUILD_NUMBER}-source"
sh "gsutil -m cp -z 'html,css,js,map,svg,json' -r source/** gs://${cdn_bucket}/${repository_short}/"
sh "gsutil -m acl set -R public-read gs://${cdn_bucket}/"
map[sh "gsutil -m setmeta -h 'Cache-Control:public, max-age=3600' gs://${cdn_bucket}/${repository_short}/**"]

Not sure if it's user error, syntax problem or go template engine problem?

template dot notation fails on missing map key in confusing way

templates/resourcequota.yaml:

apiVersion: v1
kind: ResourceQuota
metadata:
  name: default
spec:
  hard:
    {{- if .resourceQuota.hard.cpu }}
    cpu: {{ .resourceQuota.hard.cpu }}
    {{- else }}
    cpu: "1"
    {{- end}}

ERROR: error (ExecError) evaluating the template named 'templates/resourcequota.yaml': template: templates/resourcequota.yaml:8:25: executing "templates/resourcequota.yaml" at <.resourceQuota.hard....>: map has no entry for key "resourceQuota"

TODO:

  • add --unsafe-ignore-missing-keys as a workaround
  • add a dict/map function that will work with default map key option

Unhelpful empty --config message

when there is an empty --config, the error message is quite confusing, esp. when the problem is accidentally doubled param, eg
render ... --config --config something.yaml ...

can't set a --var value that contains an "="

The most simple test is:

echo "test: {{ .dave }}" | ./render --set 'dave=bob=w'

That results in the output:

INFO Version v0.2.0-273f9ec-dirty
INFO Variables:
        dave=bob=
INFO Rendering 'stdin' -> 'stdout'
ERRO Unexpected error: error (ExecError) evaluating the template named 'stdin': template: stdin:1:9: executing "stdin" at <.dave>: map has no entry for key "dave"; hint: go templates does not evaluate missing keys in dot notation, for more details see: https://github.com/VirtusLab/render/issues/11

carriage returns and empty lines are removed from the end of files

Hi! Thanks for your guys work on this. I was super-happy to find it. One thing I did notice is that trailing carriage returns and blank lines in a file are removed in the output template. This creates issues with some applications that require them.

Thanks!
Dan

go 1.11 unexpected module path "github.com/sirupsen/logrus"

It seems that in your repo you are referring to github.com/Sirupsen/logrus but go 1.11 and its modules are case sensitive and the actual path is github.com/sirupsen/logrus notice the lowercase s on sirupsen

This is currently meaning I can't include your module when using go 1.11

CVE-2020-29652 in golang.org/x/crypto

Building a Docker image with the latest version of render 0.2.0 installed. Scanning with Trivy provides the following:

usr/bin/render (gobinary)
=========================
Total: 5 (UNKNOWN: 2, LOW: 0, MEDIUM: 1, HIGH: 2, CRITICAL: 0)

+-----------------------------+------------------+----------+------------------------------------+------------------------------------+---------------------------------------+
|           LIBRARY           | VULNERABILITY ID | SEVERITY |         INSTALLED VERSION          |           FIXED VERSION            |                 TITLE                 |
+-----------------------------+------------------+----------+------------------------------------+------------------------------------+---------------------------------------+
| github.com/dgrijalva/jwt-go | CVE-2020-26160   | HIGH     | v3.2.0+incompatible                |                                    | jwt-go: access restriction            |
|                             |                  |          |                                    |                                    | bypass vulnerability                  |
|                             |                  |          |                                    |                                    | -->avd.aquasec.com/nvd/cve-2020-26160 |
+-----------------------------+------------------+          +------------------------------------+------------------------------------+---------------------------------------+
| golang.org/x/crypto         | CVE-2020-29652   |          | v0.0.0-20200622213623-75b288015ac9 | v0.0.0-20201216223049-8b5274cf687f | golang: crypto/ssh: crafted           |
|                             |                  |          |                                    |                                    | authentication request can            |
|                             |                  |          |                                    |                                    | lead to nil pointer dereference       |
|                             |                  |          |                                    |                                    | -->avd.aquasec.com/nvd/cve-2020-29652 |
+-----------------------------+------------------+----------+------------------------------------+------------------------------------+---------------------------------------+
| gopkg.in/yaml.v2            | CVE-2019-11254   | MEDIUM   | v2.2.2                             | v2.2.8                             | kubernetes: Denial of                 |
|                             |                  |          |                                    |                                    | service in API server via             |
|                             |                  |          |                                    |                                    | crafted YAML payloads by...           |
|                             |                  |          |                                    |                                    | -->avd.aquasec.com/nvd/cve-2019-11254 |
+                             +------------------+----------+                                    +------------------------------------+---------------------------------------+
|                             | GMS-2019-2       | UNKNOWN  |                                    | v2.2.3                             | XML Entity Expansion                  |
+                             +------------------+          +                                    +                                    +---------------------------------------+
|                             | GO-2021-0061     |          |                                    |                                    |                                       |
+-----------------------------+------------------+----------+------------------------------------+------------------------------------+---------------------------------------+

Using --set/--var value with spaces causes error

test.tmpl

{{ .my_var }}

render --in test.tmpl --out test.out --set "my_var=something with spaces"

Expected output:
cat test.out > something with spaces

Actual output:

ERRO Expected a valid extra parameter: 'my_var=something with spaces'
ERROR: can't parse extra configuration variables: invalid parameter: 'my_var=something with spaces'

I know the regex match ^(?P<name>\S+)=(?P<value>\S*)$ is looking for non-whitespace. maybe we allow quotes around the value? Sorry, I'm not super knowledgable about golang to know what's appropriate.
Current workaround is to use a config file instead

Allow passing context to 'render' function

I have a shared template that I'd like to 'render' with different values, that way that template can be reusable:

values.yaml:

envVars:
  x: 123
  y: 456
other: 789

map-to-json.template:

{{- range $key, $value := . -}}
{{ $key | toJson }}: {{ $value | toJson }},
{{- end -}}

render output:

// current:
{{ readFile "map-to-json.template" | render }}
// "envVars": { "x": 123, "y": 456 },
// "other": "789",

// with optional context:
{{ readFile "map-to-json.template" | render .envVars }}
// "x": 123,
// "y": 456,

Add `cidrHostEnd` custom function

Perhaps I'm just bad at using things (very plausible), but one of my use cases for render has me needing the last addressable address in a subnet.
To make this more functional, I figured I could make the function behave similar to cidrHost except the first argument would start from the end of the addressable range and work backwards.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.