Merge "Update Gemfile configuration"
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..4b4fece
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,10 @@
+language: python
+
+install:
+  - pip install cookiecutter
+
+script:
+  - MY_NEW_SALT_FORMULA_DIR="my_test_formula"
+  - mkdir $MY_NEW_SALT_FORMULA_DIR
+  - cookiecutter $PWD --output-dir $MY_NEW_SALT_FORMULA_DIR --no-input
+  - ls $MY_NEW_SALT_FORMULA_DIR/*/README.rst
diff --git a/README.rst b/README.rst
index 0b4377d..4942758 100644
--- a/README.rst
+++ b/README.rst
@@ -51,7 +51,20 @@
 
 .. code-block:: bash
 
-    MY_NEW_SALT_FORMULA_DIR="my_new_salt_formula"
+    MY_NEW_SALT_FORMULA_DIR="watchdog"
     mkdir $MY_NEW_SALT_FORMULA_DIR
     git clone https://github.com/salt-formulas/cookiecutter-salt-formula.git
     docker run --rm -it -u $(id -u):$(id -g) --env HOME=/$MY_NEW_SALT_FORMULA_DIR -v $PWD/$MY_NEW_SALT_FORMULA_DIR:/$MY_NEW_SALT_FORMULA_DIR -v $PWD/cookiecutter-salt-formula:/cookiecutter-salt-formula:ro cookiecutter/cookiecutter /cookiecutter-salt-formula --output-dir /$MY_NEW_SALT_FORMULA_DIR
+    service_name [some_service]: watchdog
+    role_name [server]:
+    initial_version [2018.1]:
+    copyright_year [2018]:
+    copyright_holder [Your Name et al.]: Mirantis, Inc.
+    author_name [John Doe]: Petr Ruzicka
+    author_contact [jdoe@domain.com]: pruzicka@mirantis.com
+    homepage [https://github.com/salt-formulas]:
+    debian_version [xenial]:
+    kitchen_driver [docker]:
+    kitchen_verifier [inspec]:
+    kitchen_formula [watchdog]:
+    kitchen_suites []: server
diff --git a/cookiecutter.json b/cookiecutter.json
index ac6cdce..3a6eb08 100644
--- a/cookiecutter.json
+++ b/cookiecutter.json
@@ -8,7 +8,7 @@
     "author_contact": "jdoe@domain.com",
     "homepage": "https://github.com/salt-formulas",
 
-    "debian_version": "trusty",
+    "debian_version": "xenial",
 
     "kitchen_driver": "docker",
     "kitchen_verifier": "inspec",
diff --git a/kitchen-init.sh b/kitchen-init.sh
index 809524e..e1ef27e 100755
--- a/kitchen-init.sh
+++ b/kitchen-init.sh
@@ -28,9 +28,9 @@
 ###################################
 test ! -e .kitchen.yml || {
   kitchen init -D kitchen-${driver} -P kitchen-salt --no-create-gemfile
-  echo .kitchen >> .gitignore
-  echo .bundle  >> .gitignore
-  echo .vendor  >> .gitignore
+  grep '.kitchen' .gitignore || echo .kitchen >> .gitignore
+  grep '.bundle' .gitignore || echo .bundle  >> .gitignore
+  grep '.vendor' .gitignore || echo .vendor  >> .gitignore
   rm -rf test
   rm -f .kitchen.yml
   rm -f chefignore
@@ -79,16 +79,22 @@
 test -e .travis.yml || \
   curl -skL  "${SOURCE_REPO_URI}/.travis.yml" -o .travis.yml
 
+# OTHER metadata if formula was not generated by up-to-date cookiecutter-salt-formula
+#####################################################################################
+
+test -e tests/pillar || \
+  mkdir -p tests/pillar
+
+test -e metadata.yml || \
+  curl -skL  "${SOURCE_REPO_URI}/metadata.yml" -o metadata.yml
+
+# Always update to letests
+curl -skL  "${SOURCE_REPO_URI}/Makefile" -o Makefile
+curl -skL  "${SOURCE_REPO_URI}/tests/run_tests.sh" -o tests/run_tests.sh && chmod u+x tests/run_tests.sh
 
 # ADD CHANGES
 #############
 
-echo "**************************************"
-echo "To update to latest test scripts, run:"
-echo "SOURCE_REPO_URI=${SOURCE_REPO_URI}"
-echo 'curl -skL  "${SOURCE_REPO_URI}/Makefile" -o Makefile'
-echo 'curl -skL  "${SOURCE_REPO_URI}/tests/run_tests.sh" -o tests/run_tests.sh'
-
 git add \
   .gitignore \
   .kitchen.yml \
diff --git "a/\173\173cookiecutter.service_name\175\175/.kitchen.docker.yml" "b/\173\173cookiecutter.service_name\175\175/.kitchen.docker.yml"
index 5d4ebed..703312e 100644
--- "a/\173\173cookiecutter.service_name\175\175/.kitchen.docker.yml"
+++ "b/\173\173cookiecutter.service_name\175\175/.kitchen.docker.yml"
@@ -33,7 +33,7 @@
 platforms:
   - name: <%=ENV['PLATFORM'] ||  'saltstack-ubuntu-xenial-salt-stable' %>
     driver_config:
-      image: <%=ENV['PLATFORM'] || 'epcim/salt-formulas:saltstack-ubuntu-xenial-salt-stable'%>
+      image: <%=ENV['PLATFORM'] || 'epcim/salt:saltstack-ubuntu-xenial-salt-stable'%>
       platform: ubuntu
 
 
diff --git "a/\173\173cookiecutter.service_name\175\175/.travis.yml" "b/\173\173cookiecutter.service_name\175\175/.travis.yml"
index 4243283..9f852ab 100644
--- "a/\173\173cookiecutter.service_name\175\175/.travis.yml"
+++ "b/\173\173cookiecutter.service_name\175\175/.travis.yml"
@@ -18,14 +18,17 @@
   - bundle install
 
 env:
-    - PLATFORM=epcim/salt-formulas:saltstack-ubuntu-xenial-salt-2017.7
-    - PLATFORM=epcim/salt-formulas:saltstack-ubuntu-xenial-salt-2016.3
-#    - PLATFORM=epcim/salt-formulas:saltstack-ubuntu-bionic-salt-2017.7
+    - PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2016.3
+    - PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-2017.7
+    - PLATFORM=epcim/salt:saltstack-ubuntu-xenial-salt-stable
+    - PLATFORM=epcim/salt:saltstack-ubuntu-bionic-salt-2017.7
+    - PLATFORM=epcim/salt:saltstack-ubuntu-bionic-salt-stable
+    - PLATFORM=epcim/salt:saltstack-centos-7-salt-2017.7
+    - PLATFORM=epcim/salt:saltstack-centos-7-salt-stable
 
 before_script:
   - set -o pipefail
   - make test | tail
-  - reno lint $PWD | tail
 
 script:
   - test ! -e .kitchen.yml || bundle exec kitchen converge ${SUITE} || true
diff --git "a/\173\173cookiecutter.service_name\175\175/Makefile" "b/\173\173cookiecutter.service_name\175\175/Makefile"
index d0e6fa4..f9b4f47 100644
--- "a/\173\173cookiecutter.service_name\175\175/Makefile"
+++ "b/\173\173cookiecutter.service_name\175\175/Makefile"
@@ -42,6 +42,7 @@
 	cp -a $(FORMULANAME) $(DESTDIR)/$(SALTENVDIR)/
 	[ ! -d _modules ] || cp -a _modules $(DESTDIR)/$(SALTENVDIR)/
 	[ ! -d _states ] || cp -a _states $(DESTDIR)/$(SALTENVDIR)/ || true
+	[ ! -d _engines ] || cp -a _engines $(DESTDIR)/$(SALTENVDIR)/ || true
 	[ ! -d _grains ] || cp -a _grains $(DESTDIR)/$(SALTENVDIR)/ || true
 	# Metadata
 	[ -d $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME) ] || mkdir -p $(DESTDIR)/$(RECLASSDIR)/service/$(FORMULANAME)
@@ -74,7 +75,7 @@
 	[ ! -f debian/changelog ] || dch -v $(VERSION_MAJOR).$(NEW_MINOR_VERSION) -m --force-distribution -D `dpkg-parsechangelog -S Distribution` "New version"
 	make genchangelog-$(VERSION_MAJOR).$(NEW_MINOR_VERSION)
 	(git add -u; git commit -m "Version $(VERSION_MAJOR).$(NEW_MINOR_VERSION)")
-	git tag -s -m $(VERSION_MAJOR) $(VERSION_MAJOR).$(NEW_MINOR_VERSION)
+	git tag -s -m $(VERSION_MAJOR).$(NEW_MINOR_VERSION) $(VERSION_MAJOR).$(NEW_MINOR_VERSION)
 
 check-changes:
 	@git log --pretty=oneline --decorate $(VERSION)..HEAD | grep -Eqc '.*' || (echo "No new changes since version $(VERSION)"; exit 1)
diff --git "a/\173\173cookiecutter.service_name\175\175/README.rst" "b/\173\173cookiecutter.service_name\175\175/README.rst"
index 5b32da7..d97513d 100644
--- "a/\173\173cookiecutter.service_name\175\175/README.rst"
+++ "b/\173\173cookiecutter.service_name\175\175/README.rst"
@@ -1,13 +1,13 @@
 
 ==================================
-{{cookiecutter.service_name}} Formula
+{{cookiecutter.service_name|capitalize}} Formula
 ==================================
 
 Service {{cookiecutter.service_name}} description
 
 
-Sample Pillars
-==============
+Sample Metadata
+===============
 
 Single {{cookiecutter.service_name}} service
 
@@ -18,10 +18,12 @@
         enabled: true
 
 
-More Information
-================
+References
+==========
 
-* A link to project home
+* A link to the documentation
+* A link to the home page
+* A link to the source code
 
 
 Documentation and Bugs
@@ -54,8 +56,3 @@
 channel:
 
     #salt-formulas @ irc.freenode.net
-
-Read more
-=========
-
-* links
diff --git "a/\173\173cookiecutter.service_name\175\175/debian/control" "b/\173\173cookiecutter.service_name\175\175/debian/control"
index edb1e07..33a1f1a 100644
--- "a/\173\173cookiecutter.service_name\175\175/debian/control"
+++ "b/\173\173cookiecutter.service_name\175\175/debian/control"
@@ -2,7 +2,7 @@
 Maintainer: {{cookiecutter.author_name}} <{{cookiecutter.author_contact}}>
 Section: admin
 Priority: optional
-Build-Depends: debhelper (>= 9), salt-master, python, python-yaml
+Build-Depends: debhelper (>= 9), python, python-yaml
 Standards-Version: 3.9.6
 Homepage: {{cookiecutter.homepage}}
 Vcs-Browser: https://github.com/salt-formulas/salt-formula-{{cookiecutter.service_name}}
diff --git "a/\173\173cookiecutter.service_name\175\175/tests/run_tests.sh" "b/\173\173cookiecutter.service_name\175\175/tests/run_tests.sh"
index 9993b8d..ad30dd9 100755
--- "a/\173\173cookiecutter.service_name\175\175/tests/run_tests.sh"
+++ "b/\173\173cookiecutter.service_name\175\175/tests/run_tests.sh"
@@ -2,7 +2,13 @@
 
 ###
 # Script requirments:
-#  apt-get install -y python-yaml virtualenv git
+#apt-get install -y python-yaml virtualenv git
+
+__ScriptVersion="2018.08.16"
+__ScriptName="run_tests.sh"
+__ScriptFullName="$0"
+__ScriptArgs="$*"
+
 set -e
 [ -n "$DEBUG" ] && set -x
 
@@ -27,6 +33,8 @@
 
 SALT_OPTS="${SALT_OPTS} --retcode-passthrough --local -c ${SALT_CONFIG_DIR} --log-file=/dev/null"
 
+IGNORE_MODELVALIDATE_MASK=${IGNORE_MODELVALIDATE_MASK:-"novalidate"}
+
 if [ "x${SALT_VERSION}" != "x" ]; then
     PIP_SALT_VERSION="==${SALT_VERSION}"
 fi
@@ -42,11 +50,12 @@
 
 setup_virtualenv() {
     log_info "Setting up Python virtualenv"
+    dependency_check virtualenv
     virtualenv $VENV_DIR
     source ${VENV_DIR}/bin/activate
-    pip install salt${PIP_SALT_VERSION}
-    if [[ -f ${CURDIR}/pip_requirements.txt ]]; then
-       pip install -r ${CURDIR}/pip_requirements.txt
+    python -m pip install salt${PIP_SALT_VERSION}
+    if [[ -f ${CURDIR}/test-requirements.txt ]]; then
+       python -m pip install -r ${CURDIR}/test-requirements.txt
     fi
 }
 
@@ -108,6 +117,7 @@
     dep_root="${DEPSDIR}/$(basename $dep_source .git)"
     dep_metadata="${dep_root}/metadata.yml"
 
+    dependency_check git
     [ -d $dep_root ] && { log_info "Dependency $dep_name already fetched"; return 0; }
 
     log_info "Fetching dependency $dep_name"
@@ -147,23 +157,28 @@
 
 salt_run() {
     [ -e ${VENV_DIR}/bin/activate ] && source ${VENV_DIR}/bin/activate
-    salt-call ${SALT_OPTS} $*
+    python $(which salt-call) ${SALT_OPTS} $*
 }
 
 prepare() {
-    [ -d ${BUILDDIR} ] && mkdir -p ${BUILDDIR}
+    if [[ -f ${BUILDDIR}/.prepare_done ]]; then
+      log_info "${BUILDDIR}/.prepare_done exist, not rebuilding BUILDDIR"
+      return
+    fi
+    [[ -d ${BUILDDIR} ]] && mkdir -p ${BUILDDIR}
 
     [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
     setup_mock_bin
     setup_pillar
     setup_salt
     install_dependencies
+    link_modules
+    touch ${BUILDDIR}/.prepare_done
 }
 
 lint_releasenotes() {
     [[ ! -f "${VENV_DIR}/bin/activate" ]] && setup_virtualenv
     source ${VENV_DIR}/bin/activate
-    pip install reno
     reno lint ${CURDIR}/../
 }
 
@@ -200,19 +215,38 @@
 }
 
 run_model_validate(){
-    [[ -d ${SCHEMARDIR} ]] || { log_err "${SCHEMARDIR} not found!"; return 1; }
+  # Run modelschema.model_validate validation.
+  # TEST iterateble, run for `each formula ROLE against each ROLE_PILLARNAME`
+  # Pillars should be named in conviend ROLE_XXX.sls or ROLE.sls
+  # Example:
+  # client.sls  client_auth.sls  server.sls  server_auth.sls
+  if [ -d ${SCHEMARDIR} ]; then
     # model validator require py modules
     fetch_dependency "salt:https://github.com/salt-formulas/salt-formula-salt"
     link_modules
-    # Rendered Example:
-    # salt-call --local -c /test1/maas/tests/build/salt --id=maas_cluster modelschema.model_validate maas cluster
+    salt_run saltutil.clear_cache; salt_run saltutil.refresh_pillar; salt_run saltutil.sync_all;
     for role in ${SCHEMARDIR}/*.yaml; do
-        state_name=$(basename "${role%*.yaml}")
-        minion_id="${state_name}"
-        # in case debug-reruns, usefull to make cleanup
-        [ -n "$DEBUG" ] && { salt_run saltutil.clear_cache; salt_run saltutil.refresh_pillar; salt_run saltutil.sync_all; }
-        salt_run --id=${minion_id} modelschema.model_validate ${FORMULA_NAME} ${state_name} || { log_err "Execution of ${FORMULA_NAME}.${state_name} failed"; exit 1 ; }
+      role_name=$(basename "${role%*.yaml}")
+      for pillar in $(ls pillar/${role_name}*.sls | grep -v ${IGNORE_MODELVALIDATE_MASK} ); do
+        pillar_name=$(basename "${pillar%*.sls}")
+        local _message="FORMULA:${FORMULA_NAME} ROLE:${role_name} against PILLAR:${pillar_name}"
+        log_info "model_validate ${_message}"
+        # Rendered Example:
+        # python $(which salt-call) --local -c /test1/maas/tests/build/salt --id=maas_cluster modelschema.model_validate maas cluster
+        salt_run -m ${DEPSDIR}/salt-formula-salt --id=${pillar_name} modelschema.model_validate ${FORMULA_NAME} ${role_name} || { log_err "Execution of model_validate ${_message} failed"; exit 1 ; }
+      done
     done
+  else
+    log_info "${SCHEMARDIR} not found!";
+  fi
+}
+
+dependency_check() {
+  local DEPENDENCY_COMMANDS=$*
+
+  for DEPENDENCY_COMMAND in $DEPENDENCY_COMMANDS; do
+    which $DEPENDENCY_COMMAND > /dev/null || ( log_err "Command \"$DEPENDENCY_COMMAND\" can not be found in default path."; exit 1; )
+  done
 }
 
 _atexit() {
@@ -228,6 +262,10 @@
 }
 
 ## Main
+
+log_info "Running version: ${__ScriptVersion}"
+log_info "Command line: '${__ScriptFullName} ${__ScriptArgs}'"
+
 trap _atexit INT TERM EXIT
 
 case $1 in
diff --git "a/\173\173cookiecutter.service_name\175\175/tests/test-requirements.txt" "b/\173\173cookiecutter.service_name\175\175/tests/test-requirements.txt"
new file mode 100644
index 0000000..a0f561a
--- /dev/null
+++ "b/\173\173cookiecutter.service_name\175\175/tests/test-requirements.txt"
@@ -0,0 +1,2 @@
+jsonschema
+reno
diff --git "a/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.service_name\175\175/schemas/\173\173cookiecutter.role_name\175\175.yaml" "b/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.service_name\175\175/schemas/\173\173cookiecutter.role_name\175\175.yaml"
new file mode 100644
index 0000000..d803f15
--- /dev/null
+++ "b/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.service_name\175\175/schemas/\173\173cookiecutter.role_name\175\175.yaml"
@@ -0,0 +1,17 @@
+%YAML 1.1
+---
+"$schema": "http://json-schema.org/draft-06/schema#"
+title: {{cookiecutter.service_name}} daemon role
+description: |
+  {{cookiecutter.service_name|capitalize}} daemon, server role
+type: object
+additionalProperties: false
+
+required:
+  - enabled
+
+properties:
+  enabled:
+    description: |
+      Enables {{cookiecutter.service_name}} daemon service
+    type: boolean
diff --git "a/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.role_name\175\175.sls" "b/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.role_name\175\175.sls"
deleted file mode 100644
index 3fcdea5..0000000
--- "a/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.service_name\175\175/\173\173cookiecutter.role_name\175\175.sls"
+++ /dev/null
@@ -1,4 +0,0 @@
-{{ '{%-' }} from "{{cookiecutter.service_name}}/map.jinja" import {{cookiecutter.role_name}} with context {{ '%}' }}
-{{ '{%-' }} if {{cookiecutter.role_name}}.enabled {{ '%}' }}
-
-{{ '{%-' }} endif {{ '%}' }}