{"id":18513358,"url":"https://github.com/jbox-web/stacker","last_synced_at":"2025-04-09T06:33:12.519Z","repository":{"id":48138993,"uuid":"261447881","full_name":"jbox-web/stacker","owner":"jbox-web","description":"Stacker - A lightweight file-based CMDB","archived":false,"fork":false,"pushed_at":"2023-12-10T00:06:49.000Z","size":517,"stargazers_count":10,"open_issues_count":0,"forks_count":0,"subscribers_count":3,"default_branch":"master","last_synced_at":"2024-03-26T11:24:06.979Z","etag":null,"topics":["cmdb","crystal","crystal-lang","salt","saltstack"],"latest_commit_sha":null,"homepage":"","language":"Crystal","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jbox-web.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null}},"created_at":"2020-05-05T11:41:17.000Z","updated_at":"2023-12-19T16:45:30.000Z","dependencies_parsed_at":"2023-12-10T00:35:14.983Z","dependency_job_id":null,"html_url":"https://github.com/jbox-web/stacker","commit_stats":null,"previous_names":[],"tags_count":3,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fstacker","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fstacker/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fstacker/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jbox-web%2Fstacker/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jbox-web","download_url":"https://codeload.github.com/jbox-web/stacker/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223367315,"owners_count":17134075,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cmdb","crystal","crystal-lang","salt","saltstack"],"created_at":"2024-11-06T15:37:50.067Z","updated_at":"2024-11-06T15:37:50.811Z","avatar_url":"https://github.com/jbox-web.png","language":"Crystal","readme":"# Stacker - A lightweight file-based CMDB\n\n[![GitHub license](https://img.shields.io/github/license/jbox-web/stacker.svg)](https://github.com/jbox-web/stacker/blob/master/LICENSE)\n[![Build Status](https://github.com/jbox-web/stacker/actions/workflows/ci.yml/badge.svg)](https://github.com/jbox-web/stacker/actions/workflows/ci.yml)\n[![Build Status](https://img.shields.io/docker/v/nicoladmin/stacker/latest?color=green\u0026label=Docker%20Image\u0026logo=docker)](https://hub.docker.com/r/nicoladmin/stacker)\n\nStacker is [Salt PillarStack](https://docs.saltstack.com/en/master/ref/pillar/all/salt.pillar.stack.html) in [Crystal](https://crystal-lang.org/).\n\nIt is implemented using [crinja](https://github.com/straight-shoota/crinja) which is Jinja2 in Crystal :)\n\n[Documentation](https://jbox-web.github.io/stacker/index.html)\n\n## Installation\n\n### Manual installation\n\nGrab the latest binary from the [releases](https://github.com/jbox-web/stacker/releases) page and run it with the [sample configuration project](https://github.com/jbox-web/stacker/tree/master/example).\n\nIf you use [asdf](https://github.com/asdf-vm/asdf) you can also install Stacker with [asdf-stacker](https://github.com/jbox-web/asdf-stacker).\n\n### Docker\n\n```sh\ndocker pull nicoladmin/stacker:latest\n```\n\n**Note :** The Docker mode comes with a [wrapper script](https://github.com/jbox-web/stacker/blob/master/stacker.sh) to ease interactions with the container\n\n```sh\ncurl -sSL -o stacker.sh https://raw.githubusercontent.com/jbox-web/stacker/master/stacker.sh\nchmod +x stacker.sh\n```\n\nUsage : `stacker.sh {start|stop|restart|status|kill|clean|fetch|info|logs}`\n\n\n## The 10 seconds test in Web mode\n\nFirst we need to start Stacker with sample data :\n\n### Manual installation\n\n```sh\nstacker server --config example/stacker.yml\n```\n\n### Docker\n\n```sh\n./stacker.sh start\n```\n\nThen fetch pillars with Curl :\n\n```sh\ncurl --no-progress-meter -X POST -H \"Content-Type: application/json\" -d @example/grains/server1.curl.json http://127.0.0.1:3000/server1.example.net | jq\n```\n\nYou can also navigate to http://127.0.0.1:3000/server1.example.net to see the generated pillars.\n\n## The 10 seconds test in CLI mode\n\nIn this mode you don't need the webserver to be running :\n\n### Manual installation\n\n```sh\nstacker fetch server1.example.net --config example/stacker.yml --grains example/grains/server1.json --pillar example/ext_pillar/server1.json | jq\n```\n\n### Docker\n\n```sh\n./stacker.sh fetch server1.example.net --grains grains/server1.json --pillar ext_pillar/server1.json | jq\n```\n\n## Usage\n\n```sh\nUsage:\n  stacker [flags...] [arg...]\n\nStacker is Salt PillarStack in Crystal\n\nFlags:\n  --help     # Displays help for the current command.\n  --version  # Displays the version of the current application.\n\nSubcommands:\n  fetch      # Fetch host pillars\n  info       # Show Stacker information\n  server     # Run Stacker webserver\n```\n\n## Configuration\n\nBy default Stacker looks for it's configuration file in the current directory (`stacker.yml`).\n\nYou can pass an alternative file by using `--config` flag.\n\nThe configuration file is a YAML file looking like this :\n\n```yml\n---\ndoc_root: example/doc_root\nentrypoint: server-pillars\nlog_file: ./log/stacker.log\n\nstacks:\n  default:\n    - example/doc_root/server-pillars/stack1.cfg\n  dev:\n    - example/doc_root/server-pillars/stack1.cfg\n    - example/doc_root/pillars/stack1.cfg\n  prod:\n    - example/doc_root/server-pillars/stack1.cfg\n    - example/doc_root/pillars/stack1.cfg\n    - example/doc_root/server-pillars/stack2.cfg\n\nserver_host: 127.0.0.1\nserver_port: 3000\nserver_environment: development\n```\n\n**Note :** You can use relative or absolute file path.\n\nConfig               | Description\n---------------------|------------\n`doc_root`           | the webserver document root (must be specified). Since pillar are also crinja templates, it means where are the template files?\n`entrypoint`         | the webserver entrypoint (must be specified). The directory in the `doc_root` where we shoud look for `\u003cminion_d\u003e.yml` file\n`log_file`           | the path to the log file\n`stacks`             | a hash of namespaced [stack configuration files](https://docs.saltstack.com/en/master/ref/pillar/all/salt.pillar.stack.html#list-of-config-files) (must be specified)\n`server_host`        | ip address to bind to (default `127.0.0.1`)\n`server_port`        | port to bind to (default `3000`)\n`server_environment` | `development` or `production` (default `production`)\n\n## Salt integration\n\nTo integrate Stacker with Salt you first need to add the [stacker pillar module](/salt/stacker.py) in Salt :\n\n1. Declare extension modules directory in Salt (`/etc/salt/master.conf` or `/etc/salt/master.d/f_defaults.conf`)\n\n```yml\nextension_modules: /data/salt/modules\n```\n\n2. Create `/data/salt/modules/pillar` directory and puts [stacker module](https://github.com/jbox-web/stacker/blob/master/salt/stacker.py) in it\n\n```sh\nmkdir -p /data/salt/modules/pillar\nwget -O /data/salt/modules/pillar/stacker.py https://raw.githubusercontent.com/jbox-web/stacker/master/salt/stacker.py\n```\n\n3. Declare the new ext_pillar module in Salt\n\n```yml\next_pillar:\n  - stacker: http://127.0.0.1:3000\n```\n\nYou can also pass parameters to Stacker module :\n\n```yml\next_pillar:\n  - stacker:\n      host: http://127.0.0.1:3000\n      namespace: 'production'\n      log_level: 'debug'\n```\n\n4. Restart Salt, you're done :)\n\n## Namespaces\n\nUse namespaces by using optional `n=` query parameter :\n\n```sh\ncurl http://127.0.0.1:3000/server1.example.net?n=dev\ncurl http://127.0.0.1:3000/server1.example.net?n=prod\n```\n\nOr with `--namespace` flag when using Stacker CLI.\n\nThe default namespace when query parameter or CLI flag is omited is `default`.\n\n## Output format\n\nSet output format by using optional `f=` query parameter :\n\n```sh\ncurl http://127.0.0.1:3000/server1.example.net?f=json\ncurl http://127.0.0.1:3000/server1.example.net?f=yaml\n```\n\nOr with `--output-format` flag when using Stacker CLI.\n\nThe default output format when query parameter or CLI flag is omited is `json`.\n\nOnly `json` and `yaml` are supported.\n\n## Logs\n\n* log level\n\nThe log level is dynamic. No need to restart the web server :)\n\nSet log level by using optional `l=` query parameter :\n\n```sh\ncurl http://127.0.0.1:3000/server1.example.net?l=debug\ncurl http://127.0.0.1:3000/server1.example.net?l=trace\n```\n\nOr with `--log-level` flag when using Stacker CLI.\n\nThe default log level when query parameter or CLI flag is omited is `info`.\n\nLog levels other than `debug` or `trace` are meaningless.\n\n`trace` level is very verbose as it dumps data before and after merge operations. In this case you might need some filtering, see below...\n\n\u003cdetails\u003e\u003csummary\u003edebug level will render something like this :\u003c/summary\u003e\n\n```sh\n2020-10-02T23:18:27.149678Z   INFO - processor: Building stack for: server2.example.net (namespace: prod)\n2020-10-02T23:18:27.149897Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/stack1.cfg\n2020-10-02T23:18:27.149927Z  DEBUG - processor: Loading: example/doc_root/server-pillars/01-base.yml\n2020-10-02T23:18:27.149936Z  DEBUG - processor: Compiling: example/doc_root/server-pillars/01-base.yml\n2020-10-02T23:18:27.150030Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/01-base.yml\n2020-10-02T23:18:27.150078Z  DEBUG - processor: Merging: example/doc_root/server-pillars/01-base.yml\n2020-10-02T23:18:27.150099Z  DEBUG - processor: Loading: example/doc_root/server-pillars/server2.example.net.yml\n2020-10-02T23:18:27.150109Z  DEBUG - processor: Compiling: example/doc_root/server-pillars/server2.example.net.yml\n2020-10-02T23:18:27.150190Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/server2.example.net.yml\n2020-10-02T23:18:27.150263Z  DEBUG - processor: Merging: example/doc_root/server-pillars/server2.example.net.yml\n2020-10-02T23:18:27.150705Z  DEBUG - renderer: Compiled: example/doc_root/pillars/stack1.cfg\n2020-10-02T23:18:27.150775Z  DEBUG - processor: Loading: example/doc_root/pillars/01-base/01-base.yml\n2020-10-02T23:18:27.150784Z  DEBUG - processor: Compiling: example/doc_root/pillars/01-base/01-base.yml\n2020-10-02T23:18:27.150873Z  DEBUG - renderer: Compiled: example/doc_root/pillars/01-base/01-base.yml\n2020-10-02T23:18:27.150932Z  DEBUG - processor: Merging: example/doc_root/pillars/01-base/01-base.yml\n2020-10-02T23:18:27.150942Z  DEBUG - processor: Loading: example/doc_root/pillars/01-base/app1.yml\n2020-10-02T23:18:27.150949Z  DEBUG - processor: Compiling: example/doc_root/pillars/01-base/app1.yml\n2020-10-02T23:18:27.151042Z  DEBUG - renderer: Compiled: example/doc_root/pillars/01-base/app1.yml\n2020-10-02T23:18:27.151091Z  DEBUG - processor: Merging: example/doc_root/pillars/01-base/app1.yml\n2020-10-02T23:18:27.151108Z  DEBUG - processor: Loading: example/doc_root/pillars/01-base/zdump.yml\n2020-10-02T23:18:27.151115Z  DEBUG - processor: Compiling: example/doc_root/pillars/01-base/zdump.yml\n2020-10-02T23:18:27.151208Z  DEBUG - renderer: Compiled: example/doc_root/pillars/01-base/zdump.yml\n2020-10-02T23:18:27.151238Z  DEBUG - processor: Merging: example/doc_root/pillars/01-base/zdump.yml\n2020-10-02T23:18:27.151267Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/common/locale.yml\n2020-10-02T23:18:27.151286Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/common/locale.yml\n2020-10-02T23:18:27.151392Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/common/locale.yml\n2020-10-02T23:18:27.151426Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/common/locale.yml\n2020-10-02T23:18:27.151452Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/common/timezone.yml\n2020-10-02T23:18:27.151462Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/common/timezone.yml\n2020-10-02T23:18:27.151572Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/common/timezone.yml\n2020-10-02T23:18:27.151597Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/common/timezone.yml\n2020-10-02T23:18:27.151619Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/common/users.yml\n2020-10-02T23:18:27.151627Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/common/users.yml\n2020-10-02T23:18:27.151795Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/common/users.yml\n2020-10-02T23:18:27.151858Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/common/users.yml\n2020-10-02T23:18:27.151879Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/client/salt.yml\n2020-10-02T23:18:27.151887Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/client/salt.yml\n2020-10-02T23:18:27.152009Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/client/salt.yml\n2020-10-02T23:18:27.152039Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/client/salt.yml\n2020-10-02T23:18:27.152060Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/server/openssh.yml\n2020-10-02T23:18:27.152069Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/server/openssh.yml\n2020-10-02T23:18:27.152231Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/server/openssh.yml\n2020-10-02T23:18:27.152331Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/server/openssh.yml\n2020-10-02T23:18:27.152351Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/server/docker.yml\n2020-10-02T23:18:27.152360Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/server/docker.yml\n2020-10-02T23:18:27.152478Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/server/docker.yml\n2020-10-02T23:18:27.152528Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/server/docker.yml\n2020-10-02T23:18:27.152547Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/server/nodejs.yml\n2020-10-02T23:18:27.152554Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/server/nodejs.yml\n2020-10-02T23:18:27.152688Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/server/nodejs.yml\n2020-10-02T23:18:27.152729Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/server/nodejs.yml\n2020-10-02T23:18:27.152748Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/server/php.yml\n2020-10-02T23:18:27.152756Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/server/php.yml\n2020-10-02T23:18:27.152931Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/server/php.yml\n2020-10-02T23:18:27.153030Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/server/php.yml\n2020-10-02T23:18:27.153050Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/server/redis.yml\n2020-10-02T23:18:27.153059Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/server/redis.yml\n2020-10-02T23:18:27.153534Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/server/redis.yml\n2020-10-02T23:18:27.153604Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/server/redis.yml\n2020-10-02T23:18:27.153631Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/custom/php-app-server-common.yml\n2020-10-02T23:18:27.153639Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/custom/php-app-server-common.yml\n2020-10-02T23:18:27.153759Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/custom/php-app-server-common.yml\n2020-10-02T23:18:27.153835Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/custom/php-app-server-common.yml\n2020-10-02T23:18:27.153856Z  DEBUG - processor: Loading: example/doc_root/pillars/02-roles/custom/php-app-server-development.yml\n2020-10-02T23:18:27.153864Z  DEBUG - processor: Compiling: example/doc_root/pillars/02-roles/custom/php-app-server-development.yml\n2020-10-02T23:18:27.154676Z  DEBUG - renderer: Compiled: example/doc_root/pillars/02-roles/custom/php-app-server-development.yml\n2020-10-02T23:18:27.154824Z  DEBUG - processor: Merging: example/doc_root/pillars/02-roles/custom/php-app-server-development.yml\n2020-10-02T23:18:27.154931Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/stack2.cfg\n2020-10-02T23:18:27.154970Z  DEBUG - processor: Loading: example/doc_root/server-pillars/server2.example.net/clean.yml\n2020-10-02T23:18:27.154978Z  DEBUG - processor: Compiling: example/doc_root/server-pillars/server2.example.net/clean.yml\n2020-10-02T23:18:27.155054Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/server2.example.net/clean.yml\n2020-10-02T23:18:27.155076Z  DEBUG - processor: Merging: example/doc_root/server-pillars/server2.example.net/clean.yml\n2020-10-02T23:18:27.155086Z  DEBUG - processor: Loading: example/doc_root/server-pillars/server2.example.net/stacker.yml\n2020-10-02T23:18:27.155090Z  DEBUG - processor: Compiling: example/doc_root/server-pillars/server2.example.net/stacker.yml\n2020-10-02T23:18:27.155162Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/server2.example.net/stacker.yml\n2020-10-02T23:18:27.155181Z  DEBUG - processor: Merging: example/doc_root/server-pillars/server2.example.net/stacker.yml\n2020-10-02T23:18:27.155191Z  DEBUG - processor: Loading: example/doc_root/server-pillars/server2.example.net/users.yml\n2020-10-02T23:18:27.155195Z  DEBUG - processor: Compiling: example/doc_root/server-pillars/server2.example.net/users.yml\n2020-10-02T23:18:27.155451Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/server2.example.net/users.yml\n2020-10-02T23:18:27.155475Z  DEBUG - processor: Merging: example/doc_root/server-pillars/server2.example.net/users.yml\n2020-10-02T23:18:27.155486Z  DEBUG - processor: Loading: example/doc_root/server-pillars/server2.example.net/zdump.yml\n2020-10-02T23:18:27.155490Z  DEBUG - processor: Compiling: example/doc_root/server-pillars/server2.example.net/zdump.yml\n2020-10-02T23:18:27.155896Z  DEBUG - renderer: Compiled: example/doc_root/server-pillars/server2.example.net/zdump.yml\n2020-10-02T23:18:27.156648Z  DEBUG - processor: Merging: example/doc_root/server-pillars/server2.example.net/zdump.yml\n2020-10-02T23:18:27.156664Z   INFO - processor: End of stack build for: server2.example.net (namespace: prod)\n```\n\u003c/details\u003e\n\n* filter logs by template path\n\nSet the file path to debug by using optional `p=` query parameter :\n\n```sh\ncurl http://127.0.0.1:3000/server1.example.net?l=trace\u0026p=doc_root/pillars/02-roles/server/openssh.yml\n```\n\nOr with `--path` flag when using Stacker CLI.\n\n* filter logs by steps\n\nSet the step to debug by using optional `s=` query parameter :\n\n```sh\ncurl http://127.0.0.1:3000/server1.example.net?l=trace\u0026p=doc_root/pillars/02-roles/server/openssh.yml\u0026s=compile,yaml-load\n```\n\nOr with `--step` flag when using Stacker CLI.\n\nValid options for the `step` param are : `compile` | `yaml-load` | `before-merge` | `after-merge` | `final`\n\n## Scaling\n\nThe Stacker's web design leads to great possibilities :\n\n* You can move Stacker and the pillar rendering process out of Salt server :\n\n```yml\next_pillar:\n  - stacker: http://stacker.example.corp:3000\n```\n\n* You can run multiple instances of Stacker and call them sequentially :\n\n```yml\next_pillar:\n  - stacker: http://127.0.0.1:3000?n=foo\n  - stacker: http://127.0.0.1:4000?n=bar\n  - stacker: http://127.0.0.1:5000?n=baz\n```\n\nWith each instance having it's own stack configuration :)\n\n## Deployment\n\nYou can use the [provided systemd unit](https://github.com/jbox-web/stacker/blob/master/extra/stacker.service) to manage the Stacker daemon.\n\n## Merging strategies\n\nStacker implements [merging strategies](https://docs.saltstack.com/en/master/ref/pillar/all/salt.pillar.stack.html#merging-strategies) like PillarStack so you can use them in Stacker too :)\n\nIt works the same way and it's [tested](/spec/stacker/value_spec.cr#L45).\n\n## Template syntax\n\nThe [template syntax](https://github.com/straight-shoota/crinja/blob/master/TEMPLATE_SYNTAX.md) is almost the same than Jinja2.\n\n[Like PillarStack](https://docs.saltstack.com/en/master/ref/pillar/all/salt.pillar.stack.html#overall-process) you have access to these variables :\n\n* `stack`\n* `pillar`\n* `minion_id`\n* `grains` (instead of `__grains__`)\n\nStacker adds a bunch of filters and functions :\n\nFilters :\n\n* json filter (dump json without character escaping) (like the [Salt one](https://docs.saltstack.com/en/latest/topics/jinja/index.html#tojson))\n* traverse filter (like the [Salt one](https://docs.saltstack.com/en/latest/topics/jinja/index.html#traverse))\n* unique filter (like the [Salt one](https://docs.saltstack.com/en/latest/topics/jinja/index.html#unique))\n\nFunctions :\n\n* log function (like the [Salt one](https://docs.saltstack.com/en/latest/topics/jinja/index.html#logs))\n* dump function (it dumps objects to YAML in log file)\n* array_push function\n* merge_dict function\n\nYou can see examples of code in the [documentation](https://jbox-web.github.io/stacker/Stacker/Runtime/Filter/Json.html).\n\nThe following filters/tests/functions/tags/operators are supported :\n\n```\nfilters:\n  abs()\n  append(string=)\n  attr(name=)\n  batch(linecount=2, fill_with=none)\n  capitalize()\n  center(width=80)\n  date(format=)\n  default(default_value='', boolean=false)\n  dictsort(case_sensitive=false, by='key')\n  escape()\n  filesizeformat(binary=false)\n  first()\n  float(default=0.0)\n  forceescape()\n  format()\n  groupby(attribute=)\n  indent(width=4, indentfirst=false)\n  int(default=0, base=10)\n  join(separator='', attribute=none)\n  json(indent=none)\n  last()\n  length()\n  list()\n  lower()\n  map()\n  pprint(verbose=false)\n  prepend(string=)\n  random()\n  reject()\n  rejectattr()\n  replace(old=, new=, count=none)\n  reverse()\n  round(precision=0, method='common', base=10)\n  safe()\n  select()\n  selectattr()\n  slice(slices=2, fill_with=none)\n  sort(reverse=false, case_sensitive=false, attribute=none)\n  string()\n  striptags()\n  sum(attribute=none, start=0)\n  title()\n  tojson(indent=none)\n  traverse(attribute=none, default=none)\n  trim()\n  truncate(length=255, killwords=false, end='...', leeway=none)\n  unique()\n  upper()\n  urlencode()\n  urlize(trim_url_limit=none, nofollow=false, target=none, rel=none)\n  wordcount()\n  wordwrap(width=79, break_long_words=true, wrapstring=none)\n  xmlattr(autoescape=true)\n\ntests:\n  callable()\n  defined()\n  divisibleby(num=)\n  equalto(other=)\n  escaped()\n  even()\n  greaterthan(other=0)\n  in(seq=[])\n  iterable()\n  lessthan(other=0)\n  lower()\n  mapping()\n  nil()\n  none()\n  number()\n  odd()\n  sameas(other=)\n  sequence()\n  string()\n  undefined()\n  upper()\n\nfunctions:\n  array_push(array=[], item=none)\n  cycler()\n  debug()\n  dict()\n  dump(object=none)\n  joiner(sep=', ')\n  log(object=none)\n  merge_dict(hash=none, other=none)\n  range(start=0, stop=0, step=1)\n  super()\n\ntags:\n  autoescape~endautoescape\n  block~endblock\n  call~endcall\n  do\n  elif\n  else\n  endautoescape\n  endblock\n  endcall\n  endfilter\n  endfor\n  endif\n  endmacro\n  endraw\n  endset\n  endwith\n  extends\n  filter~endfilter\n  for~endfor\n  from\n  if~endif\n  import\n  include\n  macro~endmacro\n  raw~endraw\n  set~endset\n  with~endwith\n\noperators:\n  operator[!=]\n  operator[%]\n  operator[*]\n  operator[**]\n  operator[+]\n  operator[-]\n  operator[/]\n  operator[//]\n  operator[\u003c]\n  operator[\u003c=]\n  operator[==]\n  operator[\u003e]\n  operator[\u003e=]\n  operator[and]\n  operator[not]\n  operator[or]\n  operator[~]\n```\n\n## Development\n\nTo compile Stacker you will need [Crystal](https://crystal-lang.org) compiler.\n\nYou can easily setup your development environment with [asdf](https://github.com/asdf-vm/asdf) :\n\n```sh\ngit clone https://github.com/jbox-web/stacker\nmake setup  # Install asdf Crystal plugin and install Crystal compiler\nmake deps   # Install Stacker dependencies\nmake build  # Build Stacker in development mode\nmake relase # Build Stacker in production mode\n```\n\n## Extend Stacker\n\nIf you need to add filters (or functions) just drop a new class with a few lines of Crystal code in [/src/runtime](https://github.com/jbox-web/stacker/tree/master/src/runtime) and recompile Stacker with `make build` (dev mode) or `make release` (release mode).\n\nYour custom filters (or functions) should be available in Jinja templates. To be sure run `stacker info` and check the Crinja environment info.\n\nThen feel free to submit a PR if you think it will be useful for people.\n\n## Roadmap\n\n* implement [Select Stacker config through grains|pillar|opts matching](https://github.com/saltstack/salt/blob/a670b4ae72ec11f5485c216c54059e14223019b8/salt/pillar/stack.py#L77)\n* add documentation about \"Stacker - Sample Project\"\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbox-web%2Fstacker","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjbox-web%2Fstacker","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjbox-web%2Fstacker/lists"}