tf

module
v0.0.0-...-7e4aa60 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 2, 2015 License: Apache-2.0

README

tf - Template File

Template Dockerfile or configuration using GO text template (http://golang.org/pkg/text/template/) in Bash with input from YAML, JSON, TOML, Etcd, REST or MySQL.

Usage

Usage:
  tf [OPTIONS]

Application Options:
  -v, --verbose         Verbose
      --version         Version
  -c, --config=         YAML, TOML or JSON config file
  -i, --input=          Input, defaults to using YAML
  -F, --input-format=   Data serialization format YAML, TOML or JSON (YAML)
  -f, --input-file=     Input file, data serialization format used is based on the file extension
  -t, --template=       Template file
  -l, --template-lang   Template language text or pongo2 (pongo2)
  -o, --output=         Output file (STDOUT)
  -p, --permission=     File permissions in octal (644)
  -O, --owner=          File Owner
      --etcd-host=      Etcd Host
      --etcd-port=      Etcd Port (2379)
      --etcd-dir=       Etcd Dir (/)
      --http-url=       HTTP Url
      --http-header=    HTTP Header (Accept: application/json)
      --http-format=    HTTP Format (JSON)
      --mysql-user=     MySQL user
      --mysql-password= MySQL password
      --mysql-host=     MySQL host
      --mysql-port=     MySQL port (3306)
      --mysql-database= MySQL database
      --mysql-query=    MySQL query

Help Options:
  -h, --help            Show this help message

Input will have it's own namespace such as Arg, File, Env, Etcd. you can also get this by:

echo '{{ keys . }}' | tf -l text

Argument input will also be in the root scope for convenience.

Configuration file

Configuration file is also a template i.e. you can use .Env and .Arg for customizing inputs.

Defaults

Key Description Default
etcd_host Default Etcd node.
etcd_port Default Etcd port. 2379
http_header HTTP accept header. application/json
http_format Format used by the http response JSON, YAML or TOML. JSON
mysql_user Default MySQL user.
mysql_password Default MySQL password.
mysql_host Default MySQL host.
mysql_port Default MySQL port 3306
mysql_database MySQL database.

Example:

[defaults]
mysql_user = "test"
mysql_pass = "test"
mysql_host = "mysql.example.com"
mysql_port = 3306
mysql_database = "test"

Inputs

Generic
Key Description Default
name Name of input in data namespace. Name given in [inputs.].
type Type of input file, etcd, http, mysql.
Specific
Type Key Description Default
file path Path to input file, format will be determined by file extension .yaml, .json or .toml.
etcd etcd_host Etcd node to connect to.
etcd etcd_port Etcd port to connect to. 2379
etcd etcd_dir Etcd directory to query, this will be queried recursively.
http http_url HTTP url to request.
http http_header HTTP accept headers to use for request. Optional will default to JSON.
http http_format Format used by the http response JSON, YAML or TOML.
mysql mysql_user MySQL user for connection.
mysql mysql_password MySQL password for connection.
mysql mysql_host MySQL host to connect to.
mysql mysql_port MySQL post to connect to.
mysql mysql_database MySQL database to connect to.
mysql mysql_query MySQL SQL query.

Example with Etcd

IP=localhost

If you're using Boot2Docker or docker-machine:

IP=$(echo ${DOCKER_HOST##tcp://} | awk -F: '{ print $1}')
docker run -d --name etcd -p 4001:4001 coreos/etcd:v0.4.6
curl -L http://${IP}:4001/v2/keys/hosts/host1.example.com/serialno -XPUT -d value="abc123"
curl -L http://${IP}:4001/v2/keys/hosts/host2.example.com/serialno -XPUT -d value="def456"
curl -L http://${IP}:4001/v2/keys/hosts/host3.example.com/serialno -XPUT -d value="fgh789"
printf '{{ range $k, $e := .Etcd }}| {{ $k | lalign 20 }} | {{ $e.serialno | lalign 10 }} |\n{{end}}' | \
tf --etcd-host ${IP} --etcd-port 4001 --etcd-dir /hosts
tf --config examples/etcd/tf.toml --template examples/etcd/hosts.tf --input "{ EtcdHost: ${IP} }"

You can find a more complete example in "examples/docker" for templating Dockerfile and configuration files, this was primary use-case for this project. However it's pretty generic and could be used for any templating in Bash.

Extended functions and tests

Tests

Test Arguments Types Description
last $index $array int, []interface{} Determine if $index is the last element in the $array
ismap $variable $interface{} Test if $variable type is a map (nested data structure)
contains $string $sub-string string, string Test if $string contains $sub-string
even $x int Test if $x is even
odd $x int Test if $x is odd
Examples
echo '{{range $i, $e := .Apples}}Apple: {{$e}}{{if last $i $.Apples | not}}{{printf ",\n"}}{{end}}{{end}}' | tf -l text -i '{ Apples: [ 1, 2, 3] }'
echo '{{range $k, $e := .Oranges}}{{if map $e | not }}{{printf "%s: %v\n" $k $e}}{{end}}{{end}}' | tf -l text -i '{ Oranges: { a: 1, b: 2, c: { a: 1, b: 2 } } }'
echo '{{1 | even }} | tf -l text

Functions

Function Arguments Types Description
join $separator $array string, []interface{} Join elements in an array to a string
split $separator $string string, string Split string into an array
repeat $count $string int, string Repeat string x number of times
keys $variable interface{} Get keys from interface{}
type $variable interface{} Get data type (usefull for debugging templates)
lower $string string Convert string to lower case
upper $string string Convert string to upper case
replace $old $new $string string, string, string Replace old with new in string
trim $trim $string string, string Trim preceding and trailing characters
ltrim $trim $string string, string Trim preceding characters
rtrim $trim $string string, string Trim trailing characters
default $default $optional interface{}, ...interface{} If no value is passed for the second arg. it returns the default
center $size $string int, string Center text
ralign $size $string int, string Right align text
lalign $size $string int, string Left align text
capitalize $string string Capitalize first character in string
add $y $x int, int Addition, arguments are in reverse order to allow pipeline
sub $y $x int, int Subtraction, arguments are in reverse order to allow pipeline
div $y $x int, int Division, arguments are in reverse order to allow pipeline
mul $y $x int, int Multiplication, arguments are in reverse order to allow pipeline
date $fmt ...interface{} Print date/time, optional argument strftime syntax
Examples
echo '{{split ":" .Env.PATH | join ",\n"}}' | tf -l text
echo '{{repeat 20 "-"}} HELLO WORLD! {{"-" | repeat 20}}' | tf -l text
echo '{{keys .Env | join "\n"}}' | tf -l text
echo '{{ "UPPER" | lower}} {{ "lower" | upper }}' | tf -l text
echo '{{ "Doo Doo" | replace "Doo" "Doo is extinct" }}' | tf -l text
echo '{{ "!!! TRIM !!!" | trim "! " }}' | tf -l text
echo '{{ 2 | add 2 | sub 2 | mul 5 | div 5}}' | tf -l text

Build

git clone https://github.com/mickep76/tf.git
cd tf
./build
bin/tf --version

Install using Homebrew

brew tap mickep76/funk-gnarge
brew install mickep76/funk-gnarge/tf

Template a directory structure

Template

input='input.yaml'
for file in $(find . -type f -name '*.tf'); do
    tf -i ${input} -t ${file} -o ${file%%.tf}
done

Cleanup

for file in $(find . -type f -name '*.tf'); do
    rm -f ${file%%.tf}
done

Use in Makefile

INPUT=input.yaml

all: build

clean:
        for file in $$(find . -type f -name '*.tf'); do \
                rm -f $${file%%.tf} ; \
        done

build: clean
        for file in $$(find . -type f -name '*.tf'); do \
                tf -f ${INPUT} -t $${file} -o $${file%%.tf} ; \
        done

Issues

Currently Go text/template doesn't have a way to suppress newlines.

Roadmap

  • Add test's
  • LDAP support
  • Add sort array asc. and desc. templ. func.
  • Examples with Etcd data
  • Examples with MySQL data
  • Validation of data input using schema
  • Config that is evaluated in sorted file order for consequtive queries using prev. values "/etc/tf.d/01-http", "/etc/tf.d/02-http" etc.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL