# https://github.com/ansible/ansible/issues/43462
    if hasattr(pexpect, 'spawn'):
        argspec = getargspec(pexpect.spawn.__init__)
        if 'echo' in argspec.args:
            HAS_PEXPECT = True
except ImportError as e:
    pass

# used to try and parse the hostname and detect if IPv6 is being used
try:
    import ipaddress
    HAS_IPADDRESS = True
except ImportError:
    HAS_IPADDRESS = False

display = Display()


class Connection(ConnectionBase):
    '''WinRM connections over HTTP/HTTPS.'''

    transport = 'winrm'
    module_implementation_preferences = ('.ps1', '.exe', '')
    become_methods = ['runas']
    allow_executable = False
    has_pipelining = True
    allow_extras = True

    def __init__(self, *args, **kwargs):

        self.always_pipeline_modules = True
#  try:
#     from __main__ import display
#   except ImportError:
#     from ansible.utils.display import Display
#     display = Display()
#
# This means that the verbosity-parameter of display _always_ default to
# zero. There is no sane way to overwrite this. Within a normal ansible
# setup __main__ corresponds to the current executable (e.g. "ansible-playbook"),
# which creates a Display instance based on the cli parameters (-v, -vv, ...).
#
# This has to happen before anything from ansible is imported!
import __main__
from ansible.utils.display import Display

__main__.display = Display()

import ansible.constants
from ansible.executor.playbook_executor import PlaybookExecutor
from ansible.parsing.dataloader import DataLoader
from ansible.plugins.callback import CallbackBase
import ansible.release

ANSIBLE_VERSION = LooseVersion(ansible.release.__version__)

if ANSIBLE_VERSION < LooseVersion('2.4.0'):
    from ansible.inventory import Inventory
    from ansible.vars import VariableManager
else:
    from ansible.inventory.manager import InventoryManager
    from ansible.vars.manager import VariableManager
 def display(*args, **kwargs):
     """Set up display function for Ansible v2"""
     display_instance = Display()
     display_instance.display(*args, **kwargs)
Exemple #4
0
    def run(self, terms, variables=None, **kwargs):

        netbox_api_token = kwargs.get("token")
        netbox_api_endpoint = kwargs.get("api_endpoint")
        netbox_ssl_verify = kwargs.get("validate_certs")
        netbox_private_key_file = kwargs.get("key_file")
        netbox_api_filter = kwargs.get("api_filter")
        netbox_raw_return = kwargs.get("raw_data")

        if not isinstance(terms, list):
            terms = [terms]

        try:
            netbox = pynetbox.api(
                netbox_api_endpoint,
                token=netbox_api_token if netbox_api_token else None,
                ssl_verify=netbox_ssl_verify,
                private_key_file=netbox_private_key_file,
            )
        except FileNotFoundError:
            raise AnsibleError(
                "%s cannot be found. Please make sure file exists." %
                netbox_private_key_file)

        results = []
        for term in terms:

            try:
                endpoint = get_endpoint(netbox, term)
            except KeyError:
                raise AnsibleError(
                    "Unrecognised term %s. Check documentation" % term)

            Display().vvvv(
                u"Netbox lookup for %s to %s using token %s filter %s" %
                (term, netbox_api_endpoint, netbox_api_token,
                 netbox_api_filter))

            if netbox_api_filter:
                args_split = split_args(netbox_api_filter)
                args = [parse_kv(x) for x in args_split]
                filter = {}
                for arg in args:
                    for k, v in arg.items():
                        if k not in filter:
                            filter[k] = list()
                            filter[k].append(v)
                        else:
                            filter[k].append(v)

                Display().vvvv("filter is %s" % filter)

                for res in endpoint.filter(**filter):

                    Display().vvvvv(pformat(dict(res)))

                    if netbox_raw_return:
                        results.append(dict(res))

                    else:
                        key = dict(res)["id"]
                        result = {key: dict(res)}
                        results.extend(self._flatten_hash_to_list(result))

            else:
                for res in endpoint.all():

                    Display().vvvvv(pformat(dict(res)))

                    if netbox_raw_return:
                        results.append(dict(res))

                    else:
                        key = dict(res)["id"]
                        result = {key: dict(res)}
                        results.extend(self._flatten_hash_to_list(result))

        return results
Exemple #5
0
 - device_metadata:
   - cores: 1

# filter devices with interface in the specified space
filter:
 - device_intf_space: AWS

# use metadata for grouping, the group key1 will contain
# subgroup for each value (eg key1_on and key1_off)
group_metadata:
 - key1
 - key2

'''

DISPLAY = Display()


class InventoryModule(BaseInventoryPlugin, Constructable, Cacheable):
    """ dynamic inventory module for EfficientIP Device Manager"""
    NAME = 'community.general.efficientip'

    sds = None
    space = None
    device_filter = []
    limit = 0
    group_metadata = []
    group_metadata_val = []

    def __init__(self):
        """ initialize the inventory module """
Exemple #6
0
def defined(value,
            test_value=None,
            var_type=None,
            fail_action=None,
            var_name=None):
    """
    defined - Ansible test plugin to test if a variable is defined and not none

    Arista.avd.defined will test value if defined and is not none and return true or false.
    If test_value is supplied, the value must also pass == test_value to return true.
    If var_type is supplied, the value must also be of the specified class/type
    If fail_action is 'warning' a warning will be emitted on failure.
    If fail_action is 'error' an error will be emitted on failure and the task will fail.
    If var_name is supplied it will be used in the warning and error messages to ease troubleshooting.

    Examples:
    1. Test if var is defined and not none:
    {% if spanning_tree is arista.avd.defined %}
    ...
    {% endif %}

    2. Test if variable is defined, not none and has value "something"
    {% if extremely_long_variable_name is arista.avd.defined("something") %}
    ...
    {% endif %}

    3. Test if variable is defined and of not print a warning message with the variable name
    {% if my_dict.my_list[12].my_var is arista.avd.defined(fail_action='warning', var_name='my_dict.my_list[12].my_var' %}

    Parameters
    ----------
    value : any
        Value to test from ansible
    test_value : any, optional
        Value to test in addition of defined and not none, by default None
    var_type : ['float', 'int', 'str', 'list', 'dict', 'tuple'], optional
        Type or Class to test for
    fail_action : ['warning', 'error'], optional
        Optional action if test fails to emit a Warning or Error
    var_name : <string>, optional
        Optional string to use as variable name in warning or error messages

    Returns
    -------
    boolean
        True if variable matches criteria, False in other cases.
    """
    if isinstance(value, Undefined) or value is None:
        # Invalid value - return false
        if str(fail_action).lower() == 'warning':
            if var_name is not None:
                Display().warning(
                    f"{var_name} was expected but not set. Output may be incorrect or incomplete!"
                )
            else:
                Display().warning(
                    "A variable was expected but not set. Output may be incorrect or incomplete!"
                )
        elif str(fail_action).lower() == 'error':
            if var_name is not None:
                raise AnsibleError(f"{var_name} was expected but not set!")
            else:
                raise AnsibleError("A variable was expected but not set!")
        return False
    elif test_value is not None and value != test_value:
        # Valid value but not matching the optional argument
        if str(fail_action).lower() == 'warning':
            if var_name is not None:
                Display().warning(
                    f"{var_name} was set to {value} but we expected {test_value}. Output may be incorrect or incomplete!"
                )
            else:
                Display().warning(
                    f"A variable was set to {value} but we expected {test_value}. Output may be incorrect or incomplete!"
                )
        elif str(fail_action).lower() == 'error':
            if var_name is not None:
                raise AnsibleError(
                    f"{var_name} was set to {value} but we expected {test_value}!"
                )
            else:
                raise AnsibleError(
                    f"A variable was set to {value} but we expected {test_value}!"
                )
        return False
    elif str(var_type).lower() in [
            'float', 'int', 'str', 'list', 'dict', 'tuple'
    ] and str(var_type).lower() != type(value).__name__:
        # Invalid class - return false
        if str(fail_action).lower() == 'warning':
            if var_name is not None:
                Display().warning(
                    f"{var_name} was a {type(value).__name__} but we expected a {str(var_type).lower()}. Output may be incorrect or incomplete!"
                )
            else:
                Display().warning(
                    f"A variable was a {type(value).__name__} but we expected a {str(var_type).lower()}. Output may be incorrect or incomplete!"
                )
        elif str(fail_action).lower() == 'error':
            if var_name is not None:
                raise AnsibleError(
                    f"{var_name} was a {type(value).__name__} but we expected a {str(var_type).lower()}!"
                )
            else:
                raise AnsibleError(
                    f"A variable was a {type(value).__name__} but we expected a {str(var_type).lower()}!"
                )
        return False
    else:
        # Valid value and is matching optional argument if provided - return true
        return True
Exemple #7
0
def display(*args, **kwargs):
    display_instance = Display()
    display_instance.display(*args, **kwargs)
Exemple #8
0
import difflib
import warnings
from copy import deepcopy

from ansible.compat.six import string_types

from ansible import constants as C
from ansible.vars import strip_internal_keys
from ansible.utils.color import stringc
from ansible.utils.unicode import to_unicode

try:
    from __main__ import display as global_display
except ImportError:
    from ansible.utils.display import Display
    global_display = Display()

__all__ = ["CallbackBase"]

try:
    from __main__ import cli
except ImportError:
    # using API w/o cli
    cli = False


class CallbackBase:
    '''
    This is a base ansible callback class that does nothing. New callbacks should
    use this class as a base and override any callback methods they wish to execute
    custom actions.
Exemple #9
0
            # We first convert to a byte string so that we get rid of
            # characters that are invalid in the user's locale
            msg2 = to_text(msg2, self._output_encoding(stderr=stderr))

        if color == CONST.COLOR_ERROR:
            logger.error(msg2)
        else:
            logger.info(msg2)


import ansible.utils.display as default_display
default_display.logger = logger
default_display.Display.display = fabric_ansible_display

from ansible.utils.display import Display
display = Display(verbosity)

from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.inventory.manager import InventoryManager
from ansible.executor.playbook_executor import PlaybookExecutor

from job_manager.job_messages import MsgBundle
from job_manager.job_manager_logger import job_mgr_logger
JM_LOGGER = job_mgr_logger("FabricAnsible")


class PlaybookHelper(object):
    def get_plugin_output(self, pbex):
        output_json = pbex._tqm._variable_manager._nonpersistent_fact_cache[
            'localhost'].get('output')
Exemple #10
0
    def __init__(self,
                 username,
                 playbook,
                 private_key_file,
                 inventory_data,
                 extra_vars,
                 become_pass,
                 verbosity=0,
                 search_filter=None):
        """
    Args:
      username: string, username of user running the playbook
      playbook: string, full playbook path eg. /tmp/my_pb.yml
      private_key_file: string, private key file
      inventory_data: dict, inventory data
      extra_vars: dict, Ansible extra vars, key = variable name
      become_pass: string, become password
      verbosity: integer, verbosity level
      search_filter: string, hosts/groups to match
    """

        self.playbook = playbook
        self.username = username
        self.inventory_data = inventory_data
        self.extra_vars = extra_vars
        self.search_filter = search_filter

        self.options = Options()
        self.options.private_key_file = private_key_file
        self.options.verbosity = verbosity
        self.options.connection = 'ssh'  # Need a connection type "smart" or "ssh"
        self.options.become = True
        self.options.become_method = 'sudo'
        self.options.become_user = '******'

        # Set global verbosity
        self.display = Display()
        self.display.verbosity = self.options.verbosity
        # Executor appears to have it's own verbosity object/setting as well
        playbook_executor.verbosity = self.options.verbosity

        # Become Pass Needed if not logging in as user root
        passwords = {'become_pass': become_pass}

        # Gets data from YAML/JSON files
        self.loader = DataLoader()

        # ORIGNAL on line 1
        #self.loader.set_vault_password(os.environ['VAULT_PASS'])
        self.loader.set_vault_password('secret')

        # All the variables from all the various places
        self.variable_manager = VariableManager()

        # Set of hosts
        hosts = set()

        # Load group variable
        for group in self.inventory_data:
            if group != '_meta':
                for host in self.inventory_data[group]['hosts']:
                    host_obj = Host(host)
                    hosts.add(host)
                    for var in self.inventory_data[group]['vars']:
                        self.variable_manager.set_host_variable(
                            host_obj, var,
                            self.inventory_data[group]['vars'][var])

        # Load host variables
        for host in self.inventory_data['_meta']['hostvars']:
            for var in self.inventory_data['_meta']['hostvars'][host]:
                host_obj = Host(host)
                self.variable_manager.set_host_variable(
                    host_obj, var,
                    self.inventory_data['_meta']['hostvars'][host][var])

        self.variable_manager.extra_vars = self.extra_vars

        # Set inventory, using most of above objects
        self.inventory = Inventory(loader=self.loader,
                                   variable_manager=self.variable_manager,
                                   host_list=list(hosts))
        self.variable_manager.set_inventory(self.inventory)

        # Setup playbook executor, but don't run until run() called
        self.pbex = playbook_executor.PlaybookExecutor(
            playbooks=[self.playbook],
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options,
            passwords=passwords)
Exemple #11
0
class ActionModule(ActionBase):  #pylint: disable=R0903
    """ The action module class
    """
    display = Display()

    def _get_network_os(self, task_vars):
        if 'network_os' in self._task.args and self._task.args['network_os']:
            self.display.vvvv('Getting network OS from task argument')
            network_os = self._task.args['network_os']
        elif self._play_context.network_os:
            self.display.vvvv('Getting network OS from inventory')
            network_os = self._play_context.network_os
        elif ('network_os' in task_vars.get('ansible_facts', {})
              and task_vars['ansible_facts']['network_os']):
            self.display.vvvv('Getting network OS from fact')
            network_os = task_vars['ansible_facts']['network_os']
        else:
            raise AnsibleError(
                'ansible_network_os must be specified on this host.')
        return network_os

    def _get_os_resource(self, network_os, resource):
        parsers = [
            p for p in parser_loader.all()
            if p.PARSER_METADATA['network_os'] == network_os
            and p.PARSER_METADATA['resource'] == resource
        ]
        if not parsers:
            self.display.warning(
                "No parser available for resource %s for network os %s" %
                (resource, network_os))
            return None
        return parsers[0]

    def _run_command(self, command, task_vars):
        socket_path = getattr(self._connection,
                              'socket_path') or task_vars.get('ansible_socket')
        connection = Connection(socket_path)
        try:
            output = connection.get(command)
        except ConnectionError as exc:
            raise AnsibleError(to_text(exc))
        return output

    @staticmethod
    def _command_map():
        command_map = {}
        parsers = [p.PARSER_METADATA for p in parser_loader.all()]
        for parser in parsers:
            if not parser['resource'] in command_map:
                command_map[parser['resource']] = {}
            if not os in command_map[parser['resource']]:
                command_map[parser['resource']][parser['network_os']] = []
            command_map[parser['resource']][parser['network_os']].append(
                parser['commands'])
        return command_map

    @staticmethod
    def _validate_args(args):
        provided = set(list(args.keys()))
        valid_args = set(
            ['resources', 'update_facts', 'fact_key', '_return_command_map'])
        extras = provided - valid_args
        if extras:
            raise AnsibleError(
                "The following arguments are not supported: %s" %
                ','.join(extras))

    def run(self, tmp=None, task_vars=None):
        self.display.verbosity = self._play_context.verbosity

        self._validate_args(self._task.args)
        result = super(ActionModule, self).run(tmp, task_vars)
        if '_return_command_map' in self._task.args and self._task.args[
                '_return_command_map']:
            result.update({'command_map': self._command_map()})
            return result

        network_os = self._get_network_os(task_vars)

        facts = {}
        if 'resources' in self._task.args and self._task.args['resources']:
            resources = self._task.args['resources']
        else:
            resources = [
                p.PARSER_METADATA['resource'] for p in parser_loader.all()
                if p.PARSER_METADATA['network_os'] == network_os
            ]

        for resource in resources:
            if 'name' in resource:
                resource_name = resource['name']
            else:
                resource_name = resource

            parser = self._get_os_resource(network_os, resource_name)
            if parser:
                if 'output' in resource:
                    outputs = resource['output']
                else:
                    outputs = []
                    for command in parser.PARSER_METADATA['commands']:
                        outputs.append(self._run_command(command, task_vars))
                objs = parser.parse(outputs)
                facts.update(
                    json.loads(json.dumps(objs, sort_keys=True, cls=ToFacts)))

        if 'update_facts' in self._task.args:
            result.update(
                {'ansible_facts': {
                    self._task.args['fact_key']: facts
                }})

        result.update({'results': facts})
        return result
Exemple #12
0
    def __init__(self,
                 playbook,
                 inventory,
                 run_data,
                 start_at_task,
                 step,
                 private_key_file,
                 become_pass,
                 verbosity=0):

        self.run_data = run_data

        self.options = Options()
        self.options.listtags = False
        self.options.listtasks = False
        self.options.listhosts = False
        self.options.syntax = False
        self.options.check = False
        self.options.diff = False
        self.options.start_at_task = start_at_task
        self.options.step = step

        self.options.private_key_file = private_key_file
        self.options.verbosity = verbosity
        self.options.connection = 'ssh'  # Need a connection type "smart" or "ssh"
        self.options.become = False
        self.options.become_method = 'sudo'
        self.options.become_user = '******'
        self.options.remote_user = '******'
        # Set global verbosity
        self.display = Display()
        self.display.verbosity = self.options.verbosity
        # Executor appears to have it's own
        # verbosity object/setting as well
        #playbook_executor.verbosity = self.options.verbosity

        # Become Pass Needed if not logging in as user root
        passwords = {'become_pass': become_pass}

        # Gets data from YAML/JSON files
        self.loader = DataLoader()
        # self.loader.set_vault_password(os.environ['VAULT_PASS'])

        # All the variables from all the various places

        # Parse hosts, I haven't found a good way to
        # pass hosts in without using a parsed template :(
        # (Maybe you know how?)
        #         self.hosts = NamedTemporaryFile(delete=False)
        #         self.hosts.write("""[run_hosts]
        # %s
        # """ % hostnames)
        #         self.hosts.close()

        # This was my attempt to pass in hosts directly.
        #
        # Also Note: In py2.7, "isinstance(foo, str)" is valid for
        #            latin chars only. Luckily, hostnames are
        #            ascii-only, which overlaps latin charset
        ## if isinstance(hostnames, str):
        ##     hostnames = {"customers": {"hosts": [hostnames]}}

        # Set inventory, using most of above objects
        inventory_dir = '/etc/ansible/inventory'
        inventory_source = "%s/%s" % (inventory_dir, inventory)
        self.inventory = InventoryManager(loader=self.loader,
                                          sources=inventory_source)
        self.variable_manager = VariableManager(loader=self.loader,
                                                inventory=self.inventory)
        if self.run_data:
            self.variable_manager.extra_vars = self.run_data['extra_vars']
            self.options.tags = self.run_data['tags']

        # Playbook to run. Assumes it is
        # local to this python file
        pb_dir = '/etc/ansible/playbooks'
        playbook = "%s/%s" % (pb_dir, playbook)
        print(playbook)
        # Setup playbook executor, but don't run until run() called
        self.pbex = playbook_executor.PlaybookExecutor(
            playbooks=[playbook],
            inventory=self.inventory,
            variable_manager=self.variable_manager,
            loader=self.loader,
            options=self.options.get_config(),
            passwords=passwords)