Skip to content

Instantly share code, notes, and snippets.

@tony
Last active July 4, 2018 08:22
Show Gist options
  • Save tony/6d8d975c817d2e4d43dd to your computer and use it in GitHub Desktop.
Save tony/6d8d975c817d2e4d43dd to your computer and use it in GitHub Desktop.
Can saltstack states and modules play with pure python / fabric? https://github.com/saltstack/salt/issues/22842
# -*- coding: utf-8 -*-
"""Proof of concept to use saltstack's pure modules and states with fabric::
fab list_packages print_specs -H <ip> --user=<user>
On my vagrant environment:
fab list_packages print_specs -H <ip> --password=vagrant --user=vagrant
"""
import os
import sys
import subprocess
from salt.modules.cmdmod import DEFAULT_SHELL
sys.path.append(os.path.dirname(__file__))
from salt_python import salt
try:
import fabric
except ImportError:
raise Exception("""
You must install the latest version of salt:
pip install fabric
""")
def salt_run_fabric(cmd,
cwd=None,
stdin=None,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
output_loglevel='debug',
quiet=False,
runas=None,
shell=DEFAULT_SHELL,
python_shell=True,
env=None,
clean_env=False,
rstrip=True,
template=None,
umask=None,
timeout=None,
with_communicate=True,
reset_system_locale=True,
ignore_retcode=False,
saltenv='base',
use_vt=False):
"""Adapter to fit salt's argument signature into into fabric's
subprocess wrapper."""
return fabric.operations.sudo(
cmd,
shell=shell,
user=runas,
timeout=timeout,
warn_only=ignore_retcode,
stdout=stdout,
stderr=stderr,
env=env
)
def salt_run_fabric_quiet(cmd,
cwd=None,
stdin=None,
runas=None,
shell=DEFAULT_SHELL,
python_shell=True,
env=None,
template=None,
umask=None,
timeout=None,
reset_system_locale=True,
saltenv='base'):
'''
Helper for running commands quietly for minion startup
'''
return salt_run_fabric(cmd,
runas=runas,
cwd=cwd,
stdin=stdin,
stderr=subprocess.STDOUT,
output_loglevel='quiet',
shell=shell,
python_shell=python_shell,
env=env,
template=template,
umask=umask,
timeout=timeout,
reset_system_locale=reset_system_locale,
saltenv=saltenv)['stdout']
def bootstrap_fabric():
from salt.config import DEFAULT_MASTER_OPTS
from salt.grains.core import os_data
__builtins__['__salt__'] = {
'cmd.run': salt_run_fabric,
'cmd.run_all': salt.modules.cmdmod.run_all
}
__builtins__['__context__'] = {}
__builtins__['__env__'] = {}
__builtins__['__opts__'] = DEFAULT_MASTER_OPTS
__builtins__['__grains__'] = salt.loader.grains(__opts__)
__builtins__['__salt__'].update(
salt.loader.minion_mods(
__opts__
)
)
print(__salt__.keys())
bootstrap_fabric()
@fabric.api.task
def list_packages():
# from salt.modules import aptpkg
# if __grains__['os'] == 'MacOS' and sources:
# causes a race condition
#print(aptpkg.install('vim'))
from salt.modules import aptpkg
print(aptpkg.list_pkgs())
@fabric.api.task
def print_specs():
from pprint import PrettyPrinter
pp = PrettyPrinter(indent=4).pprint
pp(__grains__)
#!/usr/bin/env python
"""
Mission
-------
This is a work-around to bolt saltstack modules and states into any python code.
Saltstack is a permissively-licensed, pythonic configuration management system.
Fabric is a task-runner for all sorts of miscellaneous configurations. Both are
essential tools.
You can read the documentation for the commands at:
- http://docs.saltstack.com/en/latest/ref/states/all/
- http://docs.saltstack.com/en/latest/ref/modules/all/
Growing big
-----------
If you think that your fabric file is getting too bit, or your needs get
too complicated, you can migrate your project to a salt's declarative YAML
syntax, cloud provisioning and more.
You can begin to move over using a crawl-walk-run approach. First, start
creating some initial `salt states`_ in YAML.
You can start by installing to your local machine and using ``salt-ssh`` to
setup servers. This is `Roster`_\ -based configuration.
If you are beginning to manage large clusters of servers, it makes sense to
start controlling your system via a `Salt Master`_.
.. _Roster: http://docs.saltstack.com/en/latest/topics/ssh/roster.html
.. _salt states: http://docs.saltstack.com/en/latest/topics/tutorials/starting_states.html
.. _Salt Master: http://docs.saltstack.com/en/latest/topics/tutorials/walkthrough.html#setting-up-the-salt-master
Copyright 2015, Tony Narlock (tony@git-pull.com). Licensed MIT.
Fabric is MIT, https://github.com/fabric/fabric/blob/master/LICENSE
SaltStack is Apache 2: https://github.com/saltstack/salt/blob/develop/LICENSE
"""
try:
import salt
except ImportError:
raise Exception("""
You must install the latest version of salt:
curl -L https://bootstrap.saltstack.com -o install_salt.sh
sudo sh install_salt.sh git develop
""")
def bootstrap_python():
"""
Temporary __builtins__ workaround until saltstack is refactored to handle
importing modules pythonically.
"""
from salt.config import DEFAULT_MASTER_OPTS
import salt.log.setup
salt.log.setup.setup_temp_logger(log_level='debug')
__builtins__.__salt__ = {
'cmd.run': salt.modules.cmdmod._run_quiet,
'cmd.run_all': salt.modules.cmdmod.run_all
}
__builtins__.__grains__ = {}
__builtins__.__opts__ = DEFAULT_MASTER_OPTS
__builtins__.__salt__.update(
salt.loader.minion_mods(
__opts__
)
)
def git_clone_salt():
from salt.modules import git
git.clone(
cwd='/home/tony/study/salt/_salt',
repository='https://github.com/saltstack/salt',
)
def latest_salt():
import salt.states.git
return salt.states.git.latest(
target='/home/tony/study/salt/_salt2',
name='https://github.com/saltstack/salt',
)
if __name__ == '__main__':
bootstrap_python()
print(latest_salt())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment