Last active
January 25, 2022 12:23
-
-
Save ppmathis/a78d9000a4ba90e7f6571ce06f6bc209 to your computer and use it in GitHub Desktop.
SaltStack: Custom state and execution module for ansible-like 'assemble' function
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import salt.loader | |
import salt.utils | |
import salt.utils.jinja | |
import salt.utils.files | |
from salt.exceptions import SaltInvocationError, CommandExecutionError | |
def get_assemble_fragments(fragments_path, include_pattern=None, exclude_pattern=None): | |
# Verify given fragments path | |
if not os.path.isabs(fragments_path): | |
raise SaltInvocationError('Fragments path must be absolute: {0}'.format(fragments_path)) | |
if not os.path.isdir(fragments_path): | |
raise SaltInvocationError('Fragments path must exist and be a directory: {0}'.format(fragments_path)) | |
# Get list of all fragment files | |
fragment_file_paths = set() | |
try: | |
# List all directory entries without using recursion | |
for entry_name in os.listdir(fragments_path): | |
entry_path = os.path.join(fragments_path, entry_name) | |
# Skip entry if path is not a file | |
if not os.path.isfile(entry_path): | |
continue | |
# Skip entry if name does not match include/exclude_pat | |
if not salt.utils.check_include_exclude(entry_path, include_pattern, exclude_pattern): | |
continue | |
# Append entry to set of source files | |
fragment_file_paths.add(entry_path) | |
except Exception as exc: | |
raise CommandExecutionError('Could not build list of fragment files: {0}'.format(exc)) | |
# Collect content of all fragment files, sorted by name/path | |
fragments = [] | |
try: | |
for fragment_file_path in sorted(fragment_file_paths): | |
with open(fragment_file_path, 'r') as fragment_file: | |
fragments.append({'source': fragment_file_path, 'content': fragment_file.read()}) | |
except Exception as exc: | |
raise CommandExecutionError('Unable to collect content of fragment files: {0}'.format(exc)) | |
# Return collected fragments | |
return fragments |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# noinspection PyUnresolvedReferences | |
from salt.states.file import * | |
def _error(ret, err_msg): | |
ret['result'] = False | |
ret['comment'] = err_msg | |
return ret | |
def assemble(name, | |
fragments, | |
include_pat=None, | |
exclude_pat=None, | |
template_src=None, | |
**kwargs): | |
ret = { | |
'name': name, | |
'changes': {}, | |
'pchanges': {}, | |
'result': True, | |
'comment': '' | |
} | |
# Fetch all fragments by executing ssx.get_assemble_fragments | |
try: | |
fragments = __salt__['ssx.get_assemble_fragments'](fragments_path=fragments, include_pattern=include_pat, | |
exclude_pattern=exclude_pat) | |
except Exception as exc: | |
return _error(ret, exc) | |
# Remove specific, dangerous keys before passing all kwargs to file.managed | |
for key in ('source', 'source_hash', 'contents', 'contents_grains', 'contents_pillar'): | |
kwargs.pop(key, None) | |
# Override kwargs for contents/source for fragments rendering | |
if not template_src: | |
fragment_contents = ([fragment['content'] for fragment in fragments]) | |
kwargs.update({ | |
'name': name, | |
'contents': fragment_contents | |
}) | |
else: | |
context = kwargs.get('context', {}) | |
context.update({'__fragments__': fragments}) | |
kwargs.update({ | |
'name': name, | |
'source': template_src, | |
'context': context | |
}) | |
# Execute file.managed state with modified kwargs, merge the results and return | |
ret.update(__states__['file.managed'](**kwargs)) | |
return ret |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
THIS IS HEADA! | |
{%- for fragment in __fragments__ %} | |
# {{ fragment.source }} {{ '{{{' }} | |
{{ fragment.content -}} | |
# {{ '}}}' }} | |
{%- endfor %} | |
THIS IS FOOTA! |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/tmp/development/salt/assemble1.cfg: | |
ssx.assemble: | |
- fragments: /tmp/development/salt/assemble1-fragments | |
/tmp/development/salt/assemble2.cfg: | |
ssx.assemble: | |
- fragments: /tmp/development/salt/assemble2-fragments | |
- include_pat: '*.conf' | |
- template: jinja | |
- template_src: salt://assemble.j2 | |
- check_cmd: /bin/true |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment