diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index f00fdeb..5e0c7c4 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -10,6 +10,14 @@ test_roles: tags: - docker +test_custom_grains: + stage: test + before_script: + - zypper -qn in --no-recommends python3 python3-PyYAML + script: bin/test_custom_grains.py + tags: + - docker + test_show_highstate: stage: test before_script: diff --git a/bin/test_custom_grains.py b/bin/test_custom_grains.py new file mode 100755 index 0000000..0288baa --- /dev/null +++ b/bin/test_custom_grains.py @@ -0,0 +1,61 @@ +#!/usr/bin/python3 + +# Validates if the pillar/id/$FQDN.sls has correct custom grains + +import yaml +import os +import sys + + +def error_msg(sls, key, valid_values): + if type(valid_values) == str: + msg = ' is' + result = valid_values + else: + msg = 's are' + result = ', '.join(valid_values) + print('pillar/id/%s has invalid value for the "%s" key. Valid value%s: %s' % (sls, key, msg, result)) + return 1 + + +def test_custom_grain(mygrains, sls, key, valid_values, status): + try: + value = mygrains[key] + except KeyError: + print('pillar/id/%s is missing the "%s" key' % (sls, key)) + return 1 + + if type(valid_values) == str: + if value != valid_values: + status = error_msg(sls, key, valid_values) + else: + if value not in valid_values: + status = error_msg(sls, key, valid_values) + + return status + + +status = 0 + +with open('pillar/valid_custom_grains.yaml', 'r') as f: + VALID_CUSTOM_GRAINS = yaml.load(f) + +valid_global_grains = VALID_CUSTOM_GRAINS['global'] +all_localized_grains = VALID_CUSTOM_GRAINS['localized'] + +all_ids = sorted(os.listdir('pillar/id')) +for sls in all_ids: + with open("pillar/id/%s" % sls) as f: + mygrains = yaml.load(f)['grains'] + + for key, valid_values in valid_global_grains.items(): + status = test_custom_grain(mygrains, sls, key, valid_values, status) + + try: + valid_localized_grains = all_localized_grains[mygrains['country']] + for key, valid_values in valid_localized_grains.items(): + status = test_custom_grain(mygrains, sls, key, valid_values, status) + except KeyError: + status = error_msg(sls, 'country', all_localized_grains.keys()) + +sys.exit(status) diff --git a/pillar/macros.jinja b/pillar/macros.jinja index 3a7579c..c234db6 100644 --- a/pillar/macros.jinja +++ b/pillar/macros.jinja @@ -5,3 +5,18 @@ {% endif %} {%- endfor %} {%- endmacro %} + +{%- macro valid_virt_cluster() -%} + {%- import_yaml "valid_custom_grains.yaml" as valid_custom_grains -%} + {%- set valid_virt_cluster = [] -%} + {%- for country, data in valid_custom_grains['localized'].items() -%} + {%- if data['virt_cluster'] is iterable and data['virt_cluster'] is not string -%} + {%- for item in data['virt_cluster'] -%} + {%- do valid_virt_cluster.append(item) -%} + {%- endfor -%} + {%- else -%} + {%- do valid_virt_cluster.append(data['virt_cluster']) -%} + {%- endif -%} + {%- endfor -%} + {{ valid_virt_cluster }} +{%- endmacro -%} diff --git a/pillar/top.sls b/pillar/top.sls index ae95529..eab9795 100644 --- a/pillar/top.sls +++ b/pillar/top.sls @@ -1,4 +1,5 @@ {% from "macros.jinja" import include_optional with context %} +{% from "macros.jinja" import valid_virt_cluster with context %} {% set country = salt['grains.get']('country') %} {% set domain = salt['grains.get']('domain') %} {% set id = salt['grains.get']('id') %} @@ -17,7 +18,7 @@ production: - match: grain {{ include_optional("role/{0}".format(role)) }} {% endfor %} - {% if virt_cluster in ['atreju', 'bryce'] %} + {% if virt_cluster in valid_virt_cluster() %} 'virt_cluster:{{ virt_cluster }}': - match: grain - virt_cluster.{{ virt_cluster }} diff --git a/pillar/valid_custom_grains.yaml b/pillar/valid_custom_grains.yaml new file mode 100644 index 0000000..285daa3 --- /dev/null +++ b/pillar/valid_custom_grains.yaml @@ -0,0 +1,10 @@ +--- +global: + salt_cluster: opensuse +localized: + de: + city: nuremberg + virt_cluster: atreju + us: + city: provo + virt_cluster: bryce