Merge pull request #14 from jebas/master
Creates a human readable, tested, config file that fixes issue #12
This commit is contained in:
commit
869b54d3be
42
keepalived/templates/config.jinja
Normal file
42
keepalived/templates/config.jinja
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
{%- set key = 0 -%}
|
||||||
|
{%- set value = 1 -%}
|
||||||
|
{%- set carryovers = ['real_server', 'virtual_server', 'virtual_server_group',
|
||||||
|
'vrrp_instance', 'vrrp_script', 'vrrp_sync_group'] -%}
|
||||||
|
{%- macro keepalived_config(data, carryover='', recurse=-1, indent=0) -%}
|
||||||
|
{%- set recurse = recurse + 1 -%}
|
||||||
|
{%- if data is none -%}
|
||||||
|
{{- '\n' -}}
|
||||||
|
{%- elif data is string or data is number -%}
|
||||||
|
{{- data|string|indent(indent, True) }}{{ '\n' -}}
|
||||||
|
{%- else -%}
|
||||||
|
{%- if recurse > 0 -%}
|
||||||
|
{{- '{\n' -}}
|
||||||
|
{%- set indent = indent + 2 -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if data is mapping -%}
|
||||||
|
{%- for item in data|dictsort -%}
|
||||||
|
{%- if item[key] in carryovers -%}
|
||||||
|
{{- keepalived_config(item[value], carryover=item[key], indent=indent) -}}
|
||||||
|
{%- else -%}
|
||||||
|
{%- set carryIndent = indent -%}
|
||||||
|
{%- set forwardIndent = indent -%}
|
||||||
|
{%- if carryover -%}
|
||||||
|
{{- carryover|indent(indent, True) }}{{ ' ' -}}
|
||||||
|
{%- set carryIndent = 0 -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if item[value] is string or item[value] is not iterable -%}
|
||||||
|
{%- set forwardIndent = 0 -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{{- item[key]|indent(carryIndent, True) }} {{ keepalived_config(item[value], recurse=recurse, indent=forwardIndent) -}}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- else -%}
|
||||||
|
{%- for item in data -%}
|
||||||
|
{{- keepalived_config(item, indent=indent) -}}
|
||||||
|
{%- endfor -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- if recurse > 0 -%}
|
||||||
|
{{- '}'|indent(indent - 2, True) -}}{{ '\n' }}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endif -%}
|
||||||
|
{%- endmacro -%}
|
@ -6,58 +6,10 @@
|
|||||||
# Any changes will be overwritten.
|
# Any changes will be overwritten.
|
||||||
{{ '\n' }}
|
{{ '\n' }}
|
||||||
|
|
||||||
{#
|
{%- import 'keepalived/templates/config.jinja' as config -%}
|
||||||
Macro Explanation:
|
|
||||||
|
|
||||||
This is a recursive macro that takes the type of entry and determines how
|
|
||||||
it is suppose to appear in the configuration file. Strings and numbers
|
|
||||||
are just written out. Lists and hashes are placed inside if couple of
|
|
||||||
parenthesis. It also takes into account the special groupings like
|
|
||||||
vrrp_instance and virtual_server. Any additional data from a list or a
|
|
||||||
hash is then processed by calling the macro again.
|
|
||||||
|
|
||||||
Forced carriage returns and use of jinja's indent are only there to make
|
|
||||||
the final file more human readable. They serve no other function.
|
|
||||||
#}
|
|
||||||
|
|
||||||
{%- import_yaml 'keepalived/defaults.yaml' as keepalived_defaults -%}
|
{%- import_yaml 'keepalived/defaults.yaml' as keepalived_defaults -%}
|
||||||
{%- set keepalived_final_values = salt.pillar.get(
|
{%- set keepalived_final_values = salt.pillar.get(
|
||||||
'keepalived',
|
'keepalived',
|
||||||
default=keepalived_defaults,
|
default=keepalived_defaults,
|
||||||
merge=True) -%}
|
merge=True) -%}
|
||||||
|
{{ config.keepalived_config(keepalived_final_values) }}
|
||||||
{%- set groupings = ['vrrp_script', 'vrrp_sync_group', 'vrrp_instance',
|
|
||||||
'virtual_server_group', 'virtual_server', 'real_server'] -%}
|
|
||||||
{%- macro config_entries(data, indents, carryover='') -%}
|
|
||||||
{%- if data is string or data is number -%}
|
|
||||||
{{- data|string|indent(indents, True) }}{{ '\n' -}}
|
|
||||||
{%- elif data is none -%}
|
|
||||||
{{- '\n' -}}
|
|
||||||
{%- else -%}
|
|
||||||
{%- if indents != 0 and not carryover -%}
|
|
||||||
{{- " {\n" -}}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- if data is mapping -%}
|
|
||||||
{%- for entry in data|dictsort -%}
|
|
||||||
{%- if entry[0] in groupings -%}
|
|
||||||
{{- config_entries(entry[1], indents, carryover=entry[0]) -}}
|
|
||||||
{%- else -%}
|
|
||||||
{%- if carryover -%}
|
|
||||||
{{- carryover|indent(indents, True) }}{{ ' ' }}
|
|
||||||
{%- endif -%}
|
|
||||||
{{- entry[0]|indent(indents, True) }}
|
|
||||||
{{- config_entries(entry[1], indents + 2) -}}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- endfor -%}
|
|
||||||
{%- else -%}
|
|
||||||
{%- for entry in data -%}
|
|
||||||
{{- config_entries(entry, indents) -}}
|
|
||||||
{%- endfor -%}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- if indents != 0 and not carryover -%}
|
|
||||||
{{- '}'|indent(indents - 2, True) }}{{ '\n' }}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- endif -%}
|
|
||||||
{%- endmacro -%}
|
|
||||||
|
|
||||||
{{ config_entries(keepalived_final_values, 0) }}
|
|
||||||
|
2
keepalived/templates/test_config.jinja
Normal file
2
keepalived/templates/test_config.jinja
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
{% import 'config.jinja' as config %}
|
||||||
|
{{ config.keepalived_config(testdata) }}
|
@ -1,6 +1,15 @@
|
|||||||
#
|
#
|
||||||
# Example pillar configuration
|
# Example pillar configuration
|
||||||
#
|
#
|
||||||
|
# Boolean entries must be placed stored as strings, otherwise it will show
|
||||||
|
# up as 1 or 0 in the config file.
|
||||||
|
#
|
||||||
|
# Anything that needs to be in quotes in the configuration file needs to
|
||||||
|
# be escaped in the yaml file. Otherwise the quotes will not appear in
|
||||||
|
# the config file.
|
||||||
|
#
|
||||||
|
# When order is important, put the entries into a yaml array or list. This
|
||||||
|
# could be used to place vrrp_script before vrrp_instance entries.
|
||||||
|
|
||||||
# The following would generate the example file in RedHat based systems.
|
# The following would generate the example file in RedHat based systems.
|
||||||
|
|
||||||
|
0
test/__init__.py
Normal file
0
test/__init__.py
Normal file
118
test/test_keepalived_config.py
Executable file
118
test/test_keepalived_config.py
Executable file
@ -0,0 +1,118 @@
|
|||||||
|
#!/usr/bin/python
|
||||||
|
|
||||||
|
import os, unittest
|
||||||
|
from jinja2 import Environment, FileSystemLoader
|
||||||
|
|
||||||
|
class TestKeepalivedConfiguration(unittest.TestCase):
|
||||||
|
|
||||||
|
def setUp(self):
|
||||||
|
self.t_dir = os.path.abspath(os.path.join(
|
||||||
|
os.path.dirname(__file__),
|
||||||
|
os.pardir,
|
||||||
|
'keepalived',
|
||||||
|
'templates'))
|
||||||
|
self.t_conf = Environment(loader=FileSystemLoader(self.t_dir),
|
||||||
|
trim_blocks=True)
|
||||||
|
|
||||||
|
def renderTest(self, data, result):
|
||||||
|
holder = self.t_conf.get_template('test_config.jinja').render(testdata=data)
|
||||||
|
output = repr(holder) + ' did not equal ' + repr(result)
|
||||||
|
self.assertEqual(holder, result, output)
|
||||||
|
|
||||||
|
def test_string(self):
|
||||||
|
testdata = 'stuff'
|
||||||
|
result = 'stuff\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_number(self):
|
||||||
|
testdata = 3
|
||||||
|
result = '3\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_null(self):
|
||||||
|
testdata = None
|
||||||
|
result = '\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_key_value_pair(self):
|
||||||
|
testdata = {'flintstone': 'fred'}
|
||||||
|
result = 'flintstone fred\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_key_array_pair(self):
|
||||||
|
testdata = {'flintstone': ['fred', 'wilma', 'pebbles']}
|
||||||
|
result = 'flintstone {\n fred\n wilma\n pebbles\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_key_hash_pair(self):
|
||||||
|
testdata = {'friends': {'rubble': 'barney'}}
|
||||||
|
result = 'friends {\n rubble barney\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_key_ordered_hashs(self):
|
||||||
|
testdata = {'friends': {'fred': 'flintstone', 'barney': 'rubble', 'wilma': 'flintstone', 'betty': 'rubble'}}
|
||||||
|
result = 'friends {\n barney rubble\n betty rubble\n fred flintstone\n wilma flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_ordered_hashes(self):
|
||||||
|
testdata = [{'fred': 'flintstone'}, {'wilma': 'flintstone'}, {'barney': 'rubble'}, {'betty': 'rubble'}]
|
||||||
|
result = 'fred flintstone\nwilma flintstone\nbarney rubble\nbetty rubble\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover(self):
|
||||||
|
testdata = {'vrrp_script': {'gizmo': {'fred': 'flintstone', 'barney': 'rubble'}}}
|
||||||
|
result = 'vrrp_script gizmo {\n barney rubble\n fred flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover_contains_arry(self):
|
||||||
|
testdata = {'vrrp_script': {'gizmo': [{'fred': 'flintstone'}, {'barney': 'rubble'}]}}
|
||||||
|
result = 'vrrp_script gizmo {\n fred flintstone\n barney rubble\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover_vrrp_instance(self):
|
||||||
|
testdata = {'vrrp_instance': {'gizmo': {'fred': 'flintstone', 'barney': 'rubble'}}}
|
||||||
|
result = 'vrrp_instance gizmo {\n barney rubble\n fred flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryovers_in_an_array(self):
|
||||||
|
testdata = [{'vrrp_script': {'gizmo': {'running': 'dumdums'}}}, {'vrrp_instance': {'dumdums': {'fred': 'flintstone'}}}]
|
||||||
|
result = 'vrrp_script gizmo {\n running dumdums\n}\nvrrp_instance dumdums {\n fred flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover_vrrp_sync_group(self):
|
||||||
|
testdata = {'vrrp_sync_group': {'gizmo': {'fred': 'flintstone', 'barney': 'rubble'}}}
|
||||||
|
result = 'vrrp_sync_group gizmo {\n barney rubble\n fred flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover_virtual_server_group(self):
|
||||||
|
testdata = {'virtual_server_group': {'gizmo': {'fred': 'flintstone', 'barney': 'rubble'}}}
|
||||||
|
result = 'virtual_server_group gizmo {\n barney rubble\n fred flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover_virtual_server(self):
|
||||||
|
testdata = {'virtual_server': {'gizmo': {'fred': 'flintstone', 'barney': 'rubble'}}}
|
||||||
|
result = 'virtual_server gizmo {\n barney rubble\n fred flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover_real_server(self):
|
||||||
|
testdata = {'real_server': {'gizmo': {'fred': 'flintstone', 'barney': 'rubble'}}}
|
||||||
|
result = 'real_server gizmo {\n barney rubble\n fred flintstone\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_carryover_within_carryover(self):
|
||||||
|
testdata = {'virtual_server': {'gizmo': {'real_server': {'dumdums': {'fred': 'flintstone', 'barney': 'rubble'}}}}}
|
||||||
|
result = 'virtual_server gizmo {\n real_server dumdums {\n barney rubble\n fred flintstone\n }\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_indent_nested_hashes(self):
|
||||||
|
testdata = {'flintstone': {'fred': {'role': {'family': 'father'}}}}
|
||||||
|
result = 'flintstone {\n fred {\n role {\n family father\n }\n }\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
def test_indent_carryover_with_nested_hashes(self):
|
||||||
|
testdata = {'real_server': {'gizmo': {'another': 'day', 'dumdums': {'fred': 'flintstone', 'barney': 'rubble'}}}}
|
||||||
|
result = 'real_server gizmo {\n another day\n dumdums {\n barney rubble\n fred flintstone\n }\n}\n'
|
||||||
|
self.renderTest(testdata, result)
|
||||||
|
|
||||||
|
if __name__ == '__main__':
|
||||||
|
unittest.main()
|
Loading…
Reference in New Issue
Block a user