saltstack/salt

View on GitHub
salt/modules/salt_version.py

Summary

Maintainability
A
0 mins
Test Coverage
# -*- coding: utf-8 -*-
'''
Access Salt's elemental release code-names.

.. versionadded:: Neon

Salt's feature release schedule is based on the Periodic Table, as described
in the :ref:`Version Numbers <version-numbers>` documentation.

Since deprecation notices often use the elemental release code-name when warning
users about deprecated changes, it can be difficult to build out future-proof
functionality that are dependent on a naming scheme that moves.

For example, a state syntax needs to change to support an option that will be
removed in the future, but there are many Minion versions in use across an
infrastructure. It would be handy to use some Jinja syntax to check for these
instances to perform one state syntax over another.

A simple example might be something like the following:

.. code-block:: jinja

    {# a boolean check #}
    {% set option_deprecated = salt['salt_version.is_older']("Sodium") %}

    {% if option_deprecated %}
      <use old syntax>
    {% else %}
      <use new syntax>
    {% endif %}

'''

# Import Python libs
from __future__ import absolute_import, print_function, unicode_literals
import logging

# Import Salt libs
from salt.ext import six
import salt.version
import salt.utils.versions


log = logging.getLogger(__name__)

__virtualname__ = 'salt_version'


def __virtual__():
    '''
    Only work on POSIX-like systems
    '''
    return __virtualname__


def get_release_number(name):
    '''
    Returns the release number of a given release code name in a
    ``<year>.<month>`` context.

    If the release name has not been given an assigned release number, the
    function returns a string. If the release cannot be found, it returns
    ``None``.

    name
        The release codename for which to find a release number.

    CLI Example:

    .. code-block:: bash

        salt '*' salt_version.get_release_number 'Oxygen'
    '''
    name = name.lower()
    version_map = salt.version.SaltStackVersion.LNAMES
    version = version_map.get(name)
    if version is None:
        log.info('Version %s not found.', name)
        return None

    if version[1] == 0:
        log.info('Version %s found, but no release number has been assigned yet.', name)
        return 'No version assigned.'

    return '.'.join(str(item) for item in version)


def is_equal(name):
    '''
    Returns a boolean if the named version matches the minion's current Salt
    version.

    name
        The release codename to check the version against.

    CLI Example:

    .. code-block:: bash

        salt '*' salt_version.is_equal 'Oxygen'
    '''
    if _check_release_cmp(name) == 0:
        log.info('Release codename \'%s\' equals the minion\'s version.', name)
        return True

    return False


def is_newer(name):
    '''
    Returns a boolean if the named version is newer that the minion's current
    Salt version.

    name
        The release codename to check the version against.

    CLI Example:

    .. code-block:: bash

        salt '*' salt_version.is_newer 'Sodium'
    '''
    if _check_release_cmp(name) == 1:
        log.info('Release codename \'%s\' is newer than the minion\'s version.', name)
        return True

    return False


def is_older(name):
    '''
    Returns a boolean if the named version is older that the minion's current
    Salt version.

    name
        The release codename to check the version against.

    CLI Example:

    .. code-block:: bash

        salt '*' salt_version.is_newer 'Sodium'
    '''
    if _check_release_cmp(name) == -1:
        log.info('Release codename \'%s\' is older than the minion\'s version.', name)
        return True

    return False


def _check_release_cmp(name):
    '''
    Helper function to compare release codename versions to the minion's current
    Salt version.

    If release codename isn't found, the function returns None. Otherwise, it
    returns the results of the version comparison as documented by the
    ``versions_cmp`` function in ``salt.utils.versions.py``.
    '''
    map_version = get_release_number(name)
    if map_version is None:
        log.info('Release codename %s was not found.', name)
        return None

    current_version = six.text_type(salt.version.SaltStackVersion(
        *salt.version.__version_info__))
    current_version = current_version.rsplit('.', 1)[0]
    version_cmp = salt.utils.versions.version_cmp(map_version, current_version)

    return version_cmp