saltstack/salt

View on GitHub
salt/pillar/foreman.py

Summary

Maintainability
A
55 mins
Test Coverage
# -*- strcoding: utf-8 -*-
'''
A module to pull data from Foreman via its API into the Pillar dictionary


Configuring the Foreman ext_pillar
==================================

Set the following Salt config to setup Foreman as external pillar source:

.. code-block:: yaml

  ext_pillar:
    - foreman:
        key: foreman # Nest results within this key
        only: ['hostgroup_name', 'parameters'] # Add only these keys to pillar

  foreman.url: https://example.com/foreman_api
  foreman.user: username # default is admin
  foreman.password: password # default is changeme

The following options are optional:

.. code-block:: yaml

  foreman.api: apiversion # default is 2 (1 is not supported yet)
  foreman.verifyssl: False # default is True
  foreman.certfile: /etc/ssl/certs/mycert.pem # default is None
  foreman.keyfile: /etc/ssl/private/mykey.pem # default is None
  foreman.cafile: /etc/ssl/certs/mycert.ca.pem # default is None
  foreman.lookup_parameters: True # default is True

An alternative would be to use the Foreman modules integrating Salt features
in the Smart Proxy and the webinterface.

Further information can be found on `GitHub <https://github.com/theforeman/foreman_salt>`_.

Module Documentation
====================
'''
from __future__ import absolute_import, print_function, unicode_literals

# Import python libs
import logging

from salt.ext import six
try:
    import requests
    HAS_REQUESTS = True
except ImportError:
    HAS_REQUESTS = False

__opts__ = {'foreman.url': 'http://foreman/api',
            'foreman.user': 'admin',
            'foreman.password': 'changeme',
            'foreman.api': 2,
            'foreman.verifyssl': True,
            'foreman.certfile': None,
            'foreman.keyfile': None,
            'foreman.cafile': None,
            'foreman.lookup_parameters': True,
           }


# Set up logging
log = logging.getLogger(__name__)

# Declare virtualname
__virtualname__ = 'foreman'


def __virtual__():
    '''
    Only return if all the modules are available
    '''
    if not HAS_REQUESTS:
        return False
    return __virtualname__


def ext_pillar(minion_id,
               pillar,  # pylint: disable=W0613
               key=None,
               only=()):
    '''
    Read pillar data from Foreman via its API.
    '''
    url = __opts__['foreman.url']
    user = __opts__['foreman.user']
    password = __opts__['foreman.password']
    api = __opts__['foreman.api']
    verify = __opts__['foreman.verifyssl']
    certfile = __opts__['foreman.certfile']
    keyfile = __opts__['foreman.keyfile']
    cafile = __opts__['foreman.cafile']
    lookup_parameters = __opts__['foreman.lookup_parameters']

    log.info("Querying Foreman at %r for information for %r", url, minion_id)
    try:
        # Foreman API version 1 is currently not supported
        if api != 2:
            log.error('Foreman API v2 is supported only, please specify'
                    'version 2 in your Salt master config')
            raise Exception

        headers = {'accept': 'version=' + six.text_type(api) + ',application/json'}

        if verify and cafile is not None:
            verify = cafile

        resp = requests.get(
                url + '/hosts/' + minion_id,
                auth=(user, password),
                headers=headers,
                verify=verify,
                cert=(certfile, keyfile)
                )
        result = resp.json()

        log.debug('Raw response of the Foreman request is %r', result)

        if lookup_parameters:
            parameters = dict()
            for param in result['all_parameters']:
                parameters.update({param['name']: param['value']})

            result['parameters'] = parameters

        if only:
            result = dict((k, result[k]) for k in only if k in result)

    except Exception:
        log.exception(
            'Could not fetch host data via Foreman API:'
        )
        return {}

    if key:
        result = {key: result}

    return result