From 5e72e192f9713719ef5ec066c7b6c96302327ec6 Mon Sep 17 00:00:00 2001 From: Pedro Algarvio Date: Tue, 9 Jun 2020 09:58:34 +0100 Subject: [PATCH] Blacken docs --- .pre-commit-config.yaml | 9 +- doc/ref/configuration/logging/index.rst | 14 +- doc/ref/configuration/minion.rst | 8 +- doc/ref/executors/index.rst | 3 +- doc/ref/file_server/index.rst | 16 +- doc/ref/internals/opts.rst | 6 +- doc/ref/modules/index.rst | 111 ++++--- doc/ref/renderers/all/salt.renderers.yaml.rst | 4 +- doc/ref/renderers/index.rst | 19 +- doc/ref/returners/index.rst | 92 +++--- doc/ref/runners/index.rst | 13 +- doc/ref/states/aggregate.rst | 42 +-- doc/ref/states/writing.rst | 108 ++++--- doc/topics/beacons/index.rst | 3 +- doc/topics/cloud/cloud.rst | 49 ++- doc/topics/cloud/config.rst | 119 +++---- doc/topics/cloud/reactor.rst | 4 +- doc/topics/cloud/salt.rst | 3 +- .../development/conventions/documentation.rst | 12 +- .../development/conventions/formulas.rst | 27 +- doc/topics/development/conventions/style.rst | 24 +- doc/topics/development/deprecations.rst | 8 +- doc/topics/development/extend/index.rst | 4 +- doc/topics/development/modules/developing.rst | 14 +- .../development/modules/external_pillars.rst | 21 +- doc/topics/development/modules/index.rst | 6 +- doc/topics/development/package_providers.rst | 71 +++-- doc/topics/development/tests/index.rst | 1 + doc/topics/development/tests/integration.rst | 157 ++++----- doc/topics/development/tests/unit.rst | 299 +++++++++--------- doc/topics/event/events.rst | 52 ++- doc/topics/ext_processes/index.rst | 4 +- doc/topics/grains/index.rst | 16 +- doc/topics/jinja/index.rst | 24 +- doc/topics/master_tops/index.rst | 7 +- doc/topics/matchers/index.rst | 9 +- doc/topics/orchestrate/orchestrate_runner.rst | 4 +- doc/topics/proxyminion/index.rst | 287 +++++++++-------- doc/topics/releases/0.9.3.rst | 8 +- doc/topics/releases/0.9.9.rst | 4 +- doc/topics/releases/2016.11.0.rst | 26 +- doc/topics/releases/2016.3.0.rst | 13 +- doc/topics/releases/2017.7.0.rst | 2 +- doc/topics/releases/2018.3.0.rst | 4 +- doc/topics/return_codes/index.rst | 2 +- doc/topics/sdb/index.rst | 4 +- doc/topics/spm/dev.rst | 4 +- .../troubleshooting/yaml_idiosyncrasies.rst | 2 +- doc/topics/tutorials/http.rst | 130 +++----- .../tutorials/jinja_to_execution_module.rst | 26 +- doc/topics/tutorials/packaging_modules.rst | 34 +- doc/topics/tutorials/rooted.rst | 28 +- doc/topics/tutorials/starting_states.rst | 14 +- doc/topics/tutorials/states_pt3.rst | 5 +- doc/topics/tutorials/writing_tests.rst | 54 ++-- doc/topics/utils/index.rst | 49 +-- doc/topics/yaml/index.rst | 12 +- 57 files changed, 1069 insertions(+), 1022 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 0fbbfcfaa19..89fb5a28798 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -705,7 +705,7 @@ repos: )$ - repo: https://github.com/psf/black - rev: stable + rev: 19.10b0 hooks: - id: black # This tells pre-commit not to pass files to black. @@ -717,6 +717,13 @@ repos: tests/kitchen/.* )$ + - repo: https://github.com/asottile/blacken-docs + rev: v1.7.0 + hooks: + - id: blacken-docs + args: [--skip-errors] + files: ^doc/.*\.rst + additional_dependencies: [black==19.10b0] - repo: https://github.com/saltstack/salt-nox-pre-commit rev: master diff --git a/doc/ref/configuration/logging/index.rst b/doc/ref/configuration/logging/index.rst index fa1d87fbf38..fb9b3a1aa79 100644 --- a/doc/ref/configuration/logging/index.rst +++ b/doc/ref/configuration/logging/index.rst @@ -183,10 +183,10 @@ custom LogRecord attributes to colorize console log output: .. code-block:: python - '%(colorlevel)s' # log level name colorized by level - '%(colorname)s' # colorized module name - '%(colorprocess)s' # colorized process number - '%(colormsg)s' # log message colorized by level + "%(colorlevel)s" # log level name colorized by level + "%(colorname)s" # colorized module name + "%(colorprocess)s" # colorized process number + "%(colormsg)s" # log message colorized by level .. note:: The ``%(colorlevel)s``, ``%(colorname)s``, and ``%(colorprocess)`` @@ -212,9 +212,9 @@ these custom LogRecord attributes that include padding and enclosing brackets .. code-block:: python - '%(bracketlevel)s' # equivalent to [%(levelname)-8s] - '%(bracketname)s' # equivalent to [%(name)-17s] - '%(bracketprocess)s' # equivalent to [%(process)5s] + "%(bracketlevel)s" # equivalent to [%(levelname)-8s] + "%(bracketname)s" # equivalent to [%(name)-17s] + "%(bracketprocess)s" # equivalent to [%(process)5s] .. code-block:: yaml diff --git a/doc/ref/configuration/minion.rst b/doc/ref/configuration/minion.rst index c91b727e155..c0dad97e92a 100644 --- a/doc/ref/configuration/minion.rst +++ b/doc/ref/configuration/minion.rst @@ -876,10 +876,11 @@ For example, with these custom grains functions: .. code-block:: python def custom1_k1(): - return {'custom1': {'k1': 'v1'}} + return {"custom1": {"k1": "v1"}} + def custom1_k2(): - return {'custom1': {'k2': 'v2'}} + return {"custom1": {"k2": "v2"}} Without ``grains_deep_merge``, the result would be: @@ -2710,8 +2711,7 @@ the ``extra_minion_data`` parameter will be .. code-block:: python - {'opt1': 'value1', - 'opt2': {'subopt1': 'value2'}} + {"opt1": "value1", "opt2": {"subopt1": "value2"}} Security Settings ================= diff --git a/doc/ref/executors/index.rst b/doc/ref/executors/index.rst index f72b8076fb5..97379fdba3a 100644 --- a/doc/ref/executors/index.rst +++ b/doc/ref/executors/index.rst @@ -59,7 +59,8 @@ the ``execute`` function with the following signature: .. code-block:: python - def execute(opts, data, func, args, kwargs) + def execute(opts, data, func, args, kwargs): + ... Where the args are: diff --git a/doc/ref/file_server/index.rst b/doc/ref/file_server/index.rst index ea35f0c59fe..908ee9a0a42 100644 --- a/doc/ref/file_server/index.rst +++ b/doc/ref/file_server/index.rst @@ -133,13 +133,14 @@ from within a minion module the built in ``__opts__`` data can be passed: import salt.minion import salt.fileclient - def get_file(path, dest, saltenv='base'): - ''' + + def get_file(path, dest, saltenv="base"): + """ Used to get a single file from the Salt master CLI Example: salt '*' cp.get_file salt://vimrc /etc/vimrc - ''' + """ # Get the fileclient object client = salt.fileclient.get_file_client(__opts__) # Call get_file @@ -153,12 +154,13 @@ data is not available, it needs to be generated: import salt.fileclient import salt.config - def get_file(path, dest, saltenv='base'): - ''' + + def get_file(path, dest, saltenv="base"): + """ Used to get a single file from the Salt master - ''' + """ # Get the configuration data - opts = salt.config.minion_config('/etc/salt/minion') + opts = salt.config.minion_config("/etc/salt/minion") # Get the fileclient object client = salt.fileclient.get_file_client(opts) # Call get_file diff --git a/doc/ref/internals/opts.rst b/doc/ref/internals/opts.rst index 494fdcac7f5..b742bfcee3c 100644 --- a/doc/ref/internals/opts.rst +++ b/doc/ref/internals/opts.rst @@ -25,7 +25,8 @@ for a minion instance: .. code-block:: python import salt.config - opts = salt.config.minion_config('/etc/salt/minion') + + opts = salt.config.minion_config("/etc/salt/minion") print(opts) To generate and display `opts` for a master, the process is similar: @@ -33,5 +34,6 @@ To generate and display `opts` for a master, the process is similar: .. code-block:: python import salt.config - opts = salt.config.master_config('/etc/salt/master') + + opts = salt.config.master_config("/etc/salt/master") print(opts) diff --git a/doc/ref/modules/index.rst b/doc/ref/modules/index.rst index 92c2d9e7035..faaab769e82 100644 --- a/doc/ref/modules/index.rst +++ b/doc/ref/modules/index.rst @@ -92,7 +92,7 @@ included libraries. def is_ok(person): - ''' Checks whether a person is really a lumberjack ''' + """ Checks whether a person is really a lumberjack """ return sleep.all_night(person) and work.all_day(person) Then, create the zip: @@ -154,7 +154,7 @@ dict: .. code-block:: python def foo(bar): - return __salt__['cmd.run'](bar) + return __salt__["cmd.run"](bar) This code will call the `run` function in the :mod:`cmd ` module and pass the argument ``bar`` to it. @@ -229,14 +229,16 @@ as also available in the ``__opts__`` dict. .. code-block:: python - ''' + """ Cheese module initialization example - ''' + """ + + def __init__(opts): - ''' + """ Allow foreign imports if configured to do so - ''' - if opts.get('cheese.allow_foreign', False): + """ + if opts.get("cheese.allow_foreign", False): _enable_foreign_products() @@ -266,9 +268,7 @@ names to Salt :ref:`outputters `. .. code-block:: python - __outputter__ = { - 'run': 'txt' - } + __outputter__ = {"run": "txt"} This will ensure that the ``txt`` outputter is used to display output from the ``run`` function. @@ -326,44 +326,50 @@ the case when the dependency is unavailable. .. code-block:: python - ''' + """ Cheese execution (or returner/beacon/etc.) module - ''' + """ try: import enzymes + HAS_ENZYMES = True except ImportError: HAS_ENZYMES = False def __virtual__(): - ''' + """ only load cheese if enzymes are available - ''' + """ if HAS_ENZYMES: - return 'cheese' + return "cheese" else: - return False, 'The cheese execution module cannot be loaded: enzymes unavailable.' + return ( + False, + "The cheese execution module cannot be loaded: enzymes unavailable.", + ) + def slice(): pass .. code-block:: python - ''' + """ Cheese state module. Note that this works in state modules because it is guaranteed that execution modules are loaded first - ''' + """ + def __virtual__(): - ''' + """ only load cheese if enzymes are available - ''' + """ # predicate loading of the cheese state on the corresponding execution module - if 'cheese.slice' in __salt__: - return 'cheese' + if "cheese.slice" in __salt__: + return "cheese" else: - return False, 'The cheese state module cannot be loaded: enzymes unavailable.' + return False, "The cheese state module cannot be loaded: enzymes unavailable." Examples -------- @@ -445,15 +451,15 @@ similar to the following: .. code-block:: python # Define the module's virtual name - __virtualname__ = 'pkg' + __virtualname__ = "pkg" def __virtual__(): - ''' + """ Confine this module to Mac OS with Homebrew. - ''' + """ - if salt.utils.path.which('brew') and __grains__['os'] == 'MacOS': + if salt.utils.path.which("brew") and __grains__["os"] == "MacOS": return __virtualname__ return False @@ -472,12 +478,11 @@ For example: .. code-block:: python def __virtual__(): - ''' + """ Only load if git exists on the system - ''' - if salt.utils.path.which('git') is None: - return (False, - 'The git execution module cannot be loaded: git unavailable.') + """ + if salt.utils.path.which("git") is None: + return (False, "The git execution module cannot be loaded: git unavailable.") else: return True @@ -505,13 +510,13 @@ To add documentation add a `Python docstring`_ to the function. .. code-block:: python def spam(eggs): - ''' + """ A function to make some spam with eggs! CLI Example:: salt '*' test.spam eggs - ''' + """ return eggs Now when the sys.doc call is executed the docstring will be cleanly returned @@ -560,9 +565,9 @@ logs. The following code snippet demonstrates writing log messages: log = logging.getLogger(__name__) - log.info('Here is Some Information') - log.warning('You Should Not Do That') - log.error('It Is Busted') + log.info("Here is Some Information") + log.warning("You Should Not Do That") + log.error("It Is Busted") Aliasing Functions ================== @@ -580,8 +585,8 @@ module, or from the cli, the alias name should be used. .. code-block:: python __func_alias__ = { - 'set_': 'set', - 'list_': 'list', + "set_": "set", + "list_": "list", } Private Functions @@ -604,10 +609,11 @@ Objects NOT Loaded into the Salt Minion .. code-block:: python - def _foobar(baz): # Preceded with an _ + def _foobar(baz): # Preceded with an _ return baz - cheese = {} # Not a callable Python object + + cheese = {} # Not a callable Python object Useful Decorators for Modules ============================= @@ -640,29 +646,32 @@ removing it try: import dependency_that_sometimes_exists except ImportError as e: - log.trace('Failed to import dependency_that_sometimes_exists: {0}'.format(e)) + log.trace("Failed to import dependency_that_sometimes_exists: {0}".format(e)) - @depends('dependency_that_sometimes_exists') + + @depends("dependency_that_sometimes_exists") def foo(): - ''' + """ Function with a dependency on the "dependency_that_sometimes_exists" module, if the "dependency_that_sometimes_exists" is missing this function will not exist - ''' + """ return True + def _fallback(): - ''' + """ Fallback function for the depends decorator to replace a function with - ''' + """ return '"dependency_that_sometimes_exists" needs to be installed for this function to exist' - @depends('dependency_that_sometimes_exists', fallback_function=_fallback) + + @depends("dependency_that_sometimes_exists", fallback_function=_fallback) def foo(): - ''' + """ Function with a dependency on the "dependency_that_sometimes_exists" module. If the "dependency_that_sometimes_exists" is missing this function will be replaced with "_fallback" - ''' + """ return True In addition to global dependencies the depends decorator also supports raw @@ -675,10 +684,12 @@ booleans. HAS_DEP = False try: import dependency_that_sometimes_exists + HAS_DEP = True except ImportError: pass + @depends(HAS_DEP) def foo(): return True diff --git a/doc/ref/renderers/all/salt.renderers.yaml.rst b/doc/ref/renderers/all/salt.renderers.yaml.rst index 2f4e3ca3b27..5c9a23b2bd0 100644 --- a/doc/ref/renderers/all/salt.renderers.yaml.rst +++ b/doc/ref/renderers/all/salt.renderers.yaml.rst @@ -40,7 +40,7 @@ In Python, the above maps to: .. code-block:: python - {'my_key': 'my_value'} + {"my_key": "my_value"} Dictionaries can be nested: @@ -53,7 +53,7 @@ And in Python: .. code-block:: python - {'first_level_dict_key': {'second_level_dict_key': 'value_in_second_level_dict' } } + {"first_level_dict_key": {"second_level_dict_key": "value_in_second_level_dict"}} Rule Three: Dashes ------------------ diff --git a/doc/ref/renderers/index.rst b/doc/ref/renderers/index.rst index 08174543464..38f55fb59ae 100644 --- a/doc/ref/renderers/index.rst +++ b/doc/ref/renderers/index.rst @@ -73,17 +73,14 @@ to install a package: #!py + def run(): - ''' + """ Install version 1.5-1.el7 of package "python-foo" - ''' + """ return { - 'include': ['python'], - 'python-foo': { - 'pkg.installed': [ - {'version': '1.5-1.el7'}, - ] - } + "include": ["python"], + "python-foo": {"pkg.installed": [{"version": "1.5-1.el7"},]}, } This would be equivalent to the following: @@ -185,7 +182,8 @@ strings or file-like objects as input. For example: import mycoolmodule from salt.ext import six - def render(data, saltenv='base', sls='', **kwargs): + + def render(data, saltenv="base", sls="", **kwargs): if not isinstance(data, six.string_types): # Read from file-like object data = data.read() @@ -227,7 +225,8 @@ Here is a simple YAML renderer example: from salt.utils.yamlloader import SaltYamlSafeLoader from salt.ext import six - def render(yaml_data, saltenv='', sls='', **kws): + + def render(yaml_data, saltenv="", sls="", **kws): if not isinstance(yaml_data, six.string_types): yaml_data = yaml_data.read() data = salt.utils.yaml.safe_load(yaml_data) diff --git a/doc/ref/returners/index.rst b/doc/ref/returners/index.rst index 10469df2462..16dd595683e 100644 --- a/doc/ref/returners/index.rst +++ b/doc/ref/returners/index.rst @@ -74,19 +74,17 @@ Other optional functions can be included to add support for import redis import salt.utils.json + def returner(ret): - ''' + """ Return information to a redis server - ''' + """ # Get a redis connection - serv = redis.Redis( - host='redis-serv.example.com', - port=6379, - db='0') - serv.sadd("%(id)s:jobs" % ret, ret['jid']) - serv.set("%(jid)s:%(id)s" % ret, salt.utils.json.dumps(ret['return'])) - serv.sadd('jobs', ret['jid']) - serv.sadd(ret['jid'], ret['id']) + serv = redis.Redis(host="redis-serv.example.com", port=6379, db="0") + serv.sadd("%(id)s:jobs" % ret, ret["jid"]) + serv.set("%(jid)s:%(id)s" % ret, salt.utils.json.dumps(ret["return"])) + serv.sadd("jobs", ret["jid"]) + serv.sadd(ret["jid"], ret["id"]) The above example of a returner set to send the data to a Redis server serializes the data as JSON and sets it in redis. @@ -120,11 +118,13 @@ loaded as simply ``redis``: try: import redis + HAS_REDIS = True except ImportError: HAS_REDIS = False - __virtualname__ = 'redis' + __virtualname__ = "redis" + def __virtual__(): if not HAS_REDIS: @@ -154,9 +154,9 @@ must implement the following functions: .. code-block:: python def prep_jid(nocache, passed_jid=None): # pylint: disable=unused-argument - ''' + """ Do any work necessary to prepare a JID, including sending a custom id - ''' + """ return passed_jid if passed_jid is not None else salt.utils.jid.gen_jid() ``save_load`` @@ -171,26 +171,27 @@ must implement the following functions: import salt.utils.json + def save_load(jid, load, minions=None): - ''' + """ Save the load to the specified jid id - ''' - query = '''INSERT INTO salt.jids ( + """ + query = """INSERT INTO salt.jids ( jid, load ) VALUES ( '{0}', '{1}' - );'''.format(jid, salt.utils.json.dumps(load)) + );""".format( + jid, salt.utils.json.dumps(load) + ) # cassandra_cql.cql_query may raise a CommandExecutionError try: - __salt__['cassandra_cql.cql_query'](query) + __salt__["cassandra_cql.cql_query"](query) except CommandExecutionError: - log.critical('Could not save load in jids table.') + log.critical("Could not save load in jids table.") raise except Exception as e: - log.critical( - 'Unexpected error while inserting into jids: {0}'.format(e) - ) + log.critical("Unexpected error while inserting into jids: {0}".format(e)) raise @@ -201,26 +202,30 @@ must implement the following functions: .. code-block:: python def get_load(jid): - ''' + """ Return the load data that marks a specified jid - ''' - query = '''SELECT load FROM salt.jids WHERE jid = '{0}';'''.format(jid) + """ + query = """SELECT load FROM salt.jids WHERE jid = '{0}';""".format(jid) ret = {} # cassandra_cql.cql_query may raise a CommandExecutionError try: - data = __salt__['cassandra_cql.cql_query'](query) + data = __salt__["cassandra_cql.cql_query"](query) if data: - load = data[0].get('load') + load = data[0].get("load") if load: ret = json.loads(load) except CommandExecutionError: - log.critical('Could not get load from jids table.') + log.critical("Could not get load from jids table.") raise except Exception as e: - log.critical('''Unexpected error while getting load from - jids: {0}'''.format(str(e))) + log.critical( + """Unexpected error while getting load from + jids: {0}""".format( + str(e) + ) + ) raise return ret @@ -322,20 +327,21 @@ contains the jid and therefore is guaranteed to be unique. import salt.utils.json - def event_return(events): - ''' - Return event to mysql server - Requires that configuration be enabled via 'event_return' - option in master config. - ''' - with _get_serv(events, commit=True) as cur: - for event in events: - tag = event.get('tag', '') - data = event.get('data', '') - sql = '''INSERT INTO `salt_events` (`tag`, `data`, `master_id` ) - VALUES (%s, %s, %s)''' - cur.execute(sql, (tag, salt.utils.json.dumps(data), __opts__['id'])) + def event_return(events): + """ + Return event to mysql server + + Requires that configuration be enabled via 'event_return' + option in master config. + """ + with _get_serv(events, commit=True) as cur: + for event in events: + tag = event.get("tag", "") + data = event.get("data", "") + sql = """INSERT INTO `salt_events` (`tag`, `data`, `master_id` ) + VALUES (%s, %s, %s)""" + cur.execute(sql, (tag, salt.utils.json.dumps(data), __opts__["id"])) Testing the Returner diff --git a/doc/ref/runners/index.rst b/doc/ref/runners/index.rst index 92f07c26737..5eedd3dc530 100644 --- a/doc/ref/runners/index.rst +++ b/doc/ref/runners/index.rst @@ -36,7 +36,7 @@ fired onto the master event bus where. For example: .. code-block:: python def a_runner(outputter=None, display_progress=False): - print('Hello world') + print("Hello world") ... The above would result in an event fired as follows: @@ -62,7 +62,7 @@ A custom runner may send its own progress event by using the .. code-block:: python if display_progress: - __jid_event__.fire_event({'message': 'A progress message'}, 'progress') + __jid_event__.fire_event({"message": "A progress message"}, "progress") The above would produce output on the console reading: ``A progress message`` as well as an event on the event similar to: @@ -117,11 +117,12 @@ responding to Salt calls could look like this: # Import salt modules import salt.client + def up(): - ''' + """ Print a list of all of the minions that are up - ''' - client = salt.client.LocalClient(__opts__['conf_file']) - minions = client.cmd('*', 'test.version', timeout=1) + """ + client = salt.client.LocalClient(__opts__["conf_file"]) + minions = client.cmd("*", "test.version", timeout=1) for minion in sorted(minions): print minion diff --git a/doc/ref/states/aggregate.rst b/doc/ref/states/aggregate.rst index ce25507a1ca..5e25dda8fce 100644 --- a/doc/ref/states/aggregate.rst +++ b/doc/ref/states/aggregate.rst @@ -102,48 +102,48 @@ This example, simplified from the pkg state, shows how to create mod_aggregate f .. code-block:: python def mod_aggregate(low, chunks, running): - ''' + """ The mod_aggregate function which looks up all packages in the available low chunks and merges them into a single pkgs ref in the present low data - ''' + """ pkgs = [] # What functions should we aggregate? agg_enabled = [ - 'installed', - 'latest', - 'removed', - 'purged', - ] + "installed", + "latest", + "removed", + "purged", + ] # The `low` data is just a dict with the state, function (fun) and # arguments passed in from the sls - if low.get('fun') not in agg_enabled: + if low.get("fun") not in agg_enabled: return low # Now look into what other things are set to execute for chunk in chunks: # The state runtime uses "tags" to track completed jobs, it may # look familiar with the _|- - tag = __utils__['state.gen_tag'](chunk) + tag = __utils__["state.gen_tag"](chunk) if tag in running: # Already ran the pkg state, skip aggregation continue - if chunk.get('state') == 'pkg': - if '__agg__' in chunk: + if chunk.get("state") == "pkg": + if "__agg__" in chunk: continue # Check for the same function - if chunk.get('fun') != low.get('fun'): + if chunk.get("fun") != low.get("fun"): continue # Pull out the pkg names! - if 'pkgs' in chunk: - pkgs.extend(chunk['pkgs']) - chunk['__agg__'] = True - elif 'name' in chunk: - pkgs.append(chunk['name']) - chunk['__agg__'] = True + if "pkgs" in chunk: + pkgs.extend(chunk["pkgs"]) + chunk["__agg__"] = True + elif "name" in chunk: + pkgs.append(chunk["name"]) + chunk["__agg__"] = True if pkgs: - if 'pkgs' in low: - low['pkgs'].extend(pkgs) + if "pkgs" in low: + low["pkgs"].extend(pkgs) else: - low['pkgs'] = pkgs + low["pkgs"] = pkgs # The low has been modified and needs to be returned to the state # runtime for execution return low diff --git a/doc/ref/states/writing.rst b/doc/ref/states/writing.rst index effdb42ca23..c28ff61b08c 100644 --- a/doc/ref/states/writing.rst +++ b/doc/ref/states/writing.rst @@ -66,13 +66,10 @@ A well-written state function will follow these steps: .. code-block:: python - ret = {'name': name, - 'result': False, - 'changes': {}, - 'comment': ''} + ret = {"name": name, "result": False, "changes": {}, "comment": ""} if foo and bar: - ret['comment'] = 'Only one of foo and bar is permitted' + ret["comment"] = "Only one of foo and bar is permitted" return ret 2. Check if changes need to be made. This is best done with an @@ -83,7 +80,7 @@ A well-written state function will follow these steps: .. code-block:: python - result = __salt__['modname.check'](name) + result = __salt__["modname.check"](name) 3. If step 2 found that the minion is already in the desired state, then exit immediately with a ``True`` result and without making any changes. @@ -91,8 +88,8 @@ A well-written state function will follow these steps: .. code-block:: python if result: - ret['result'] = True - ret['comment'] = '{0} is already installed'.format(name) + ret["result"] = True + ret["comment"] = "{0} is already installed".format(name) return ret 4. If step 2 found that changes *do* need to be made, then check to see if the @@ -102,10 +99,10 @@ A well-written state function will follow these steps: .. code-block:: python - if __opts__['test']: - ret['result'] = None - ret['comment'] = '{0} would be installed'.format(name) - ret['changes'] = result + if __opts__["test"]: + ret["result"] = None + ret["comment"] = "{0} would be installed".format(name) + ret["changes"] = result return ret 5. Make the desired changes. This should again be done using a function from an @@ -115,7 +112,7 @@ A well-written state function will follow these steps: .. code-block:: python - result = __salt__['modname.install'](name) + result = __salt__["modname.install"](name) 6. Perform the same check from step 2 again to confirm whether or not the minion is in the desired state. Just as in step 2, this function should be @@ -123,7 +120,7 @@ A well-written state function will follow these steps: .. code-block:: python - ret['changes'] = __salt__['modname.check'](name) + ret["changes"] = __salt__["modname.check"](name) As you can see here, we are setting the ``changes`` key in the return dictionary to the result of the ``modname.check`` function (just as we did @@ -135,11 +132,11 @@ A well-written state function will follow these steps: .. code-block:: python - if ret['changes']: - ret['comment'] = '{0} failed to install'.format(name) + if ret["changes"]: + ret["comment"] = "{0} failed to install".format(name) else: - ret['result'] = True - ret['comment'] = '{0} was installed'.format(name) + ret["result"] = True + ret["comment"] = "{0} was installed".format(name) return ret @@ -202,7 +199,7 @@ Salt state modules can be cross-called by accessing the value in the .. code-block:: python - ret = __states__['file.managed'](name='/tmp/myfile', source='salt://myfile') + ret = __states__["file.managed"](name="/tmp/myfile", source="salt://myfile") This code will call the `managed` function in the :mod:`file ` state module and pass the arguments ``name`` and ``source`` @@ -225,8 +222,7 @@ A State Module must return a dict containing the following keys/values: .. code-block:: python - ret['changes'].update({'my_pkg_name': {'old': '', - 'new': 'my_pkg_name-1.0'}}) + ret["changes"].update({"my_pkg_name": {"old": "", "new": "my_pkg_name-1.0"}}) - **result:** A tristate value. ``True`` if the action was successful, @@ -273,9 +269,9 @@ run. An example of such a check could look like this: .. code-block:: python # Return comment of changes if test. - if __opts__['test']: - ret['result'] = None - ret['comment'] = 'State Foo will execute with param {0}'.format(bar) + if __opts__["test"]: + ret["result"] = None + ret["comment"] = "State Foo will execute with param {0}".format(bar) return ret Make sure to test and return before performing any real actions on the minion. @@ -337,13 +333,13 @@ A good example of the mod_init function is found in the pkg state module: .. code-block:: python def mod_init(low): - ''' + """ Refresh the package database here so that it only needs to happen once - ''' - if low['fun'] == 'installed' or low['fun'] == 'latest': + """ + if low["fun"] == "installed" or low["fun"] == "latest": rtag = __gen_rtag() if not os.path.exists(rtag): - open(rtag, 'w+').write('') + open(rtag, "w+").write("") return True else: return False @@ -368,9 +364,9 @@ logs. The following code snippet demonstrates writing log messages: log = logging.getLogger(__name__) - log.info('Here is Some Information') - log.warning('You Should Not Do That') - log.error('It Is Busted') + log.info("Here is Some Information") + log.warning("You Should Not Do That") + log.error("It Is Busted") Strings and Unicode @@ -424,8 +420,9 @@ Example state module import salt.exceptions + def enforce_custom_thing(name, foo, bar=True): - ''' + """ Enforce the state of a custom thing This state module does a custom thing. It calls out to the execution module @@ -438,52 +435,53 @@ Example state module A required argument bar : True An argument with a default value - ''' + """ ret = { - 'name': name, - 'changes': {}, - 'result': False, - 'comment': '', - } + "name": name, + "changes": {}, + "result": False, + "comment": "", + } # Start with basic error-checking. Do all the passed parameters make sense # and agree with each-other? - if bar == True and foo.startswith('Foo'): + if bar == True and foo.startswith("Foo"): raise salt.exceptions.SaltInvocationError( - 'Argument "foo" cannot start with "Foo" if argument "bar" is True.') + 'Argument "foo" cannot start with "Foo" if argument "bar" is True.' + ) # Check the current state of the system. Does anything need to change? - current_state = __salt__['my_custom_module.current_state'](name) + current_state = __salt__["my_custom_module.current_state"](name) if current_state == foo: - ret['result'] = True - ret['comment'] = 'System already in the correct state' + ret["result"] = True + ret["comment"] = "System already in the correct state" return ret # The state of the system does need to be changed. Check if we're running # in ``test=true`` mode. - if __opts__['test'] == True: - ret['comment'] = 'The state of "{0}" will be changed.'.format(name) - ret['changes'] = { - 'old': current_state, - 'new': 'Description, diff, whatever of the new state', + if __opts__["test"] == True: + ret["comment"] = 'The state of "{0}" will be changed.'.format(name) + ret["changes"] = { + "old": current_state, + "new": "Description, diff, whatever of the new state", } # Return ``None`` when running with ``test=true``. - ret['result'] = None + ret["result"] = None return ret # Finally, make the actual change and return the result. - new_state = __salt__['my_custom_module.change_state'](name, foo) + new_state = __salt__["my_custom_module.change_state"](name, foo) - ret['comment'] = 'The state of "{0}" was changed!'.format(name) + ret["comment"] = 'The state of "{0}" was changed!'.format(name) - ret['changes'] = { - 'old': current_state, - 'new': new_state, + ret["changes"] = { + "old": current_state, + "new": new_state, } - ret['result'] = True + ret["result"] = True return ret diff --git a/doc/topics/beacons/index.rst b/doc/topics/beacons/index.rst index 1a6b79224fc..0c896bff416 100644 --- a/doc/topics/beacons/index.rst +++ b/doc/topics/beacons/index.rst @@ -360,8 +360,7 @@ The return data structure would look something like this: .. code-block:: python - [{'changes': ['/foo/bar'], 'tag': 'foo'}, - {'changes': ['/foo/baz'], 'tag': 'bar'}] + [{"changes": ["/foo/bar"], "tag": "foo"}, {"changes": ["/foo/baz"], "tag": "bar"}] Calling Execution Modules ------------------------- diff --git a/doc/topics/cloud/cloud.rst b/doc/topics/cloud/cloud.rst index 30cd17963f4..ffebf995973 100644 --- a/doc/topics/cloud/cloud.rst +++ b/doc/topics/cloud/cloud.rst @@ -145,7 +145,7 @@ library. The following two lines set up the imports: .. code-block:: python - from salt.cloud.libcloudfuncs import * # pylint: disable=W0614,W0401 + from salt.cloud.libcloudfuncs import * # pylint: disable=W0614,W0401 import salt.utils.functools And then a series of declarations will make the necessary functions available @@ -162,7 +162,9 @@ within the cloud module. destroy = salt.utils.functools.namespaced_function(destroy, globals()) list_nodes = salt.utils.functools.namespaced_function(list_nodes, globals()) list_nodes_full = salt.utils.functools.namespaced_function(list_nodes_full, globals()) - list_nodes_select = salt.utils.functools.namespaced_function(list_nodes_select, globals()) + list_nodes_select = salt.utils.functools.namespaced_function( + list_nodes_select, globals() + ) show_instance = salt.utils.functools.namespaced_function(show_instance, globals()) If necessary, these functions may be replaced by removing the appropriate @@ -300,11 +302,11 @@ general, the following code can be used as-is: .. code-block:: python def list_nodes_select(call=None): - ''' + """ Return a list of the VMs that are on the provider, with select fields - ''' + """ return salt.utils.cloud.list_nodes_select( - list_nodes_full('function'), __opts__['query.selection'], call, + list_nodes_full("function"), __opts__["query.selection"], call, ) However, depending on the cloud provider, additional variables may be required. @@ -315,16 +317,14 @@ appropriately: .. code-block:: python def list_nodes_select(conn=None, call=None): - ''' + """ Return a list of the VMs that are on the provider, with select fields - ''' + """ if not conn: - conn = get_conn() # pylint: disable=E0602 + conn = get_conn() # pylint: disable=E0602 return salt.utils.cloud.list_nodes_select( - list_nodes_full(conn, 'function'), - __opts__['query.selection'], - call, + list_nodes_full(conn, "function"), __opts__["query.selection"], call, ) This function is normally called with the ``-S`` option: @@ -372,15 +372,15 @@ useful information to the user. A basic action looks like: .. code-block:: python def show_instance(name, call=None): - ''' - Show the details from EC2 concerning an AMI - ''' - if call != 'action': - raise SaltCloudSystemExit( - 'The show_instance action must be called with -a or --action.' - ) + """ + Show the details from EC2 concerning an AMI + """ + if call != "action": + raise SaltCloudSystemExit( + "The show_instance action must be called with -a or --action." + ) - return _get_node(name) + return _get_node(name) Please note that generic kwargs, if used, are passed through to actions as ``kwargs`` and not ``**kwargs``. An example of this is seen in the Functions @@ -406,16 +406,15 @@ useful information to the user. A basic function looks like: .. code-block:: python def show_image(kwargs, call=None): - ''' + """ Show the details from EC2 concerning an AMI - ''' - if call != 'function': + """ + if call != "function": raise SaltCloudSystemExit( - 'The show_image action must be called with -f or --function.' + "The show_image action must be called with -f or --function." ) - params = {'ImageId.1': kwargs['image'], - 'Action': 'DescribeImages'} + params = {"ImageId.1": kwargs["image"], "Action": "DescribeImages"} result = query(params) log.info(result) diff --git a/doc/topics/cloud/config.rst b/doc/topics/cloud/config.rst index 23df63496cc..828540e3b7c 100644 --- a/doc/topics/cloud/config.rst +++ b/doc/topics/cloud/config.rst @@ -572,33 +572,43 @@ data: .. code-block:: python - [{'deploy': False, - 'image': 'ami-08d97e61', - 'profile': 'Fedora-17', - 'provider': 'my-ec2-config', - 'securitygroup': ['default'], - 'size': 't1.micro', - 'ssh_username': 'ec2_user'}, - {'deploy': False, - 'image': 'ami-09b61d60', - 'profile': 'CentOS-5', - 'provider': 'my-aws-config', - 'securitygroup': ['default'], - 'size': 't1.micro', - 'ssh_username': 'ec2_user'}, - {'deploy': False, - 'image': 'ami-54cf5c3d', - 'profile': 'Amazon-Linux-AMI-2012.09-64bit', - 'provider': 'my-ec2-config', - 'securitygroup': ['default'], - 'size': 't1.micro', - 'ssh_username': 'ec2_user'}, - {'deploy': False, - 'profile': 'development-instances', - 'provider': 'my-ec2-config', - 'securitygroup': ['default'], - 'size': 't1.micro', - 'ssh_username': 'ec2_user'}] + [ + { + "deploy": False, + "image": "ami-08d97e61", + "profile": "Fedora-17", + "provider": "my-ec2-config", + "securitygroup": ["default"], + "size": "t1.micro", + "ssh_username": "ec2_user", + }, + { + "deploy": False, + "image": "ami-09b61d60", + "profile": "CentOS-5", + "provider": "my-aws-config", + "securitygroup": ["default"], + "size": "t1.micro", + "ssh_username": "ec2_user", + }, + { + "deploy": False, + "image": "ami-54cf5c3d", + "profile": "Amazon-Linux-AMI-2012.09-64bit", + "provider": "my-ec2-config", + "securitygroup": ["default"], + "size": "t1.micro", + "ssh_username": "ec2_user", + }, + { + "deploy": False, + "profile": "development-instances", + "provider": "my-ec2-config", + "securitygroup": ["default"], + "size": "t1.micro", + "ssh_username": "ec2_user", + }, + ] Pretty cool right? @@ -642,33 +652,36 @@ data: .. code-block:: python - 'providers': { - 'my-develop-envs': [ - {'availability_zone': 'ap-southeast-1b', - 'id': 'HJGRYCILJLKJYG', - 'key': 'kdjgfsgm;woormgl/aserigjksjdhasdfgn', - 'keyname': 'test', - 'location': 'ap-southeast-1', - 'private_key': '/root/test.pem', - 'driver': 'aws', - 'securitygroup': 'quick-start' + "providers": { + "my-develop-envs": [ + { + "availability_zone": "ap-southeast-1b", + "id": "HJGRYCILJLKJYG", + "key": "kdjgfsgm;woormgl/aserigjksjdhasdfgn", + "keyname": "test", + "location": "ap-southeast-1", + "private_key": "/root/test.pem", + "driver": "aws", + "securitygroup": "quick-start", }, - {'location': 'Raleigh', - 'password': 'mypass', - 'driver': 'ibmsce', - 'ssh_key_file': '/etc/salt/ibm/mykey.pem', - 'ssh_key_name': 'mykey', - 'user': 'myuser@mycorp.com' + { + "location": "Raleigh", + "password": "mypass", + "driver": "ibmsce", + "ssh_key_file": "/etc/salt/ibm/mykey.pem", + "ssh_key_name": "mykey", + "user": "myuser@mycorp.com", + }, + ], + "my-productions-envs": [ + { + "availability_zone": "us-east-1", + "location": "us-east-1", + "password": "mypass", + "driver": "ibmsce", + "ssh_key_file": "/etc/salt/ibm/mykey.pem", + "ssh_key_name": "mykey", + "user": "my-production-user@mycorp.com", } ], - 'my-productions-envs': [ - {'availability_zone': 'us-east-1', - 'location': 'us-east-1', - 'password': 'mypass', - 'driver': 'ibmsce', - 'ssh_key_file': '/etc/salt/ibm/mykey.pem', - 'ssh_key_name': 'mykey', - 'user': 'my-production-user@mycorp.com' - } - ] } diff --git a/doc/topics/cloud/reactor.rst b/doc/topics/cloud/reactor.rst index 22b415db5fc..ad81bad49cf 100644 --- a/doc/topics/cloud/reactor.rst +++ b/doc/topics/cloud/reactor.rst @@ -32,9 +32,7 @@ using the ``ec2-config`` provider, the payload for this tag would look like: .. code-block:: python - {'name': 'web1', - 'profile': 'ec2-centos', - 'provider': 'ec2-config:ec2'} + {"name": "web1", "profile": "ec2-centos", "provider": "ec2-config:ec2"} Available Events ================ diff --git a/doc/topics/cloud/salt.rst b/doc/topics/cloud/salt.rst index c10e19c1ee3..15499cc59a9 100644 --- a/doc/topics/cloud/salt.rst +++ b/doc/topics/cloud/salt.rst @@ -309,7 +309,8 @@ the master or a minion), create a client object and issue a command against it: import salt.cloud import pprint - client = salt.cloud.CloudClient('/etc/salt/cloud') + + client = salt.cloud.CloudClient("/etc/salt/cloud") nodes = client.query() pprint.pprint(nodes) diff --git a/doc/topics/development/conventions/documentation.rst b/doc/topics/development/conventions/documentation.rst index 70abab28086..06929039048 100644 --- a/doc/topics/development/conventions/documentation.rst +++ b/doc/topics/development/conventions/documentation.rst @@ -97,7 +97,7 @@ code and can contain special formatting. For example: .. code-block:: python def my_function(value): - ''' + """ Upper-case the given value Usage: @@ -110,7 +110,7 @@ code and can contain special formatting. For example: :param value: a string :return: a copy of ``value`` that has been upper-cased - ''' + """ return value.upper() Specify a release for additions or changes @@ -122,13 +122,13 @@ denotes what Salt release will be affected. For example: .. code-block:: python def my_function(value): - ''' + """ Upper-case the given value .. versionadded:: 2014.7.0 <...snip...> - ''' + """ return value.upper() For changes to a function: @@ -136,14 +136,14 @@ For changes to a function: .. code-block:: python def my_function(value, strip=False): - ''' + """ Upper-case the given value .. versionchanged:: 2016.3.0 Added a flag to also strip whitespace from the string. <...snip...> - ''' + """ if strip: return value.upper().strip() return value.upper() diff --git a/doc/topics/development/conventions/formulas.rst b/doc/topics/development/conventions/formulas.rst index 8ab5ce61b48..e86608acae8 100644 --- a/doc/topics/development/conventions/formulas.rst +++ b/doc/topics/development/conventions/formulas.rst @@ -642,32 +642,29 @@ example is a state tree of two sls files, one simple and one complicated. # This example has the minion id in the form 'web-03-dev'. # Easily access the grains dictionary: try: - app, instance_number, environment = __grains__['id'].split('-') + app, instance_number, environment = __grains__["id"].split("-") instance_number = int(instance_number) except ValueError: - app, instance_number, environment = ['Unknown', 0, 'dev'] + app, instance_number, environment = ["Unknown", 0, "dev"] list_of_roles.add(app) - if app == 'web' and environment == 'dev': - list_of_roles.add('primary') - list_of_roles.add('secondary') - elif app == 'web' and environment == 'staging': + if app == "web" and environment == "dev": + list_of_roles.add("primary") + list_of_roles.add("secondary") + elif app == "web" and environment == "staging": if instance_number == 0: - list_of_roles.add('primary') + list_of_roles.add("primary") else: - list_of_roles.add('secondary') + list_of_roles.add("secondary") # Easily cross-call Salt execution modules: - if __salt__['myutils.query_valid_ec2_instance'](): - list_of_roles.add('is_ec2_instance') + if __salt__["myutils.query_valid_ec2_instance"](): + list_of_roles.add("is_ec2_instance") return { - 'set_roles_grains': { - 'grains.present': [ - {'name': 'roles'}, - {'value': list(list_of_roles)}, - ], + "set_roles_grains": { + "grains.present": [{"name": "roles"}, {"value": list(list_of_roles)},], }, } diff --git a/doc/topics/development/conventions/style.rst b/doc/topics/development/conventions/style.rst index dd911ba93fd..0654b612f37 100644 --- a/doc/topics/development/conventions/style.rst +++ b/doc/topics/development/conventions/style.rst @@ -68,8 +68,8 @@ All strings which require formatting should use the `.format` string method: .. code-block:: python - data = 'some text' - more = '{0} and then some'.format(data) + data = "some text" + more = "{0} and then some".format(data) Make sure to use indices or identifiers in the format brackets, since empty brackets are not supported by python 2.6. @@ -84,15 +84,15 @@ When adding a new function or state, where possible try to use a .. code-block:: python - def new_func(msg=''): - ''' + def new_func(msg=""): + """ .. versionadded:: 0.16.0 Prints what was passed to the function. msg : None The string to be printed. - ''' + """ print(msg) If you are uncertain what version should be used, either consult a core @@ -109,8 +109,8 @@ significantly, the ``versionchanged`` directive can be used to clarify this: .. code-block:: python - def new_func(msg='', signature=''): - ''' + def new_func(msg="", signature=""): + """ .. versionadded:: 0.16.0 Prints what was passed to the function. @@ -124,8 +124,8 @@ significantly, the ``versionchanged`` directive can be used to clarify this: An optional signature. .. versionadded 0.17.0 - ''' - print('Greetings! {0}\n\n{1}'.format(msg, signature)) + """ + print("Greetings! {0}\n\n{1}".format(msg, signature)) Dictionaries @@ -154,8 +154,9 @@ To say this more directly with an example, this is `GOOD`: import os + def minion_path(): - path = os.path.join(self.opts['cachedir'], 'minions') + path = os.path.join(self.opts["cachedir"], "minions") return path This on the other hand is `DISCOURAGED`: @@ -164,8 +165,9 @@ This on the other hand is `DISCOURAGED`: from os.path import join + def minion_path(): - path = join(self.opts['cachedir'], 'minions') + path = join(self.opts["cachedir"], "minions") return path The time when this is changed is for importing exceptions, generally directly diff --git a/doc/topics/development/deprecations.rst b/doc/topics/development/deprecations.rst index 2b555124ab8..918951c63c4 100644 --- a/doc/topics/development/deprecations.rst +++ b/doc/topics/development/deprecations.rst @@ -45,10 +45,10 @@ Consider the following example: def some_function(bar=False, foo=None): if foo is not None: salt.utils.versions.warn_until( - 'Aluminum', - 'The \'foo\' argument has been deprecated and its ' - 'functionality removed, as such, its usage is no longer ' - 'required.' + "Aluminum", + "The 'foo' argument has been deprecated and its " + "functionality removed, as such, its usage is no longer " + "required.", ) Development begins on the ``Aluminum`` release when the ``Magnesium`` branch is diff --git a/doc/topics/development/extend/index.rst b/doc/topics/development/extend/index.rst index 349e833ba42..7a581af95cd 100644 --- a/doc/topics/development/extend/index.rst +++ b/doc/topics/development/extend/index.rst @@ -79,8 +79,8 @@ Example file in the template directory .. code-block:: python - print('Hello {{module_name}}') - __virtual__ = '{{__virtual_name__}}' + print("Hello {{module_name}}") + __virtual__ = "{{__virtual_name__}}" Default context properties ************************** diff --git a/doc/topics/development/modules/developing.rst b/doc/topics/development/modules/developing.rst index 127a8cf7504..f6c1594848f 100644 --- a/doc/topics/development/modules/developing.rst +++ b/doc/topics/development/modules/developing.rst @@ -30,8 +30,10 @@ the debugger should be started: .. code-block:: python - test = 'test123' - import IPython; IPython.embed_kernel() + test = "test123" + import IPython + + IPython.embed_kernel() After running a Salt command that hits that line, the following will show up in the log file: @@ -146,8 +148,8 @@ functions to be called as they have been set up by the salt loader. .. code-block:: python - __salt__['cmd.run']('fdisk -l') - __salt__['network.ip_addrs']() + __salt__["cmd.run"]("fdisk -l") + __salt__["network.ip_addrs"]() .. note:: @@ -205,8 +207,8 @@ each file. Here is an example from salt/modules/cp.py: .. code-block:: python - if not 'cp.fileclient' in __context__: - __context__['cp.fileclient'] = salt.fileclient.get_file_client(__opts__) + if not "cp.fileclient" in __context__: + __context__["cp.fileclient"] = salt.fileclient.get_file_client(__opts__) .. note:: Because __context__ may or may not have been destroyed, always be diff --git a/doc/topics/development/modules/external_pillars.rst b/doc/topics/development/modules/external_pillars.rst index c34ae5abe54..0eb4989c15b 100644 --- a/doc/topics/development/modules/external_pillars.rst +++ b/doc/topics/development/modules/external_pillars.rst @@ -65,6 +65,7 @@ import errors and set a flag that the ``__virtual__`` function can use later. try: import weird_thing + EXAMPLE_A_LOADED = True except ImportError: EXAMPLE_A_LOADED = False @@ -80,7 +81,7 @@ things ``modulename.option``. .. code-block:: python - __opts__ = { 'example_a.someconfig': 137 } + __opts__ = {"example_a.someconfig": 137} Initialization @@ -91,8 +92,9 @@ signature: .. code-block:: python - def __init__( __opts__ ): + def __init__(__opts__): # Do init work here + ... **Note**: The ``__init__`` function is ran every time a particular minion causes @@ -127,7 +129,8 @@ installed. .. code-block:: python # This external pillar will be known as `something_else` - __virtualname__ = 'something_else' + __virtualname__ = "something_else" + def __virtual__(): if EXAMPLE_A_LOADED: @@ -151,9 +154,9 @@ Using our example above: .. code-block:: python - ext_pillar( id, pillar, 'some argument' ) # example_a - ext_pillar( id, pillar, 'argumentA', 'argumentB' ) # example_b - ext_pillar( id, pillar, keyA='valueA', keyB='valueB' ) # example_c + ext_pillar(id, pillar, "some argument") # example_a + ext_pillar(id, pillar, "argumentA", "argumentB") # example_b + ext_pillar(id, pillar, keyA="valueA", keyB="valueB") # example_c In the ``example_a`` case, ``pillar`` will contain the items from the @@ -168,11 +171,11 @@ is called once for each minion that fetches its pillar data. .. code-block:: python - def ext_pillar( minion_id, pillar, *args, **kwargs ): + def ext_pillar(minion_id, pillar, *args, **kwargs): - my_pillar = {'external_pillar': {}} + my_pillar = {"external_pillar": {}} - my_pillar['external_pillar'] = get_external_pillar_dictionary() + my_pillar["external_pillar"] = get_external_pillar_dictionary() return my_pillar diff --git a/doc/topics/development/modules/index.rst b/doc/topics/development/modules/index.rst index 7b9918c00bc..3fc59f9d0b2 100644 --- a/doc/topics/development/modules/index.rst +++ b/doc/topics/development/modules/index.rst @@ -101,11 +101,7 @@ This is done via setuptools entry points: setup( # ... - entry_points={ - 'salt.loader': [ - 'module_dirs=spirofs.loader:module', - ], - }, + entry_points={"salt.loader": ["module_dirs=spirofs.loader:module"]}, # ... ) diff --git a/doc/topics/development/package_providers.rst b/doc/topics/development/package_providers.rst index fb71918df6e..12a931aaad1 100644 --- a/doc/topics/development/package_providers.rst +++ b/doc/topics/development/package_providers.rst @@ -23,7 +23,7 @@ so: .. code-block:: python - __salt__['pkg_resource.add_pkg'](ret, name, version) + __salt__["pkg_resource.add_pkg"](ret, name, version) The last thing that should be done before returning is to execute :mod:`pkg_resource.sort_pkglist `. This @@ -32,7 +32,7 @@ future versions of Salt. .. code-block:: python - __salt__['pkg_resource.sort_pkglist'](ret) + __salt__["pkg_resource.sort_pkglist"](ret) ``list_pkgs`` returns a dictionary of installed packages, with the keys being @@ -41,8 +41,7 @@ data: .. code-block:: python - {'foo': '1.2.3-4', - 'bar': '5.6.7-8'} + {"foo": "1.2.3-4", "bar": "5.6.7-8"} latest_version @@ -83,7 +82,7 @@ Deprecated and destined to be removed. For now, should just do the following: .. code-block:: python - return __salt__['pkg.latest_version'](name) != '' + return __salt__["pkg.latest_version"](name) != "" install @@ -106,9 +105,7 @@ system. .. code-block:: python - pkg_params, pkg_type = __salt__['pkg_resource.parse_targets'](name, - pkgs, - sources) + pkg_params, pkg_type = __salt__["pkg_resource.parse_targets"](name, pkgs, sources) Two values will be returned to the :strong:`install` function. The first of them will be a dictionary. The keys of this dictionary will be package names, @@ -164,8 +161,8 @@ changed. .. code-block:: python - basedir = '/etc/yum.repos.d' - __salt__['pkg.list_repos'](basedir) + basedir = "/etc/yum.repos.d" + __salt__["pkg.list_repos"](basedir) list_repos ^^^^^^^^^^ @@ -173,7 +170,7 @@ Lists the repositories that are currently configured on this system. .. code-block:: python - __salt__['pkg.list_repos']() + __salt__["pkg.list_repos"]() Returns a dictionary, in the following format: @@ -190,7 +187,7 @@ Displays all local configuration for a specific repository. .. code-block:: python - __salt__['pkg.get_repo'](repo='myrepo') + __salt__["pkg.get_repo"](repo="myrepo") The information is formatted in much the same way as list_repos, but is specific to only one repo. @@ -211,7 +208,7 @@ success. .. code-block:: python - __salt__['pkg.del_repo'](repo='myrepo') + __salt__["pkg.del_repo"](repo="myrepo") mod_repo ^^^^^^^^ @@ -224,7 +221,7 @@ refer to the documentation for your specific repo manager for specifics. .. code-block:: python - __salt__['pkg.mod_repo'](repo='myrepo', url='http://myurl.com/repo') + __salt__["pkg.mod_repo"](repo="myrepo", url="http://myurl.com/repo") Low-Package Functions @@ -251,14 +248,13 @@ packages will be listed. .. code-block:: python - installed = __salt__['lowpkg.list_pkgs']('foo', 'bar') + installed = __salt__["lowpkg.list_pkgs"]("foo", "bar") Example output: .. code-block:: python - {'foo': '1.2.3-4', - 'bar': '5.6.7-8'} + {"foo": "1.2.3-4", "bar": "5.6.7-8"} verify ^^^^^^ @@ -269,14 +265,18 @@ included. .. code-block:: python - installed = __salt__['lowpkg.verify']('httpd') + installed = __salt__["lowpkg.verify"]("httpd") Example output: .. code-block:: python - {'/etc/httpd/conf/httpd.conf': {'mismatch': ['size', 'md5sum', 'mtime'], - 'type': 'config'}} + { + "/etc/httpd/conf/httpd.conf": { + "mismatch": ["size", "md5sum", "mtime"], + "type": "config", + } + } file_list ^^^^^^^^^ @@ -285,7 +285,7 @@ specified, then all files for all known packages are returned. .. code-block:: python - installed = __salt__['lowpkg.file_list']('httpd', 'apache') + installed = __salt__["lowpkg.file_list"]("httpd", "apache") This function does not return which files belong to which packages; all files are returned as one giant list (hence the `file_list` function name. However, @@ -294,11 +294,10 @@ any errors to the user in a sane manner. .. code-block:: python - {'errors': ['package apache is not installed'], - 'files': ['/etc/httpd', - '/etc/httpd/conf', - '/etc/httpd/conf.d', - '...SNIP...']} + { + "errors": ["package apache is not installed"], + "files": ["/etc/httpd", "/etc/httpd/conf", "/etc/httpd/conf.d", "...SNIP..."], + } file_dict ^^^^^^^^^ @@ -307,17 +306,21 @@ specified, then all files for all known packages are returned. .. code-block:: python - installed = __salt__['lowpkg.file_dict']('httpd', 'apache', 'kernel') + installed = __salt__["lowpkg.file_dict"]("httpd", "apache", "kernel") Unlike `file_list`, this function will break down which files belong to which packages. It will also return errors in the same manner as `file_list`. .. code-block:: python - {'errors': ['package apache is not installed'], - 'packages': {'httpd': ['/etc/httpd', - '/etc/httpd/conf', - '...SNIP...'], - 'kernel': ['/boot/.vmlinuz-2.6.32-279.el6.x86_64.hmac', - '/boot/System.map-2.6.32-279.el6.x86_64', - '...SNIP...']}} + { + "errors": ["package apache is not installed"], + "packages": { + "httpd": ["/etc/httpd", "/etc/httpd/conf", "...SNIP..."], + "kernel": [ + "/boot/.vmlinuz-2.6.32-279.el6.x86_64.hmac", + "/boot/System.map-2.6.32-279.el6.x86_64", + "...SNIP...", + ], + }, + } diff --git a/doc/topics/development/tests/index.rst b/doc/topics/development/tests/index.rst index 6725ef5e889..76ddab498da 100644 --- a/doc/topics/development/tests/index.rst +++ b/doc/topics/development/tests/index.rst @@ -358,6 +358,7 @@ the actual testing, such as functions containing assertions, must start with .. code-block:: python def test_user_present(self): + ... When functions in test files are not prepended with ``test_``, the function acts as a normal, helper function and is not run as a test by the test suite. diff --git a/doc/topics/development/tests/integration.rst b/doc/topics/development/tests/integration.rst index 79c1eb3a487..4eb2bb9a8a7 100644 --- a/doc/topics/development/tests/integration.rst +++ b/doc/topics/development/tests/integration.rst @@ -89,16 +89,12 @@ kernel is not present, then the test should be skipped. .. code-block:: python def setUp(self): - ''' + """ Sets up test requirements - ''' - os_grain = self.run_function('grains.item', ['kernel']) - if os_grain['kernel'] not in 'Darwin': - self.skipTest( - 'Test not applicable to \'{kernel}\' kernel'.format( - **os_grain - ) - ) + """ + os_grain = self.run_function("grains.item", ["kernel"]) + if os_grain["kernel"] not in "Darwin": + self.skipTest("Test not applicable to '{kernel}' kernel".format(**os_grain)) The ``setUp`` function can be used for many things. The above code snippet is only one example. Another example might be to ensure that a particular setting @@ -272,24 +268,25 @@ Now the workhorse method ``run_function`` can be used to test a module: .. code-block:: python import os - import tests.integration as integration + from tests.support.case import ModuleCase - class TestModuleTest(integration.ModuleCase): - ''' + class TestModuleTest(ModuleCase): + """ Validate the test module - ''' + """ + def test_ping(self): - ''' + """ test.ping - ''' - self.assertTrue(self.run_function('test.ping')) + """ + self.assertTrue(self.run_function("test.ping")) def test_echo(self): - ''' + """ test.echo - ''' - self.assertEqual(self.run_function('test.echo', ['text']), 'text') + """ + self.assertEqual(self.run_function("test.echo", ["text"]), "text") The fist example illustrates the testing master issuing a ``test.ping`` call to a testing minion. The test asserts that the minion returned with a ``True`` @@ -312,26 +309,29 @@ Validating the shell commands can be done via shell tests: import shutil import tempfile - import tests.integration as integration + from tests.support.case import ShellCase - class KeyTest(integration.ShellCase): - ''' + + class KeyTest(ShellCase): + """ Test salt-key script - ''' + """ - _call_binary_ = 'salt-key' + _call_binary_ = "salt-key" def test_list(self): - ''' + """ test salt-key -L - ''' - data = self.run_key('-L') + """ + data = self.run_key("-L") expect = [ - 'Unaccepted Keys:', - 'Accepted Keys:', - 'minion', - 'sub_minion', - 'Rejected:', ''] + "Unaccepted Keys:", + "Accepted Keys:", + "minion", + "sub_minion", + "Rejected:", + "", + ] self.assertEqual(data, expect) This example verifies that the ``salt-key`` command executes and returns as @@ -345,9 +345,9 @@ Testing salt-ssh functionality can be done using the SSHCase test class: .. code-block:: python - import tests.integration as integration + from tests.support.case import SSHCase - class SSHGrainsTest(integration.SSHCase): + class SSHGrainsTest(SSHCase): ''' Test salt-ssh grains functionality Depend on proper environment set by integration.SSHCase class @@ -370,20 +370,23 @@ on a minion event bus. .. code-block:: python - import tests.integration as integration import salt.utils.event + from tests.support.mixins import SaltEventAssertsMixin - class TestEvent(integration.SaltEventAssertsMixin): - ''' + + class TestEvent(SaltEventAssertsMixin): + """ Example test of firing an event and receiving it - ''' + """ def test_event(self): - e = salt.utils.event.get_event('minion', sock_dir=self.minion_opts['sock_dir'], opts=self.minion_opts) + e = salt.utils.event.get_event( + "minion", sock_dir=self.minion_opts["sock_dir"], opts=self.minion_opts + ) - e.fire_event({'a': 'b'}, '/test_event') + e.fire_event({"a": "b"}, "/test_event") - self.assertMinionEventReceived({'a': 'b'}) + self.assertMinionEventReceived({"a": "b"}) Syndic Example via SyndicCase @@ -393,17 +396,19 @@ Testing Salt's Syndic can be done via the SyndicCase test class: .. code-block:: python - import tests.integration as integration + from tests.support.case import SyndicCase - class TestSyndic(integration.SyndicCase): - ''' + + class TestSyndic(SyndicCase): + """ Validate the syndic interface by testing the test module - ''' + """ + def test_ping(self): - ''' + """ test.ping - ''' - self.assertTrue(self.run_function('test.ping')) + """ + self.assertTrue(self.run_function("test.ping")) This example verifies that a ``test.ping`` command is issued from the testing master, is passed through to the testing syndic, down to the minion, and back @@ -446,16 +451,16 @@ to test states: # Import salt libs import salt.utils.files - HFILE = os.path.join(TMP, 'hosts') + HFILE = os.path.join(TMP, "hosts") class HostTest(ModuleCase, SaltReturnAssertsMixin): - ''' + """ Validate the host state - ''' + """ def setUp(self): - shutil.copyfile(os.path.join(FILES, 'hosts'), HFILE) + shutil.copyfile(os.path.join(FILES, "hosts"), HFILE) super(HostTest, self).setUp() def tearDown(self): @@ -464,18 +469,18 @@ to test states: super(HostTest, self).tearDown() def test_present(self): - ''' + """ host.present - ''' - name = 'spam.bacon' - ip = '10.10.10.10' - ret = self.run_state('host.present', name=name, ip=ip) + """ + name = "spam.bacon" + ip = "10.10.10.10" + ret = self.run_state("host.present", name=name, ip=ip) self.assertSaltTrueReturn(ret) with salt.utils.files.fopen(HFILE) as fp_: output = fp_.read() - self.assertIn('{0}\t\t{1}'.format(ip, name), output) + self.assertIn("{0}\t\t{1}".format(ip, name), output) -To access the integration files, a variable named ``FILES`` points to the +To access the integration files, a variable named ``FILES`` points to the ``tests/integration/files`` directory. This is where the referenced ``host.present`` sls file resides. @@ -507,24 +512,25 @@ the test method: .. code-block:: python - import tests.integration as integration + from tests.support.case import ModuleCase from tests.support.helpers import destructiveTest, skip_if_not_root - class DestructiveExampleModuleTest(integration.ModuleCase): - ''' + + class DestructiveExampleModuleTest(ModuleCase): + """ Demonstrate a destructive test - ''' + """ @destructiveTest @skip_if_not_root def test_user_not_present(self): - ''' + """ This is a DESTRUCTIVE TEST it creates a new user on the minion. And then destroys that user. - ''' - ret = self.run_state('user.present', name='salt_test') + """ + ret = self.run_state("user.present", name="salt_test") self.assertSaltTrueReturn(ret) - ret = self.run_state('user.absent', name='salt_test') + ret = self.run_state("user.absent", name="salt_test") self.assertSaltTrueReturn(ret) @@ -634,27 +640,28 @@ the test function: from tests.support.helpers import expensiveTest + @expensiveTest def test_instance(self): - ''' + """ Test creating an instance on Linode - ''' - name = 'linode-testing' + """ + name = "linode-testing" # create the instance - instance = self.run_cloud('-p linode-test {0}'.format(name)) - str = ' {0}'.format(name) + instance = self.run_cloud("-p linode-test {0}".format(name)) + str = " {0}".format(name) # check if instance with salt installed returned as expected try: self.assertIn(str, instance) except AssertionError: - self.run_cloud('-d {0} --assume-yes'.format(name)) + self.run_cloud("-d {0} --assume-yes".format(name)) raise # delete the instance - delete = self.run_cloud('-d {0} --assume-yes'.format(name)) - str = ' True' + delete = self.run_cloud("-d {0} --assume-yes".format(name)) + str = " True" try: self.assertIn(str, delete) except AssertionError: diff --git a/doc/topics/development/tests/unit.rst b/doc/topics/development/tests/unit.rst index 47bed3567c5..969d064ec9a 100644 --- a/doc/topics/development/tests/unit.rst +++ b/doc/topics/development/tests/unit.rst @@ -113,14 +113,10 @@ to the module being tested one should do: import salt.modules.somemodule as somemodule - class SomeModuleTest(TestCase, LoaderModuleMockMixin): + class SomeModuleTest(TestCase, LoaderModuleMockMixin): def setup_loader_modules(self): - return { - somemodule: { - '__opts__': {'test': True} - } - } + return {somemodule: {"__opts__": {"test": True}}} Consider this more extensive example from ``tests/unit/modules/test_libcloud_dns.py``: @@ -133,10 +129,7 @@ Consider this more extensive example from # Import Salt Testing Libs from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase - from tests.support.mock import ( - patch, - MagicMock, - ) + from tests.support.mock import patch, MagicMock import salt.modules.libcloud_dns as libcloud_dns @@ -149,23 +142,18 @@ Consider this more extensive example from return MockDNSDriver() - @patch('salt.modules.libcloud_dns._get_driver', - MagicMock(return_value=MockDNSDriver())) + @patch("salt.modules.libcloud_dns._get_driver", MagicMock(return_value=MockDNSDriver())) class LibcloudDnsModuleTestCase(TestCase, LoaderModuleMockMixin): - def setup_loader_modules(self): module_globals = { - '__salt__': { - 'config.option': MagicMock(return_value={ - 'test': { - 'driver': 'test', - 'key': '2orgk34kgk34g' - } - }) + "__salt__": { + "config.option": MagicMock( + return_value={"test": {"driver": "test", "key": "2orgk34kgk34g"}} + ) } } if libcloud_dns.HAS_LIBCLOUD is False: - module_globals['sys.modules'] = {'libcloud': MagicMock()} + module_globals["sys.modules"] = {"libcloud": MagicMock()} return {libcloud_dns: module_globals} @@ -193,18 +181,15 @@ a separate implementation which has additional functionality. .. code-block:: python from tests.support.unit import TestCase - from tests.support.mock import ( - patch - mock_open, - ) + from tests.support.mock import patch, mock_open import salt.modules.mymod as mymod - class MyAwesomeTestCase(TestCase): + class MyAwesomeTestCase(TestCase): def test_something(self): - fopen_mock = mock_open(read_data='foo\nbar\nbaz\n') - with patch('salt.utils.files.fopen', fopen_mock): + fopen_mock = mock_open(read_data="foo\nbar\nbaz\n") + with patch("salt.utils.files.fopen", fopen_mock): result = mymod.myfunc() assert result is True @@ -245,30 +230,31 @@ those cases, you can pass ``read_data`` as a dictionary: import textwrap from tests.support.unit import TestCase - from tests.support.mock import ( - patch - mock_open, - ) + from tests.support.mock import patch, mock_open import salt.modules.mymod as mymod - class MyAwesomeTestCase(TestCase): + class MyAwesomeTestCase(TestCase): def test_something(self): contents = { - '/etc/foo.conf': textwrap.dedent('''\ + "/etc/foo.conf": textwrap.dedent( + """\ foo bar baz - '''), - '/etc/b*.conf': textwrap.dedent('''\ + """ + ), + "/etc/b*.conf": textwrap.dedent( + """\ one two three - '''), + """ + ), } fopen_mock = mock_open(read_data=contents) - with patch('salt.utils.files.fopen', fopen_mock): + with patch("salt.utils.files.fopen", fopen_mock): result = mymod.myfunc() assert result is True @@ -284,8 +270,8 @@ below two ``mock_open`` calls would produce identical results: .. code-block:: python - mock_open(read_data='foo\n') - mock_open(read_data={'*': 'foo\n'}) + mock_open(read_data="foo\n") + mock_open(read_data={"*": "foo\n"}) .. note:: Take care when specifying the ``read_data`` as a dictionary, in cases where @@ -300,9 +286,9 @@ below two ``mock_open`` calls would produce identical results: .. code-block:: python contents = OrderedDict() - contents['/etc/bar.conf'] = 'foo\nbar\nbaz\n' - contents['/etc/b*.conf'] = IOError(errno.EACCES, 'Permission denied') - contents['*'] = 'This is a fallback for files not beginning with "/etc/b"\n' + contents["/etc/bar.conf"] = "foo\nbar\nbaz\n" + contents["/etc/b*.conf"] = IOError(errno.EACCES, "Permission denied") + contents["*"] = 'This is a fallback for files not beginning with "/etc/b"\n' fopen_mock = mock_open(read_data=contents) Raising Exceptions @@ -315,19 +301,16 @@ Instead of a string, an exception can also be used as the ``read_data``: import errno from tests.support.unit import TestCase - from tests.support.mock import ( - patch - mock_open, - ) + from tests.support.mock import patch, mock_open import salt.modules.mymod as mymod - class MyAwesomeTestCase(TestCase): + class MyAwesomeTestCase(TestCase): def test_something(self): - exc = IOError(errno.EACCES, 'Permission denied') + exc = IOError(errno.EACCES, "Permission denied") fopen_mock = mock_open(read_data=exc) - with patch('salt.utils.files.fopen', fopen_mock): + with patch("salt.utils.files.fopen", fopen_mock): mymod.myfunc() The above example would raise the specified exception when any file is opened. @@ -350,39 +333,42 @@ and produce a mocked filehandle with the specified contents. For example: import textwrap from tests.support.unit import TestCase - from tests.support.mock import ( - patch - mock_open, - ) + from tests.support.mock import patch, mock_open import salt.modules.mymod as mymod - class MyAwesomeTestCase(TestCase): + class MyAwesomeTestCase(TestCase): def test_something(self): contents = { - '/etc/foo.conf': [ - textwrap.dedent('''\ + "/etc/foo.conf": [ + textwrap.dedent( + """\ foo bar - '''), - textwrap.dedent('''\ + """ + ), + textwrap.dedent( + """\ foo bar baz - '''), + """ + ), ], - '/etc/b*.conf': [ - IOError(errno.ENOENT, 'No such file or directory'), - textwrap.dedent('''\ + "/etc/b*.conf": [ + IOError(errno.ENOENT, "No such file or directory"), + textwrap.dedent( + """\ one two three - '''), + """ + ), ], } fopen_mock = mock_open(read_data=contents) - with patch('salt.utils.files.fopen', fopen_mock): + with patch("salt.utils.files.fopen", fopen_mock): result = mymod.myfunc() assert result is True @@ -423,8 +409,8 @@ so, just add an ``as`` clause to the end of the ``patch`` statement: .. code-block:: python - fopen_mock = mock_open(read_data='foo\nbar\nbaz\n') - with patch('salt.utils.files.fopen', fopen_mock) as m_open: + fopen_mock = mock_open(read_data="foo\nbar\nbaz\n") + with patch("salt.utils.files.fopen", fopen_mock) as m_open: # do testing here ... ... @@ -448,29 +434,25 @@ several useful attributes: .. code-block:: python from tests.support.unit import TestCase - from tests.support.mock import ( - patch - mock_open, - MockCall, - ) + from tests.support.mock import patch, mock_open, MockCall import salt.modules.mymod as mymod - class MyAwesomeTestCase(TestCase): + class MyAwesomeTestCase(TestCase): def test_something(self): - with patch('salt.utils.files.fopen', mock_open(read_data=b'foo\n')) as m_open: + with patch("salt.utils.files.fopen", mock_open(read_data=b"foo\n")) as m_open: mymod.myfunc() # Assert that only two opens attempted assert m_open.call_count == 2 # Assert that only /etc/foo.conf was opened - assert all(call.args[0] == '/etc/foo.conf' for call in m_open.calls) + assert all(call.args[0] == "/etc/foo.conf" for call in m_open.calls) # Asser that the first open was for binary read, and the # second was for binary write. assert m_open.calls == [ - MockCall('/etc/foo.conf', 'rb'), - MockCall('/etc/foo.conf', 'wb'), + MockCall("/etc/foo.conf", "rb"), + MockCall("/etc/foo.conf", "wb"), ] Note that ``MockCall`` is imported from ``tests.support.mock`` in the above @@ -526,35 +508,35 @@ Examples .. code-block:: python - with patch('salt.utils.files.fopen', mock_open(read_data=contents)) as m_open: + with patch("salt.utils.files.fopen", mock_open(read_data=contents)) as m_open: # Run the code you are unit testing mymod.myfunc() # Check that only the expected file was opened, and that it was opened # only once. assert m_open.call_count == 1 - assert list(m_open.filehandles) == ['/etc/foo.conf'] + assert list(m_open.filehandles) == ["/etc/foo.conf"] # "opens" will be a list of all the mocked filehandles opened - opens = m_open.filehandles['/etc/foo.conf'] + opens = m_open.filehandles["/etc/foo.conf"] # Check that we wrote the expected lines ("expected" here is assumed to # be a list of strings) assert opens[0].write_calls == expected .. code-block:: python - with patch('salt.utils.files.fopen', mock_open(read_data=contents)) as m_open: + with patch("salt.utils.files.fopen", mock_open(read_data=contents)) as m_open: # Run the code you are unit testing mymod.myfunc() # Check that .readlines() was called (remember, it's a Mock) - m_open.filehandles['/etc/foo.conf'][0].readlines.assert_called() + m_open.filehandles["/etc/foo.conf"][0].readlines.assert_called() .. code-block:: python - with patch('salt.utils.files.fopen', mock_open(read_data=contents)) as m_open: + with patch("salt.utils.files.fopen", mock_open(read_data=contents)) as m_open: # Run the code you are unit testing mymod.myfunc() # Check that we read the file and also wrote to it - m_open.filehandles['/etc/foo.conf'][0].read.assert_called_once() - m_open.filehandles['/etc/foo.conf'][1].writelines.assert_called_once() + m_open.filehandles["/etc/foo.conf"][0].read.assert_called_once() + m_open.filehandles["/etc/foo.conf"][1].writelines.assert_called_once() .. _`Mock()`: https://github.com/testing-cabal/mock @@ -628,11 +610,13 @@ methods, here presented in pseduo-code in an imaginary execution module called .. code-block:: python def create_user(username): - qry = 'CREATE USER {0}'.format(username) + qry = "CREATE USER {0}".format(username) execute_query(qry) + def execute_query(qry): # Connect to a database and actually do the query... + ... Here, let's imagine that we want to create a unit test for the `create_user` function. In doing so, we want to avoid any calls out to an external system and @@ -661,10 +645,10 @@ additional imports for MagicMock: class DbTestCase(TestCase): def test_create_user(self): # First, we replace 'execute_query' with our own mock function - with patch.object(db, 'execute_query', MagicMock()) as db_exq: + with patch.object(db, "execute_query", MagicMock()) as db_exq: # Now that the exits are blocked, we can run the function under test. - db.create_user('testuser') + db.create_user("testuser") # We could now query our mock object to see which calls were made # to it. @@ -672,7 +656,7 @@ additional imports for MagicMock: # Construct a call object that simulates the way we expected # execute_query to have been called. - expected_call = call('CREATE USER testuser') + expected_call = call("CREATE USER testuser") # Compare the expected call with the list of actual calls. The # test will succeed or fail depending on the output of this @@ -730,14 +714,15 @@ we might write the skeleton for testing ``fib.py``: # Create test case class and inherit from Salt's customized TestCase class FibTestCase(TestCase): - ''' + """ This class contains a set of functions that test salt.modules.fib. - ''' + """ + def test_fib(self): - ''' + """ To create a unit test, we should prefix the name with `test_' so that it's recognized by the test runner. - ''' + """ fib_five = (0, 1, 1, 2, 3) self.assertEqual(fib.calculate(5), fib_five) @@ -774,7 +759,7 @@ Consider the following function from salt/modules/linux_sysctl.py. .. code-block:: python def get(name): - ''' + """ Return a single sysctl parameter for this minion CLI Example: @@ -782,9 +767,9 @@ Consider the following function from salt/modules/linux_sysctl.py. .. code-block:: bash salt '*' sysctl.get net.ipv4.ip_forward - ''' - cmd = 'sysctl -n {0}'.format(name) - out = __salt__['cmd.run'](cmd) + """ + cmd = "sysctl -n {0}".format(name) + out = __salt__["cmd.run"](cmd) return out This function is very simple, comprising only four source lines of code and @@ -805,24 +790,21 @@ will also redefine the ``__salt__`` dictionary such that it only contains # Import Salt Testing Libs from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase - from tests.support.mock import ( - MagicMock, - patch, - ) + from tests.support.mock import MagicMock, patch class LinuxSysctlTestCase(TestCase, LoaderModuleMockMixin): - ''' + """ TestCase for salt.modules.linux_sysctl module - ''' + """ def test_get(self): - ''' + """ Tests the return of get function - ''' + """ mock_cmd = MagicMock(return_value=1) - with patch.dict(linux_sysctl.__salt__, {'cmd.run': mock_cmd}): - self.assertEqual(linux_sysctl.get('net.ipv4.ip_forward'), 1) + with patch.dict(linux_sysctl.__salt__, {"cmd.run": mock_cmd}): + self.assertEqual(linux_sysctl.get("net.ipv4.ip_forward"), 1) Since ``get()`` has only one raise or return statement and that statement is a success condition, the test function is simply named ``test_get()``. As @@ -847,7 +829,7 @@ salt/modules/linux_sysctl.py source file. .. code-block:: python def assign(name, value): - ''' + """ Assign a single sysctl parameter for this minion CLI Example: @@ -855,31 +837,30 @@ salt/modules/linux_sysctl.py source file. .. code-block:: bash salt '*' sysctl.assign net.ipv4.ip_forward 1 - ''' + """ value = str(value) - sysctl_file = '/proc/sys/{0}'.format(name.replace('.', '/')) + sysctl_file = "/proc/sys/{0}".format(name.replace(".", "/")) if not os.path.exists(sysctl_file): - raise CommandExecutionError('sysctl {0} does not exist'.format(name)) + raise CommandExecutionError("sysctl {0} does not exist".format(name)) ret = {} cmd = 'sysctl -w {0}="{1}"'.format(name, value) - data = __salt__['cmd.run_all'](cmd) - out = data['stdout'] - err = data['stderr'] + data = __salt__["cmd.run_all"](cmd) + out = data["stdout"] + err = data["stderr"] # Example: # # sysctl -w net.ipv4.tcp_rmem="4096 87380 16777216" # net.ipv4.tcp_rmem = 4096 87380 16777216 - regex = re.compile(r'^{0}\s+=\s+{1}$'.format(re.escape(name), - re.escape(value))) + regex = re.compile(r"^{0}\s+=\s+{1}$".format(re.escape(name), re.escape(value))) - if not regex.match(out) or 'Invalid argument' in str(err): - if data['retcode'] != 0 and err: + if not regex.match(out) or "Invalid argument" in str(err): + if data["retcode"] != 0 and err: error = err else: error = out - raise CommandExecutionError('sysctl -w failed: {0}'.format(error)) - new_name, new_value = out.split(' = ', 1) + raise CommandExecutionError("sysctl -w failed: {0}".format(error)) + new_name, new_value = out.split(" = ", 1) ret[new_name] = new_value return ret @@ -904,53 +885,63 @@ with. # Import Salt Testing Libs from tests.support.mixins import LoaderModuleMockMixin from tests.support.unit import TestCase - from tests.support.mock import ( - MagicMock, - patch, - ) + from tests.support.mock import MagicMock, patch class LinuxSysctlTestCase(TestCase, LoaderModuleMockMixin): - ''' + """ TestCase for salt.modules.linux_sysctl module - ''' + """ - @patch('os.path.exists', MagicMock(return_value=False)) + @patch("os.path.exists", MagicMock(return_value=False)) def test_assign_proc_sys_failed(self): - ''' + """ Tests if /proc/sys/ exists or not - ''' - cmd = {'pid': 1337, 'retcode': 0, 'stderr': '', - 'stdout': 'net.ipv4.ip_forward = 1'} + """ + cmd = { + "pid": 1337, + "retcode": 0, + "stderr": "", + "stdout": "net.ipv4.ip_forward = 1", + } mock_cmd = MagicMock(return_value=cmd) - with patch.dict(linux_sysctl.__salt__, {'cmd.run_all': mock_cmd}): - self.assertRaises(CommandExecutionError, - linux_sysctl.assign, - 'net.ipv4.ip_forward', 1) + with patch.dict(linux_sysctl.__salt__, {"cmd.run_all": mock_cmd}): + self.assertRaises( + CommandExecutionError, linux_sysctl.assign, "net.ipv4.ip_forward", 1 + ) - @patch('os.path.exists', MagicMock(return_value=True)) + @patch("os.path.exists", MagicMock(return_value=True)) def test_assign_cmd_failed(self): - ''' + """ Tests if the assignment was successful or not - ''' - cmd = {'pid': 1337, 'retcode': 0, 'stderr': - 'sysctl: setting key "net.ipv4.ip_forward": Invalid argument', - 'stdout': 'net.ipv4.ip_forward = backward'} + """ + cmd = { + "pid": 1337, + "retcode": 0, + "stderr": 'sysctl: setting key "net.ipv4.ip_forward": Invalid argument', + "stdout": "net.ipv4.ip_forward = backward", + } mock_cmd = MagicMock(return_value=cmd) - with patch.dict(linux_sysctl.__salt__, {'cmd.run_all': mock_cmd}): - self.assertRaises(CommandExecutionError, - linux_sysctl.assign, - 'net.ipv4.ip_forward', 'backward') + with patch.dict(linux_sysctl.__salt__, {"cmd.run_all": mock_cmd}): + self.assertRaises( + CommandExecutionError, + linux_sysctl.assign, + "net.ipv4.ip_forward", + "backward", + ) - @patch('os.path.exists', MagicMock(return_value=True)) + @patch("os.path.exists", MagicMock(return_value=True)) def test_assign_success(self): - ''' + """ Tests the return of successful assign function - ''' - cmd = {'pid': 1337, 'retcode': 0, 'stderr': '', - 'stdout': 'net.ipv4.ip_forward = 1'} - ret = {'net.ipv4.ip_forward': '1'} + """ + cmd = { + "pid": 1337, + "retcode": 0, + "stderr": "", + "stdout": "net.ipv4.ip_forward = 1", + } + ret = {"net.ipv4.ip_forward": "1"} mock_cmd = MagicMock(return_value=cmd) - with patch.dict(linux_sysctl.__salt__, {'cmd.run_all': mock_cmd}): - self.assertEqual(linux_sysctl.assign( - 'net.ipv4.ip_forward', 1), ret) + with patch.dict(linux_sysctl.__salt__, {"cmd.run_all": mock_cmd}): + self.assertEqual(linux_sysctl.assign("net.ipv4.ip_forward", 1), ret) diff --git a/doc/topics/event/events.rst b/doc/topics/event/events.rst index 1e620451bba..c7a76f6e630 100644 --- a/doc/topics/event/events.rst +++ b/doc/topics/event/events.rst @@ -84,13 +84,11 @@ The following code will check for a single event: import salt.config import salt.utils.event - opts = salt.config.client_config('/etc/salt/master') + opts = salt.config.client_config("/etc/salt/master") event = salt.utils.event.get_event( - 'master', - sock_dir=opts['sock_dir'], - transport=opts['transport'], - opts=opts) + "master", sock_dir=opts["sock_dir"], transport=opts["transport"], opts=opts + ) data = event.get_event() @@ -106,15 +104,15 @@ instead of the default 5. .. code-block:: python - data = event.get_event(wait=10, tag='salt/auth') + data = event.get_event(wait=10, tag="salt/auth") To retrieve the tag as well as the event data, pass ``full=True``: .. code-block:: python - evdata = event.get_event(wait=10, tag='salt/job', full=True) + evdata = event.get_event(wait=10, tag="salt/job", full=True) - tag, data = evdata['tag'], evdata['data'] + tag, data = evdata["tag"], evdata["data"] Instead of looking for a single event, the ``iter_events`` method can be used to @@ -124,7 +122,7 @@ The iter_events method also accepts a tag but not a wait time: .. code-block:: python - for data in event.iter_events(tag='salt/auth'): + for data in event.iter_events(tag="salt/auth"): print(data) And finally event tags can be globbed, such as they can be in the Reactor, @@ -137,21 +135,19 @@ using the fnmatch library. import salt.config import salt.utils.event - opts = salt.config.client_config('/etc/salt/master') + opts = salt.config.client_config("/etc/salt/master") sevent = salt.utils.event.get_event( - 'master', - sock_dir=opts['sock_dir'], - transport=opts['transport'], - opts=opts) + "master", sock_dir=opts["sock_dir"], transport=opts["transport"], opts=opts + ) while True: ret = sevent.get_event(full=True) if ret is None: continue - if fnmatch.fnmatch(ret['tag'], 'salt/job/*/ret/*'): - do_something_with_job_return(ret['data']) + if fnmatch.fnmatch(ret["tag"], "salt/job/*/ret/*"): + do_something_with_job_return(ret["data"]) Firing Events ============= @@ -184,12 +180,12 @@ a minion on a non-Windows system: # Job on minion import salt.utils.event - opts = salt.config.minion_config('/etc/salt/minion') + opts = salt.config.minion_config("/etc/salt/minion") event = salt.utils.event.MinionEvent(opts) - for evdata in event.iter_events(match_type = 'regex', - tag = 'custom/.*'): + for evdata in event.iter_events(match_type="regex", tag="custom/.*"): # do your processing here... + ... And an example of listening local events on a Windows system: @@ -201,9 +197,9 @@ And an example of listening local events on a Windows system: opts = salt.config.minion_config(salt.minion.DEFAULT_MINION_OPTS) event = salt.utils.event.MinionEvent(opts) - for evdata in event.iter_events(match_type = 'regex', - tag = 'custom/.*'): + for evdata in event.iter_events(match_type="regex", tag="custom/.*"): # do your processing here... + ... .. code-block:: bash @@ -224,19 +220,20 @@ easily done using the normal cross-calling syntax: # /srv/salt/_modules/my_custom_module.py + def do_something(): - ''' + """ Do something and fire an event to the master when finished CLI Example:: salt '*' my_custom_module:do_something - ''' + """ # do something! - __salt__['event.send']('myco/my_custom_module/finished', { - 'finished': True, - 'message': "The something is finished!", - }) + __salt__["event.send"]( + "myco/my_custom_module/finished", + {"finished": True, "message": "The something is finished!",}, + ) From Custom Python Scripts -------------------------- @@ -257,3 +254,4 @@ done at the CLI: if not ret: # the event could not be sent, process the error here + ... diff --git a/doc/topics/ext_processes/index.rst b/doc/topics/ext_processes/index.rst index b147336fa37..4c5b4af1d49 100644 --- a/doc/topics/ext_processes/index.rst +++ b/doc/topics/ext_processes/index.rst @@ -58,9 +58,9 @@ Example Process Class self.opts = opts def run(self): - self.event = SaltEvent('master', self.opts['sock_dir']) + self.event = SaltEvent("master", self.opts["sock_dir"]) i = 0 while True: - self.event.fire_event({'iteration': i}, 'ext_processes/test{0}') + self.event.fire_event({"iteration": i}, "ext_processes/test{0}") time.sleep(60) diff --git a/doc/topics/grains/index.rst b/doc/topics/grains/index.rst index 008121521bc..92a94f61fb1 100644 --- a/doc/topics/grains/index.rst +++ b/doc/topics/grains/index.rst @@ -146,12 +146,12 @@ dictionary. For example: .. code-block:: python def yourfunction(): - # initialize a grains dictionary - grains = {} - # Some code for logic that sets grains like - grains['yourcustomgrain'] = True - grains['anothergrain'] = 'somevalue' - return grains + # initialize a grains dictionary + grains = {} + # Some code for logic that sets grains like + grains["yourcustomgrain"] = True + grains["anothergrain"] = "somevalue" + return grains The name of the function does not matter and will not factor into the grains data at all; only the keys/values returned become part of the grains. @@ -205,14 +205,14 @@ grain data structure. For example, consider this custom grain file: #!/usr/bin/env python def _my_custom_grain(): - my_grain = {'foo': 'bar', 'hello': 'world'} + my_grain = {"foo": "bar", "hello": "world"} return my_grain def main(): # initialize a grains dictionary grains = {} - grains['my_grains'] = _my_custom_grain() + grains["my_grains"] = _my_custom_grain() return grains The output of this example renders like so: diff --git a/doc/topics/jinja/index.rst b/doc/topics/jinja/index.rst index 38c3fdcc00c..e0a758cbe6e 100644 --- a/doc/topics/jinja/index.rst +++ b/doc/topics/jinja/index.rst @@ -379,7 +379,7 @@ Returns: .. code-block:: python - ('defabcdef',) + ("defabcdef",) .. jinja_ref:: regex_match @@ -740,7 +740,7 @@ Returns: .. code-block:: python - {'new': [4], 'old': [3]} + {"new": [4], "old": [3]} .. jinja_ref:: compare_dicts @@ -762,7 +762,7 @@ Returns: .. code-block:: python - {'a': {'new': 'c', 'old': 'b'}} + {"a": {"new": "c", "old": "b"}} .. jinja_ref:: is_hex @@ -1018,7 +1018,7 @@ Returns: .. code-block:: python - {'a': '\xd0\x94'} + {"a": "\xd0\x94"} .. jinja_ref:: tojson @@ -1381,7 +1381,7 @@ Returns: .. code-block:: python - {'c1': 'foo'} + {"c1": "foo"} .. code-block:: jinja @@ -1391,7 +1391,7 @@ Returns: .. code-block:: python - 'default' + "default" .. jinja_ref:: json_query @@ -1571,7 +1571,7 @@ Returns: .. code-block:: python - ['192.168.0.1', 'fe80::'] + ["192.168.0.1", "fe80::"] .. jinja_ref:: ipv4 @@ -1594,7 +1594,7 @@ Returns: .. code-block:: python - ['192.168.0.1'] + ["192.168.0.1"] .. jinja_ref:: ipv6 @@ -1617,7 +1617,7 @@ Returns: .. code-block:: python - ['fe80::'] + ["fe80::"] .. jinja_ref:: network_hosts @@ -1644,7 +1644,7 @@ Returns: .. code-block:: python - ['192.168.0.1', '192.168.0.2'] + ["192.168.0.1", "192.168.0.2"] .. jinja_ref:: network_size @@ -1947,7 +1947,7 @@ Returns: .. code-block:: python - [{'value': 3}] + [{"value": 3}] .. jinja_ref:: match @@ -1976,7 +1976,7 @@ Returns: .. code-block:: python - [{'value': 'b'}, {'value': 'c'}] + [{"value": "b"}, {"value": "c"}] Test supports additional optional arguments: ``ignorecase``, ``multiline`` diff --git a/doc/topics/master_tops/index.rst b/doc/topics/master_tops/index.rst index c387abd2527..b8c3bdc0af9 100644 --- a/doc/topics/master_tops/index.rst +++ b/doc/topics/master_tops/index.rst @@ -61,8 +61,9 @@ bare-bones example: import logging import sys + # Define the module's virtual name - __virtualname__ = 'customtop' + __virtualname__ = "customtop" log = logging.getLogger(__name__) @@ -72,8 +73,8 @@ bare-bones example: def top(**kwargs): - log.debug('Calling top in customtop') - return {'base': ['test']} + log.debug("Calling top in customtop") + return {"base": ["test"]} `salt minion state.show_top` should then display something like: diff --git a/doc/topics/matchers/index.rst b/doc/topics/matchers/index.rst index 261fad82eb9..344502b0972 100644 --- a/doc/topics/matchers/index.rst +++ b/doc/topics/matchers/index.rst @@ -36,14 +36,15 @@ As an example, let's modify the ``list`` matcher to have the separator be a from __future__ import absolute_import, print_function, unicode_literals from salt.ext import six # pylint: disable=3rd-party-module-not-gated + def match(self, tgt): - ''' + """ Determines if this host is on the list - ''' + """ if isinstance(tgt, six.string_types): # The stock matcher splits on `,`. Change to `/` below. - tgt = tgt.split('/') - return bool(self.opts['id'] in tgt) + tgt = tgt.split("/") + return bool(self.opts["id"] in tgt) Place this code in a file called ``list_matcher.py`` in ``_matchers`` in your diff --git a/doc/topics/orchestrate/orchestrate_runner.rst b/doc/topics/orchestrate/orchestrate_runner.rst index 78cd4b1ce1c..11fbab63a04 100644 --- a/doc/topics/orchestrate/orchestrate_runner.rst +++ b/doc/topics/orchestrate/orchestrate_runner.rst @@ -278,10 +278,10 @@ in remote execution functions. Here is some example pseudocode: def myrunner(): ... - do stuff + # do stuff ... if some_error_condition: - __context__['retcode'] = 1 + __context__["retcode"] = 1 return result This allows a custom runner/wheel function to report its failure so that diff --git a/doc/topics/proxyminion/index.rst b/doc/topics/proxyminion/index.rst index 929fa99300f..07bead1883a 100644 --- a/doc/topics/proxyminion/index.rst +++ b/doc/topics/proxyminion/index.rst @@ -85,12 +85,14 @@ they are being loaded for the correct proxytype, example below: .. code-block:: python def __virtual__(): - ''' + """ Only work on proxy - ''' + """ try: - if salt.utils.platform.is_proxy() and \ - __opts__['proxy']['proxytype'] == 'ssh_sample': + if ( + salt.utils.platform.is_proxy() + and __opts__["proxy"]["proxytype"] == "ssh_sample" + ): return __virtualname__ except KeyError: pass @@ -110,10 +112,10 @@ to ``__proxy__``. This enables patterns like .. code-block:: python def get_ip(proxy): - ''' + """ Ask the remote device what IP it has - ''' - return {'ip':proxy['proxymodulename.get_ip']()} + """ + return {"ip": proxy["proxymodulename.get_ip"]()} Then the grain ``ip`` will contain the result of calling the ``get_ip()`` function @@ -397,10 +399,10 @@ and status; "package" installation, and a ping. .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ This is a simple proxy-minion designed to connect to and communicate with the bottle-based web service contained in https://github.com/saltstack/salt-contrib/tree/master/proxyminion_rest_example - ''' + """ from __future__ import absolute_import # Import python libs @@ -410,7 +412,7 @@ and status; "package" installation, and a ping. HAS_REST_EXAMPLE = True # This must be present or the Salt loader won't load this module - __proxyenabled__ = ['rest_sample'] + __proxyenabled__ = ["rest_sample"] # Variables are scoped to this module so we can have persistent data @@ -425,182 +427,207 @@ and status; "package" installation, and a ping. # This does nothing, it's here just as an example and to provide a log # entry when the module is loaded. def __virtual__(): - ''' + """ Only return if all the modules are available - ''' - log.debug('rest_sample proxy __virtual__() called...') + """ + log.debug("rest_sample proxy __virtual__() called...") return True def _complicated_function_that_determines_if_alive(): return True + # Every proxy module needs an 'init', though you can # just put DETAILS['initialized'] = True here if nothing # else needs to be done. + def init(opts): - log.debug('rest_sample proxy init() called...') - DETAILS['initialized'] = True + log.debug("rest_sample proxy init() called...") + DETAILS["initialized"] = True # Save the REST URL - DETAILS['url'] = opts['proxy']['url'] + DETAILS["url"] = opts["proxy"]["url"] # Make sure the REST URL ends with a '/' - if not DETAILS['url'].endswith('/'): - DETAILS['url'] += '/' + if not DETAILS["url"].endswith("/"): + DETAILS["url"] += "/" + def alive(opts): - ''' + """ This function returns a flag with the connection state. It is very useful when the proxy minion establishes the communication via a channel that requires a more elaborated keep-alive mechanism, e.g. NETCONF over SSH. - ''' - log.debug('rest_sample proxy alive() called...') + """ + log.debug("rest_sample proxy alive() called...") return _complicated_function_that_determines_if_alive() def initialized(): - ''' + """ Since grains are loaded in many different places and some of those places occur before the proxy can be initialized, return whether our init() function has been called - ''' - return DETAILS.get('initialized', False) + """ + return DETAILS.get("initialized", False) def grains(): - ''' + """ Get the grains from the proxied device - ''' - if not DETAILS.get('grains_cache', {}): - r = salt.utils.http.query(DETAILS['url']+'info', decode_type='json', decode=True) - DETAILS['grains_cache'] = r['dict'] - return DETAILS['grains_cache'] + """ + if not DETAILS.get("grains_cache", {}): + r = salt.utils.http.query( + DETAILS["url"] + "info", decode_type="json", decode=True + ) + DETAILS["grains_cache"] = r["dict"] + return DETAILS["grains_cache"] def grains_refresh(): - ''' + """ Refresh the grains from the proxied device - ''' - DETAILS['grains_cache'] = None + """ + DETAILS["grains_cache"] = None return grains() def fns(): - return {'details': 'This key is here because a function in ' - 'grains/rest_sample.py called fns() here in the proxymodule.'} + return { + "details": "This key is here because a function in " + "grains/rest_sample.py called fns() here in the proxymodule." + } def service_start(name): - ''' + """ Start a "service" on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'service/start/'+name, decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "service/start/" + name, decode_type="json", decode=True + ) + return r["dict"] def service_stop(name): - ''' + """ Stop a "service" on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'service/stop/'+name, decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "service/stop/" + name, decode_type="json", decode=True + ) + return r["dict"] def service_restart(name): - ''' + """ Restart a "service" on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'service/restart/'+name, decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "service/restart/" + name, decode_type="json", decode=True + ) + return r["dict"] def service_list(): - ''' + """ List "services" on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'service/list', decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "service/list", decode_type="json", decode=True + ) + return r["dict"] def service_status(name): - ''' + """ Check if a service is running on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'service/status/'+name, decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "service/status/" + name, decode_type="json", decode=True + ) + return r["dict"] def package_list(): - ''' + """ List "packages" installed on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'package/list', decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "package/list", decode_type="json", decode=True + ) + return r["dict"] def package_install(name, **kwargs): - ''' + """ Install a "package" on the REST server - ''' - cmd = DETAILS['url']+'package/install/'+name - if kwargs.get('version', False): - cmd += '/'+kwargs['version'] + """ + cmd = DETAILS["url"] + "package/install/" + name + if kwargs.get("version", False): + cmd += "/" + kwargs["version"] else: - cmd += '/1.0' - r = salt.utils.http.query(cmd, decode_type='json', decode=True) - return r['dict'] + cmd += "/1.0" + r = salt.utils.http.query(cmd, decode_type="json", decode=True) + return r["dict"] def fix_outage(): - r = salt.utils.http.query(DETAILS['url']+'fix_outage') + r = salt.utils.http.query(DETAILS["url"] + "fix_outage") return r def uptodate(name): - ''' + """ Call the REST endpoint to see if the packages on the "server" are up to date. - ''' - r = salt.utils.http.query(DETAILS['url']+'package/remove/'+name, decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "package/remove/" + name, decode_type="json", decode=True + ) + return r["dict"] def package_remove(name): - ''' + """ Remove a "package" on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'package/remove/'+name, decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "package/remove/" + name, decode_type="json", decode=True + ) + return r["dict"] def package_status(name): - ''' + """ Check the installation status of a package on the REST server - ''' - r = salt.utils.http.query(DETAILS['url']+'package/status/'+name, decode_type='json', decode=True) - return r['dict'] + """ + r = salt.utils.http.query( + DETAILS["url"] + "package/status/" + name, decode_type="json", decode=True + ) + return r["dict"] def ping(): - ''' + """ Is the REST server up? - ''' - r = salt.utils.http.query(DETAILS['url']+'ping', decode_type='json', decode=True) + """ + r = salt.utils.http.query(DETAILS["url"] + "ping", decode_type="json", decode=True) try: - return r['dict'].get('ret', False) + return r["dict"].get("ret", False) except Exception: return False def shutdown(opts): - ''' + """ For this proxy shutdown is a no-op - ''' - log.debug('rest_sample proxy shutdown() called...') + """ + log.debug("rest_sample proxy shutdown() called...") .. _grains support code: @@ -702,19 +729,23 @@ Example from ``salt/grains/rest_sample.py``: .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ Generate baseline proxy minion grains - ''' + """ from __future__ import absolute_import import salt.utils.platform - __proxyenabled__ = ['rest_sample'] + __proxyenabled__ = ["rest_sample"] + + __virtualname__ = "rest_sample" - __virtualname__ = 'rest_sample' def __virtual__(): try: - if salt.utils.platform.is_proxy() and __opts__['proxy']['proxytype'] == 'rest_sample': + if ( + salt.utils.platform.is_proxy() + and __opts__["proxy"]["proxytype"] == "rest_sample" + ): return __virtualname__ except KeyError: pass @@ -746,12 +777,12 @@ This proxymodule enables "package" installation. .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ This is a simple proxy-minion designed to connect to and communicate with a server that exposes functionality via SSH. This can be used as an option when the device does not provide an api over HTTP and doesn't have the python stack to run a minion. - ''' + """ from __future__ import absolute_import # Import python libs @@ -763,7 +794,7 @@ This proxymodule enables "package" installation. from salt.utils.vt import TerminalException # This must be present or the Salt loader won't load this module - __proxyenabled__ = ['ssh_sample'] + __proxyenabled__ = ["ssh_sample"] DETAILS = {} @@ -774,25 +805,27 @@ This proxymodule enables "package" installation. # This does nothing, it's here just as an example and to provide a log # entry when the module is loaded. def __virtual__(): - ''' + """ Only return if all the modules are available - ''' - log.info('ssh_sample proxy __virtual__() called...') + """ + log.info("ssh_sample proxy __virtual__() called...") return True def init(opts): - ''' + """ Required. Can be used to initialize the server connection. - ''' + """ try: - DETAILS['server'] = SSHConnection(host=__opts__['proxy']['host'], - username=__opts__['proxy']['username'], - password=__opts__['proxy']['password']) + DETAILS["server"] = SSHConnection( + host=__opts__["proxy"]["host"], + username=__opts__["proxy"]["username"], + password=__opts__["proxy"]["password"], + ) # connected to the SSH server - out, err = DETAILS['server'].sendline('help') + out, err = DETAILS["server"].sendline("help") except TerminalException as e: log.error(e) @@ -800,73 +833,73 @@ This proxymodule enables "package" installation. def shutdown(opts): - ''' + """ Disconnect - ''' - DETAILS['server'].close_connection() + """ + DETAILS["server"].close_connection() def parse(out): - ''' + """ Extract json from out. Parameter out: Type string. The data returned by the ssh command. - ''' + """ jsonret = [] in_json = False - for ln_ in out.split('\n'): - if '{' in ln_: + for ln_ in out.split("\n"): + if "{" in ln_: in_json = True if in_json: jsonret.append(ln_) - if '}' in ln_: + if "}" in ln_: in_json = False - return salt.utils.json.loads('\n'.join(jsonret)) + return salt.utils.json.loads("\n".join(jsonret)) def package_list(): - ''' + """ List "packages" by executing a command via ssh This function is called in response to the salt command ..code-block::bash salt target_minion pkg.list_pkgs - ''' + """ # Send the command to execute - out, err = DETAILS['server'].sendline('pkg_list') + out, err = DETAILS["server"].sendline("pkg_list") # "scrape" the output and return the right fields as a dict return parse(out) def package_install(name, **kwargs): - ''' + """ Install a "package" on the REST server - ''' - cmd = 'pkg_install ' + name - if 'version' in kwargs: - cmd += '/'+kwargs['version'] + """ + cmd = "pkg_install " + name + if "version" in kwargs: + cmd += "/" + kwargs["version"] else: - cmd += '/1.0' + cmd += "/1.0" # Send the command to execute - out, err = DETAILS['server'].sendline(cmd) + out, err = DETAILS["server"].sendline(cmd) # "scrape" the output and return the right fields as a dict return parse(out) def package_remove(name): - ''' + """ Remove a "package" on the REST server - ''' - cmd = 'pkg_remove ' + name + """ + cmd = "pkg_remove " + name # Send the command to execute - out, err = DETAILS['server'].sendline(cmd) + out, err = DETAILS["server"].sendline(cmd) # "scrape" the output and return the right fields as a dict return parse(out) diff --git a/doc/topics/releases/0.9.3.rst b/doc/topics/releases/0.9.3.rst index 9b95f10e45c..c39f3365561 100644 --- a/doc/topics/releases/0.9.3.rst +++ b/doc/topics/releases/0.9.3.rst @@ -110,12 +110,12 @@ write Salt States in pure Python: #!py + def run(): - ''' + """ Install the python-mako package - ''' - return {'include': ['python'], - 'python-mako': {'pkg': ['installed']}} + """ + return {"include": ["python"], "python-mako": {"pkg": ["installed"]}} This renderer is used by making a run function that returns the Highstate data structure. Any capabilities of Python can be used in pure Python sls modules. diff --git a/doc/topics/releases/0.9.9.rst b/doc/topics/releases/0.9.9.rst index 6ee5564dc41..1020ce41ec5 100644 --- a/doc/topics/releases/0.9.9.rst +++ b/doc/topics/releases/0.9.9.rst @@ -162,8 +162,8 @@ This addition to the LocalClient api can be used like so: import salt.client - client = salt.client.LocalClient('/etc/salt/master') - ret = client.cmd('*', 'cmd.run', ['ls -l'], kwarg={'cwd': '/etc'}) + client = salt.client.LocalClient("/etc/salt/master") + ret = client.cmd("*", "cmd.run", ["ls -l"], kwarg={"cwd": "/etc"}) This update has been added to all cmd methods in the LocalClient class. diff --git a/doc/topics/releases/2016.11.0.rst b/doc/topics/releases/2016.11.0.rst index 4f9b8b7accc..aae3c8c0a30 100644 --- a/doc/topics/releases/2016.11.0.rst +++ b/doc/topics/releases/2016.11.0.rst @@ -378,10 +378,7 @@ eAuth Changes .. code-block:: python - [{'web*': ['test.*', - 'network.*']}, - '@wheel', - '@runner'] + [{"web*": ["test.*", "network.*"]}, "@wheel", "@runner"] - External auth is supported by :ref:`salt-run ` and :ref:`salt-key ` now. Note that master must be started to @@ -554,13 +551,15 @@ General Deprecations .. code-block:: python - def fcn(msg='', env='base', refresh=True, saltenv='base', **kwargs): + def fcn(msg="", env="base", refresh=True, saltenv="base", **kwargs): + ... has been changed to .. code-block:: python - def fcn(msg='', refresh=True, saltenv='base', **kwargs): + def fcn(msg="", refresh=True, saltenv="base", **kwargs): + ... - If ``env`` (or ``__env__``) is supplied as a keyword argument to a function that also accepts arbitrary keyword arguments, then a new warning informs the @@ -569,12 +568,13 @@ General Deprecations .. code-block:: python - def fcn(msg='', refresh=True, saltenv='base', **kwargs): + def fcn(msg="", refresh=True, saltenv="base", **kwargs): + ... .. code-block:: python # will result in a warning log message - fcn(msg='add more salt', env='prod', refresh=False) + fcn(msg="add more salt", env="prod", refresh=False) - If ``env`` (or ``__env__``) is supplied as a keyword argument to a function that does not accept arbitrary keyword arguments, then python will issue an @@ -582,12 +582,13 @@ General Deprecations .. code-block:: python - def fcn(msg='', refresh=True, saltenv='base'): + def fcn(msg="", refresh=True, saltenv="base"): + ... .. code-block:: python # will result in a python TypeError - fcn(msg='add more salt', env='prod', refresh=False) + fcn(msg="add more salt", env="prod", refresh=False) - If ``env`` (or ``__env__``) is supplied as a positional argument to a function, then undefined behavior will occur, as the removal of ``env`` and @@ -596,12 +597,13 @@ General Deprecations .. code-block:: python - def fcn(msg='', refresh=True, saltenv='base'): + def fcn(msg="", refresh=True, saltenv="base"): + ... .. code-block:: python # will result in refresh evaluating to True and saltenv likely not being a string at all - fcn('add more salt', 'prod', False) + fcn("add more salt", "prod", False) - Deprecations in ``minion.py``: diff --git a/doc/topics/releases/2016.3.0.rst b/doc/topics/releases/2016.3.0.rst index 4d75363142f..6bd91ba0669 100644 --- a/doc/topics/releases/2016.3.0.rst +++ b/doc/topics/releases/2016.3.0.rst @@ -156,12 +156,11 @@ they are being loaded for the correct proxytype, example below: .. code-block:: python def __virtual__(): - ''' + """ Only work on proxy - ''' + """ try: - if salt.utils.is_proxy() and \ - __opts__['proxy']['proxytype'] == 'ssh_sample': + if salt.utils.is_proxy() and __opts__["proxy"]["proxytype"] == "ssh_sample": return __virtualname__ except KeyError: pass @@ -185,10 +184,10 @@ to ``__proxy__``. This enables patterns like .. code-block:: python def get_ip(proxy): - ''' + """ Ask the remote device what IP it has - ''' - return {'ip':proxy['proxymodulename.get_ip']()} + """ + return {"ip": proxy["proxymodulename.get_ip"]()} Then the grain ``ip`` will contain the result of calling the ``get_ip()`` function diff --git a/doc/topics/releases/2017.7.0.rst b/doc/topics/releases/2017.7.0.rst index 4f9e26b744a..3f1de2a631c 100644 --- a/doc/topics/releases/2017.7.0.rst +++ b/doc/topics/releases/2017.7.0.rst @@ -675,7 +675,7 @@ Additional Features .. code-block:: python - ret1 = __salt__['salt.execute']('*', 'mod.fun') + ret1 = __salt__["salt.execute"]("*", "mod.fun") New Modules =========== diff --git a/doc/topics/releases/2018.3.0.rst b/doc/topics/releases/2018.3.0.rst index 6d99b62d02e..65e8e81e311 100644 --- a/doc/topics/releases/2018.3.0.rst +++ b/doc/topics/releases/2018.3.0.rst @@ -216,10 +216,10 @@ they failed. Here's some example pseudocode: def myrunner(): ... - do stuff + # do stuff ... if some_error_condition: - __context__['retcode'] = 1 + __context__["retcode"] = 1 return result Variable Update Intervals for Fileserver Backends diff --git a/doc/topics/return_codes/index.rst b/doc/topics/return_codes/index.rst index f96e995660c..e9862104f29 100644 --- a/doc/topics/return_codes/index.rst +++ b/doc/topics/return_codes/index.rst @@ -29,7 +29,7 @@ occurred: .. code-block:: python if something_went_wrong: - __context__['retcode'] = 42 + __context__["retcode"] = 42 This is actually how states signal that they have failed. Different cases result in different codes being set in the :ref:`__context__ ` diff --git a/doc/topics/sdb/index.rst b/doc/topics/sdb/index.rst index fae39687585..5d930a2e9e8 100644 --- a/doc/topics/sdb/index.rst +++ b/doc/topics/sdb/index.rst @@ -140,7 +140,7 @@ something like: .. code-block:: python - mykey = __salt__['config.get']('mykey') + mykey = __salt__["config.get"]("mykey") Templating renderers use a similar construct. To get the ``mykey`` value from above in Jinja, you would use: @@ -175,7 +175,7 @@ in the module as well: .. code-block:: python __func_alias__ = { - 'set_': 'set', + "set_": "set", } This is because ``set`` is a Python built-in, and therefore functions should not diff --git a/doc/topics/spm/dev.rst b/doc/topics/spm/dev.rst index 4a4d82129b2..e96355dca2e 100644 --- a/doc/topics/spm/dev.rst +++ b/doc/topics/spm/dev.rst @@ -41,7 +41,7 @@ connection object, then that connection object is returned. For instance, the .. code-block:: python - conn = sqlite3.connect(__opts__['spm_db'], isolation_level=None) + conn = sqlite3.connect(__opts__["spm_db"], isolation_level=None) ... return conn @@ -259,7 +259,7 @@ This function will not generally be more complex than: .. code-block:: python def hash_file(path, hashobj, conn=None): - with salt.utils.files.fopen(path, 'r') as f: + with salt.utils.files.fopen(path, "r") as f: hashobj.update(f.read()) return hashobj.hexdigest() diff --git a/doc/topics/troubleshooting/yaml_idiosyncrasies.rst b/doc/topics/troubleshooting/yaml_idiosyncrasies.rst index bbcd6ce1ed2..9c61c80cb0e 100644 --- a/doc/topics/troubleshooting/yaml_idiosyncrasies.rst +++ b/doc/topics/troubleshooting/yaml_idiosyncrasies.rst @@ -384,4 +384,4 @@ longer that 1024 characters. PyYAML enforces these limitations (see here__), and therefore anything parsed as YAML in Salt is subject to them. .. _`YAML Spec`: https://yaml.org/spec/1.2/spec.html#id2792424 -.. __: https://github.com/yaml/pyyaml/blob/eb459f8/lib/yaml/scanner.py#L279-L293 \ No newline at end of file +.. __: https://github.com/yaml/pyyaml/blob/eb459f8/lib/yaml/scanner.py#L279-L293 diff --git a/doc/topics/tutorials/http.rst b/doc/topics/tutorials/http.rst index 03cbc574b2d..31d0a5cdac8 100644 --- a/doc/topics/tutorials/http.rst +++ b/doc/topics/tutorials/http.rst @@ -64,14 +64,14 @@ single URL: .. code-block:: python - salt.utils.http.query('http://example.com') + salt.utils.http.query("http://example.com") By default the query will be performed with a ``GET`` method. The method can be overridden with the ``method`` argument: .. code-block:: python - salt.utils.http.query('http://example.com/delete/url', 'DELETE') + salt.utils.http.query("http://example.com/delete/url", "DELETE") When using the ``POST`` method (and others, such as ``PUT``), extra data is usually sent as well. This data can be sent directly (would be URL encoded when necessary), @@ -80,9 +80,7 @@ or in whatever format is required by the remote server (XML, JSON, plain text, e .. code-block:: python salt.utils.http.query( - 'http://example.com/post/url', - method='POST', - data=json.dumps(mydict) + "http://example.com/post/url", method="POST", data=json.dumps(mydict) ) Data Formatting and Templating @@ -96,9 +94,7 @@ the file (untemplated): .. code-block:: python salt.utils.http.query( - 'http://example.com/post/url', - method='POST', - data_file='/srv/salt/somefile.xml' + "http://example.com/post/url", method="POST", data_file="/srv/salt/somefile.xml" ) To pass through a file that contains jinja + yaml templating (the default): @@ -106,11 +102,11 @@ To pass through a file that contains jinja + yaml templating (the default): .. code-block:: python salt.utils.http.query( - 'http://example.com/post/url', - method='POST', - data_file='/srv/salt/somefile.jinja', + "http://example.com/post/url", + method="POST", + data_file="/srv/salt/somefile.jinja", data_render=True, - template_dict={'key1': 'value1', 'key2': 'value2'} + template_dict={"key1": "value1", "key2": "value2"}, ) To pass through a file that contains mako templating: @@ -118,12 +114,12 @@ To pass through a file that contains mako templating: .. code-block:: python salt.utils.http.query( - 'http://example.com/post/url', - method='POST', - data_file='/srv/salt/somefile.mako', + "http://example.com/post/url", + method="POST", + data_file="/srv/salt/somefile.mako", data_render=True, - data_renderer='mako', - template_dict={'key1': 'value1', 'key2': 'value2'} + data_renderer="mako", + template_dict={"key1": "value1", "key2": "value2"}, ) Because this function uses Salt's own rendering system, any Salt renderer can @@ -136,21 +132,21 @@ However, this can be changed to ``master`` if necessary. .. code-block:: python salt.utils.http.query( - 'http://example.com/post/url', - method='POST', - data_file='/srv/salt/somefile.jinja', + "http://example.com/post/url", + method="POST", + data_file="/srv/salt/somefile.jinja", data_render=True, - template_dict={'key1': 'value1', 'key2': 'value2'}, - opts=__opts__ + template_dict={"key1": "value1", "key2": "value2"}, + opts=__opts__, ) salt.utils.http.query( - 'http://example.com/post/url', - method='POST', - data_file='/srv/salt/somefile.jinja', + "http://example.com/post/url", + method="POST", + data_file="/srv/salt/somefile.jinja", data_render=True, - template_dict={'key1': 'value1', 'key2': 'value2'}, - node='master' + template_dict={"key1": "value1", "key2": "value2"}, + node="master", ) Headers @@ -165,12 +161,12 @@ a Python dict. .. code-block:: python salt.utils.http.query( - 'http://example.com/delete/url', - method='POST', - header_file='/srv/salt/headers.jinja', + "http://example.com/delete/url", + method="POST", + header_file="/srv/salt/headers.jinja", header_render=True, - header_renderer='jinja', - template_dict={'key1': 'value1', 'key2': 'value2'} + header_renderer="jinja", + template_dict={"key1": "value1", "key2": "value2"}, ) Because much of the data that would be templated between headers and data may be @@ -186,9 +182,7 @@ password may be passed in as ``username`` and ``password``, respectively. .. code-block:: python salt.utils.http.query( - 'http://example.com', - username='larry', - password='5700g3543v4r', + "http://example.com", username="larry", password="5700g3543v4r", ) Cookies and Sessions @@ -199,10 +193,7 @@ are turned off by default. To turn cookies on, set ``cookies`` to True. .. code-block:: python - salt.utils.http.query( - 'http://example.com', - cookies=True - ) + salt.utils.http.query("http://example.com", cookies=True) By default cookies are stored in Salt's cache directory, normally ``/var/cache/salt``, as a file called ``cookies.txt``. However, this location @@ -211,9 +202,7 @@ may be changed with the ``cookie_jar`` argument: .. code-block:: python salt.utils.http.query( - 'http://example.com', - cookies=True, - cookie_jar='/path/to/cookie_jar.txt' + "http://example.com", cookies=True, cookie_jar="/path/to/cookie_jar.txt" ) By default, the format of the cookie jar is LWP (aka, lib-www-perl). This @@ -223,10 +212,10 @@ format of the cookie jar can be set to Mozilla: .. code-block:: python salt.utils.http.query( - 'http://example.com', + "http://example.com", cookies=True, - cookie_jar='/path/to/cookie_jar.txt', - cookie_format='mozilla' + cookie_jar="/path/to/cookie_jar.txt", + cookie_format="mozilla", ) Because Salt commands are normally one-off commands that are piped together, @@ -238,9 +227,7 @@ Salt's cache directory, is ``cookies.session.p``. This can also be changed. .. code-block:: python salt.utils.http.query( - 'http://example.com', - persist_session=True, - session_cookie_jar='/path/to/jar.p' + "http://example.com", persist_session=True, session_cookie_jar="/path/to/jar.p" ) The format of this file is msgpack, which is consistent with much of the rest @@ -265,11 +252,7 @@ these are set in the minion configuration file. .. code-block:: python - salt.utils.http.query( - 'http://example.com', - opts=__opts__, - backend='tornado' - ) + salt.utils.http.query("http://example.com", opts=__opts__, backend="tornado") Return Data ~~~~~~~~~~~ @@ -294,10 +277,7 @@ force either JSON or XML decoding, the ``decode_type`` may be set: .. code-block:: python - salt.utils.http.query( - 'http://example.com', - decode_type='xml' - ) + salt.utils.http.query("http://example.com", decode_type="xml") Once translated, the return dict from ``query()`` will include a dict called ``dict``. @@ -307,10 +287,7 @@ turned off. .. code-block:: python - salt.utils.http.query( - 'http://example.com', - decode=False - ) + salt.utils.http.query("http://example.com", decode=False) If decoding is turned on, and references to JSON or XML cannot be found, then this module will default to plain text, and return the undecoded data as @@ -321,12 +298,7 @@ as required. However, each must individually be turned on. .. code-block:: python - salt.utils.http.query( - 'http://example.com', - status=True, - headers=True, - text=True - ) + salt.utils.http.query("http://example.com", status=True, headers=True, text=True) The return from these will be found in the return dict as ``status``, ``headers`` and ``text``, respectively. @@ -341,11 +313,11 @@ to be returned to the user in order to do this. .. code-block:: python salt.utils.http.query( - 'http://example.com', + "http://example.com", text=False, headers=False, - text_out='/path/to/url_download.txt', - headers_out='/path/to/headers_download.txt', + text_out="/path/to/url_download.txt", + headers_out="/path/to/headers_download.txt", ) SSL Verification @@ -356,8 +328,7 @@ debugging purposes, SSL verification can be turned off. .. code-block:: python salt.utils.http.query( - 'https://example.com', - verify_ssl=False, + "https://example.com", verify_ssl=False, ) CA Bundles @@ -373,8 +344,7 @@ using the ``ca_bundle`` variable. .. code-block:: python salt.utils.http.query( - 'https://example.com', - ca_bundle='/path/to/ca_bundle.pem', + "https://example.com", ca_bundle="/path/to/ca_bundle.pem", ) Updating CA Bundles @@ -395,8 +365,8 @@ download which is hazardous or does not meet the needs of the user. .. code-block:: python salt.utils.http.update_ca_bundle( - target='/path/to/ca-bundle.crt', - source='https://example.com/path/to/ca-bundle.crt', + target="/path/to/ca-bundle.crt", + source="https://example.com/path/to/ca-bundle.crt", opts=__opts__, ) @@ -423,10 +393,10 @@ otherwise reasonable to add to the bundle file. salt.utils.http.update_ca_bundle( opts=__opts__, merge_files=[ - '/etc/ssl/private_cert_1.pem', - '/etc/ssl/private_cert_2.pem', - '/etc/ssl/private_cert_3.pem', - ] + "/etc/ssl/private_cert_1.pem", + "/etc/ssl/private_cert_2.pem", + "/etc/ssl/private_cert_3.pem", + ], ) diff --git a/doc/topics/tutorials/jinja_to_execution_module.rst b/doc/topics/tutorials/jinja_to_execution_module.rst index 91500f4f82d..27c54d75271 100644 --- a/doc/topics/tutorials/jinja_to_execution_module.rst +++ b/doc/topics/tutorials/jinja_to_execution_module.rst @@ -100,31 +100,33 @@ Note how the module encapsulates all of the logic around finding the storage ser # _modules/storage.py #!python - ''' + """ Functions related to storage servers. - ''' + """ import re def ips(): - ''' + """ Provide a list of all local storage server IPs. CLI Example:: salt \* storage.ips - ''' + """ - if __grains__.get('virtual', None) in ['VirtualBox', 'oracle']: - return ['192.168.33.51', ] + if __grains__.get("virtual", None) in ["VirtualBox", "oracle"]: + return [ + "192.168.33.51", + ] - colo = __pillar__.get('inventory', {}).get('colo', 'Unknown') - return __pillar__.get('storage_servers', {}).get(colo, ['unknown', ]) + colo = __pillar__.get("inventory", {}).get("colo", "Unknown") + return __pillar__.get("storage_servers", {}).get(colo, ["unknown",]) def ip(): - ''' + """ Select and return a local storage server IP. This loadbalances across storage servers by using the modulus of the client's id number. @@ -138,12 +140,12 @@ Note how the module encapsulates all of the logic around finding the storage ser salt \* storage.ip - ''' + """ - numerical_suffix = re.compile(r'^.*(\d+)$') + numerical_suffix = re.compile(r"^.*(\d+)$") servers_list = ips() - m = numerical_suffix.match(__grains__['id']) + m = numerical_suffix.match(__grains__["id"]) if m: modulus = len(servers_list) server_number = int(m.group(1)) diff --git a/doc/topics/tutorials/packaging_modules.rst b/doc/topics/tutorials/packaging_modules.rst index ee522935110..ba7d327e96e 100644 --- a/doc/topics/tutorials/packaging_modules.rst +++ b/doc/topics/tutorials/packaging_modules.rst @@ -11,7 +11,7 @@ The salt loader was enhanced to look for external modules by looking at the `salt.loader` entry-point: https://setuptools.readthedocs.io/en/latest/pkg_resources.html#entry-points - + `pkg_resources` should be installed, which is normally included in setuptools. https://setuptools.readthedocs.io/en/latest/pkg_resources.html @@ -24,21 +24,23 @@ function: from setuptools import setup, find_packages - setup(name=, - version=, - description=, - author=, - author_email=, - url=' ... ', - packages=find_packages(), - entry_points=''' - [salt.loader] - engines_dirs = .:engines_dirs - fileserver_dirs = .:fileserver_dirs - pillar_dirs = .:pillar_dirs - returner_dirs = .:returner_dirs - roster_dirs = .:roster_dirs - ''') + setup( + name=, + version=, + description=, + author=, + author_email=, + url=" ... ", + packages=find_packages(), + entry_points=""" + [salt.loader] + engines_dirs = .:engines_dirs + fileserver_dirs = .:fileserver_dirs + pillar_dirs = .:pillar_dirs + returner_dirs = .:returner_dirs + roster_dirs = .:roster_dirs + """ + ) The above setup script example mentions a loader module. here's an example of diff --git a/doc/topics/tutorials/rooted.rst b/doc/topics/tutorials/rooted.rst index 237fbb9505a..9895ae3bf90 100644 --- a/doc/topics/tutorials/rooted.rst +++ b/doc/topics/tutorials/rooted.rst @@ -37,22 +37,24 @@ Edit it to include needed variables and your new paths .. code-block:: python # you need to edit this - ROOT_DIR = *your current dir* + '/salt/root' + _your_current_dir_ = ... + ROOT_DIR = _your_current_dir_ + "/salt/root" # you need to edit this - INSTALL_DIR = *location of source code* + _location_of_source_code_ = ... + INSTALL_DIR = _location_of_source_code_ - CONFIG_DIR = ROOT_DIR + '/etc/salt' - CACHE_DIR = ROOT_DIR + '/var/cache/salt' - SOCK_DIR = ROOT_DIR + '/var/run/salt' - SRV_ROOT_DIR= ROOT_DIR + '/srv' - BASE_FILE_ROOTS_DIR = ROOT_DIR + '/srv/salt' - BASE_PILLAR_ROOTS_DIR = ROOT_DIR + '/srv/pillar' - BASE_MASTER_ROOTS_DIR = ROOT_DIR + '/srv/salt-master' - LOGS_DIR = ROOT_DIR + '/var/log/salt' - PIDFILE_DIR = ROOT_DIR + '/var/run' - CLOUD_DIR = INSTALL_DIR + '/cloud' - BOOTSTRAP = CLOUD_DIR + '/deploy/bootstrap-salt.sh' + CONFIG_DIR = ROOT_DIR + "/etc/salt" + CACHE_DIR = ROOT_DIR + "/var/cache/salt" + SOCK_DIR = ROOT_DIR + "/var/run/salt" + SRV_ROOT_DIR = ROOT_DIR + "/srv" + BASE_FILE_ROOTS_DIR = ROOT_DIR + "/srv/salt" + BASE_PILLAR_ROOTS_DIR = ROOT_DIR + "/srv/pillar" + BASE_MASTER_ROOTS_DIR = ROOT_DIR + "/srv/salt-master" + LOGS_DIR = ROOT_DIR + "/var/log/salt" + PIDFILE_DIR = ROOT_DIR + "/var/run" + CLOUD_DIR = INSTALL_DIR + "/cloud" + BOOTSTRAP = CLOUD_DIR + "/deploy/bootstrap-salt.sh" Create the directory structure diff --git a/doc/topics/tutorials/starting_states.rst b/doc/topics/tutorials/starting_states.rst index 1f0782efe9e..3f453777b7e 100644 --- a/doc/topics/tutorials/starting_states.rst +++ b/doc/topics/tutorials/starting_states.rst @@ -484,12 +484,12 @@ This example shows a very basic Python SLS file: #!py + def run(): - ''' + """ Install the django package - ''' - return {'include': ['python'], - 'django': {'pkg': ['installed']}} + """ + return {"include": ["python"], "django": {"pkg": ["installed"]}} This is a very simple example; the first line has an SLS shebang that tells Salt to not use the default renderer, but to use the ``py`` renderer. @@ -504,8 +504,8 @@ renderer, the above example can be written more succinctly as: #!pydsl - include('python', delayed=True) - state('django').pkg.installed() + include("python", delayed=True) + state("django").pkg.installed() The :mod:`pyobjects` renderer provides an `"Pythonic"`_ object based approach for building the state data. @@ -515,7 +515,7 @@ The above example could be written as: #!pyobjects - include('python') + include("python") Pkg.installed("django") diff --git a/doc/topics/tutorials/states_pt3.rst b/doc/topics/tutorials/states_pt3.rst index e355d5617b7..a43bbaf915c 100644 --- a/doc/topics/tutorials/states_pt3.rst +++ b/doc/topics/tutorials/states_pt3.rst @@ -146,7 +146,8 @@ a value equivalent to the following python pseudo-code: .. code-block:: python import salt.modules.file - file.group_to_gid('some_group_that_exists') + + file.group_to_gid("some_group_that_exists") Note that for the above example to work, ``some_group_that_exists`` must exist before the state file is processed by the templating engine. @@ -156,7 +157,7 @@ MAC address for eth0: .. code-block:: python - salt['network.hw_addr']('eth0') + salt["network.hw_addr"]("eth0") To examine the possible arguments to each execution module function, one can examine the `module reference documentation `_: diff --git a/doc/topics/tutorials/writing_tests.rst b/doc/topics/tutorials/writing_tests.rst index cbe98a76b0d..8845d9bb167 100644 --- a/doc/topics/tutorials/writing_tests.rst +++ b/doc/topics/tutorials/writing_tests.rst @@ -139,10 +139,10 @@ file: .. code-block:: python def test_ping(self): - ''' + """ test.ping - ''' - self.assertTrue(self.run_function('test.ping')) + """ + self.assertTrue(self.run_function("test.ping")) The test above is a very simple example where the ``test.ping`` function is executed by Salt's test suite runner and is asserting that the minion returned @@ -254,20 +254,20 @@ minion's return is expected. .. code-block:: python def test_ping(self): - ''' + """ test.ping - ''' - self.assertTrue(self.run_function('test.ping')) + """ + self.assertTrue(self.run_function("test.ping")) Args can be passed in to the ``run_function`` method as well: .. code-block:: python def test_echo(self): - ''' + """ test.echo - ''' - self.assertEqual(self.run_function('test.echo', ['text']), 'text') + """ + self.assertEqual(self.run_function("test.echo", ["text"]), "text") The next example is taken from the ``tests/integration/modules/test_aliases.py`` file and @@ -279,18 +279,13 @@ call should return. .. code-block:: python def test_set_target(self): - ''' + """ aliases.set_target and aliases.get_target - ''' - set_ret = self.run_function( - 'aliases.set_target', - alias='fred', - target='bob') + """ + set_ret = self.run_function("aliases.set_target", alias="fred", target="bob") self.assertTrue(set_ret) - tgt_ret = self.run_function( - 'aliases.get_target', - alias='fred') - self.assertEqual(tgt_ret, 'bob') + tgt_ret = self.run_function("aliases.get_target", alias="fred") + self.assertEqual(tgt_ret, "bob") Using multiple Salt commands in this manner provides two useful benefits. The first is that it provides some additional coverage for the ``aliases.set_target`` function. @@ -335,12 +330,13 @@ the test method: import integration from tests.support.helpers import destructiveTest + class PkgTest(integration.ModuleCase): @destructiveTest def test_pkg_install(self): - ret = self.run_function('pkg.install', name='finch') + ret = self.run_function("pkg.install", name="finch") self.assertSaltTrueReturn(ret) - ret = self.run_function('pkg.purge', name='finch') + ret = self.run_function("pkg.purge", name="finch") self.assertSaltTrueReturn(ret) @@ -372,13 +368,13 @@ testing the call to ``cp.hash_file``, which is used in ``cp.get_file``. .. code-block:: python def test_get_file_not_found(self): - ''' + """ Test if get_file can't find the file. - ''' - with patch('salt.modules.cp.hash_file', MagicMock(return_value=False)): - path = 'salt://saltines' - dest = '/srv/salt/cheese' - ret = '' + """ + with patch("salt.modules.cp.hash_file", MagicMock(return_value=False)): + path = "salt://saltines" + dest = "/srv/salt/cheese" + ret = "" assert cp.get_file(path, dest) == ret Note that Salt's ``cp`` module is imported at the top of the file, along with all @@ -446,10 +442,10 @@ can be used # .. inside test with TstSuiteLoggingHandler() as handler: for message in handler.messages: - if message.startswith('ERROR: This is the error message we seek'): + if message.startswith("ERROR: This is the error message we seek"): break else: - raise AssertionError('Did not find error message') + raise AssertionError("Did not find error message") Automated Test Runs diff --git a/doc/topics/utils/index.rst b/doc/topics/utils/index.rst index c0257f9d616..bf156e4a31b 100644 --- a/doc/topics/utils/index.rst +++ b/doc/topics/utils/index.rst @@ -23,15 +23,16 @@ For example, assuming the following simple utility module, saved to .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ My utils module --------------- This module contains common functions for use in my other custom types. - ''' + """ + def bar(): - return 'baz' + return "baz" Once synced to a minion, this function would be available to other custom Salt types like so: @@ -39,13 +40,14 @@ types like so: .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ My awesome execution module --------------------------- - ''' + """ + def observe_the_awesomeness(): - ''' + """ Prints information from my utility module CLI Example: @@ -53,8 +55,8 @@ types like so: .. code-block:: bash salt '*' mymodule.observe_the_awesomeness - ''' - return __utils__['foo.bar']() + """ + return __utils__["foo.bar"]() Utility modules, like any other kind of Salt extension, support using a :ref:`__virtual__ function ` to conditionally load them, @@ -65,21 +67,23 @@ the ``foo`` utility module with a ``__virtual__`` function. .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ My utils module --------------- This module contains common functions for use in my other custom types. - ''' + """ + def __virtual__(): - ''' + """ Load as a different name - ''' - return 'foo' + """ + return "foo" + def bar(): - return 'baz' + return "baz" .. versionadded:: 2018.3.0 Instantiating objects from classes declared in util modules works with @@ -90,35 +94,36 @@ Also you could even write your utility modules in object oriented fashion: .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ My OOP-style utils module ------------------------- This module contains common functions for use in my other custom types. - ''' + """ + class Foo(object): - def __init__(self): pass def bar(self): - return 'baz' + return "baz" And import them into other custom modules: .. code-block:: python # -*- coding: utf-8 -*- - ''' + """ My awesome execution module --------------------------- - ''' + """ import mymodule + def observe_the_awesomeness(): - ''' + """ Prints information from my utility module CLI Example: @@ -126,7 +131,7 @@ And import them into other custom modules: .. code-block:: bash salt '*' mymodule.observe_the_awesomeness - ''' + """ foo = mymodule.Foo() return foo.bar() diff --git a/doc/topics/yaml/index.rst b/doc/topics/yaml/index.rst index bd2a7767f6c..5d5bce5e8bc 100644 --- a/doc/topics/yaml/index.rst +++ b/doc/topics/yaml/index.rst @@ -40,7 +40,7 @@ In Python, the above maps to: .. code-block:: python - {'my_key': 'my_value'} + {"my_key": "my_value"} Alternatively, a value can be associated with a key through indentation. @@ -58,7 +58,7 @@ In Python, the above maps to: .. code-block:: python - {'my_key': 'my_value'} + {"my_key": "my_value"} Dictionaries can be nested: @@ -71,11 +71,7 @@ And in Python: .. code-block:: python - { - 'first_level_dict_key': { - 'second_level_dict_key': 'value_in_second_level_dict' - } - } + {"first_level_dict_key": {"second_level_dict_key": "value_in_second_level_dict"}} Rule Three: Dashes ------------------ @@ -102,7 +98,7 @@ In Python, the above maps to: .. code-block:: python - {'my_dictionary': ['list_value_one', 'list_value_two', 'list_value_three']} + {"my_dictionary": ["list_value_one", "list_value_two", "list_value_three"]} Learning More -------------