Exemplo n.º 1
0
 def do_check(self, arg):
     """Toggle whether plays run with check mode"""
     if arg:
         self.options.check = C.mk_boolean(arg)
         display.v("check mode changed to %s" % self.options.check)
     else:
         display.display("Please specify check mode value, e.g. `check yes`")
Exemplo n.º 2
0
    def run(self):
        """Run the ansible command

        Subclasses must implement this method.  It does the actual work of
        running an Ansible command.
        """

        display.vv(to_text(self.parser.get_version()))

        if C.CONFIG_FILE:
            display.v(u"Using %s as config file" % to_text(C.CONFIG_FILE))
        else:
            display.v(u"No config file found; using defaults")

        # warn about deprecated config options
        for deprecated in C.config.DEPRECATED:
            name = deprecated[0]
            why = deprecated[1]['why']
            if 'alternatives' in deprecated[1]:
                alt = ', use %s instead' % deprecated[1]['alternatives']
            else:
                alt = ''
            ver = deprecated[1]['version']
            display.deprecated("%s option, %s %s" % (name, why, alt), version=ver)

        # warn about typing issues with configuration entries
        for unable in C.config.UNABLE:
            display.warning("Unable to set correct type for configuration entry: %s" % unable)
Exemplo n.º 3
0
 def do_become_method(self, arg):
     """Given a become_method, set the privilege escalation method when using become"""
     if arg:
         self.options.become_method = arg
         display.v("become_method changed to %s" % self.options.become_method)
     else:
         display.display("Please specify a become_method, e.g. `become_method su`")
Exemplo n.º 4
0
    def _parse_pkglist(self, pkglist, other=False):

        pkgs_dict = dict()
        repo_dict = dict()
        display.v("Handling package list: %s" % pkglist)

        with open(pkglist) as f:
            for line in f.readlines():
                line = line.strip()
                if line.startswith('#'):
                    m = self.INCLUDE_PATTERN.match(line)
                    if not m:
                        continue
                    incf = m.group(1).strip()
                    display.vvv("Including: %s" % incf)
                    d1, d2 = self._parse_pkglist(incf, other)
                    pkgs_dict.update(d1)
                    if other:
                        repo_dict.update(d2)
                else:
                    if other:
                        repo_dir = os.path.dirname(line) or ''
                        if repo_dir:
                            repo_dict[repo_dir] = 1

                    pkgname = os.path.basename(line)
                    if pkgname.startswith('@ '):
                        # it is a group, get rid of the space
                        pkgname = "@%s" % pkgname[1:].strip()
                    pkgs_dict[pkgname] = 1

        return pkgs_dict, repo_dict
Exemplo n.º 5
0
    def run(self):
        """Run the ansible command

        Subclasses must implement this method.  It does the actual work of
        running an Ansible command.
        """

        display.vv(to_text(self.parser.get_version()))

        if C.CONFIG_FILE:
            display.v(u"Using %s as config file" % to_text(C.CONFIG_FILE))
        else:
            display.v(u"No config file found; using defaults")

        # warn about deprecated config options
        for deprecated in C.config.DEPRECATED:
            name = deprecated[0]
            why = deprecated[1]['why']
            if 'alternative' in deprecated[1]:
                alt = ', use %s instead' % deprecated[1]['alternative']
            else:
                alt = ''
            ver = deprecated[1]['version']
            display.deprecated("%s option, %s %s" % (name, why, alt),
                               version=ver)

        # warn about typing issues with configuration entries
        for unable in C.config.UNABLE:
            display.warning(
                "Unable to set correct type for configuration entry: %s" %
                unable)
Exemplo n.º 6
0
 def _get_arg_or_var(self, name, default=None, is_required=True):
     ret = self._task.args.get(name, self._task_vars.get(name, default))
     display.v("_get_arg_or_var %s, default: %s, required: %s, ret: %s" % (name, default, is_required, ret))
     if is_required and not ret and ret != default:
         raise AnsibleOptionsError("parameter %s is required" % name)
     else:
         return ret
Exemplo n.º 7
0
 def do_diff(self, arg):
     """Toggle whether plays run with diff"""
     if arg:
         self.options.diff = C.mk_boolean(arg)
         display.v("diff mode changed to %s" % self.options.diff)
     else:
         display.display("Please specify a diff value , e.g. `diff yes`")
Exemplo n.º 8
0
 def do_verbosity(self, arg):
     """Set verbosity level"""
     if not arg:
         display.display('Usage: verbosity <number>')
     else:
         display.verbosity = int(arg)
         display.v('verbosity level set to %s' % arg)
Exemplo n.º 9
0
 def do_become_method(self, arg):
     """Given a become_method, set the privilege escalation method when using become"""
     if arg:
         self.options.become_method = arg
         display.v("become_method changed to %s" % self.options.become_method)
     else:
         display.display("Please specify a become_method, e.g. `become_method su`")
Exemplo n.º 10
0
 def do_check(self, arg):
     """Toggle whether plays run with check mode"""
     if arg:
         self.options.check = C.mk_boolean(arg)
         display.v("check mode changed to %s" % self.options.check)
     else:
         display.display("Please specify check mode value, e.g. `check yes`")
    def create_request(self, account_id, reason, period):
        display.v("Creating request for: %s (%s) " % (account_id, reason))
        now = int(time())

        payload = json.dumps(
            {
                "AccountID": account_id,
                "Reason": reason,
                "fromDate": now,
                "toDate": now + period,
                "hasTimeframe": True,
                "MultipleAccessRequired": True,
            },
            indent=2,
            sort_keys=False)

        display.v(payload)

        response = self.request(api_endpoint='API/MyRequests',
                                data=payload,
                                method='POST')

        # if response.status != 201:
        #     raise PWVRequestInvalid(0, "unexpected return code", "%s instead of 201" % response.status_code)

        response = json.loads(response.read())

        if response['Status'] == 7:
            raise PWVRequestInvalid(response['RequestID'],
                                    response['StatusTitle'],
                                    response['StatusRequestReason'])

        return response['RequestID']
Exemplo n.º 12
0
 def do_verbosity(self, arg):
     """Set verbosity level"""
     if not arg:
         display.display('Usage: verbosity <number>')
     else:
         display.verbosity = int(arg)
         display.v('verbosity level set to %s' % arg)
Exemplo n.º 13
0
 def do_diff(self, arg):
     """Toggle whether plays run with diff"""
     if arg:
         self.options.diff = C.mk_boolean(arg)
         display.v("diff mode changed to %s" % self.options.diff)
     else:
         display.display("Please specify a diff value , e.g. `diff yes`")
Exemplo n.º 14
0
 def run(self, tmp=None, task_vars=None):
     display.v("a log")
     display.vv("Kind of verbose")
     display.vvv("Verbose")
     display.vvvv("Lookout!")
     display.verbose("Super custom verbosity", caplevel=6)
     return {'msg': 'done'}
Exemplo n.º 15
0
 def do_become(self, arg):
     """Toggle whether plays run with become"""
     if arg:
         self.options.become = C.mk_boolean(arg)
         display.v("become changed to %s" % self.options.become)
         self.set_prompt()
     else:
         display.display("Please specify become value, e.g. `become yes`")
Exemplo n.º 16
0
 def do_become_user(self, arg):
     """Given a username, set the user that plays are run by when using become"""
     if arg:
         self.options.become_user = arg
     else:
         display.display("Please specify a user, e.g. `become_user jenkins`")
         display.v("Current user is %s" % self.options.become_user)
     self.set_prompt()
Exemplo n.º 17
0
 def do_become(self, arg):
     """Toggle whether plays run with become"""
     if arg:
         self.options.become = C.mk_boolean(arg)
         display.v("become changed to %s" % self.options.become)
         self.set_prompt()
     else:
         display.display("Please specify become value, e.g. `become yes`")
Exemplo n.º 18
0
 def do_become_user(self, arg):
     """Given a username, set the user that plays are run by when using become"""
     if arg:
         self.options.become_user = arg
     else:
         display.display("Please specify a user, e.g. `become_user jenkins`")
         display.v("Current user is %s" % self.options.become_user)
     self.set_prompt()
Exemplo n.º 19
0
 def _get_arg_or_var(self, name, default=None, is_required=True):
     display.v("%s, %s, %s" % (name, default, is_required))
     ret = self._task.args.get(name, self._task_vars.get(name, default))
     ret = self._templar.template(ret)
     if is_required and ret == None:
         raise AnsibleOptionsError("parameter %s is required" % name)
     else:
         return ret
Exemplo n.º 20
0
    def read_put_file(self, connection, in_path, out_path):
        self.put_index += 1
        display.v('FIXTURE_PUT_INDEX: %s' % self.put_index)
        fixture_file = self.get_fixture_file('put', 'read', connection=connection)

        with open(fixture_file, 'r') as f:
            jdata = json.loads(f.read())

        return (jdata['returncode'], jdata['stdout'], jdata['stderr'])
Exemplo n.º 21
0
 def orion_query(self, swis, query):
     """ Connect to Orion server and send query """
     rsp = swis.query("{}".format(query))
     if rsp['results'] == []:
         print("No results for: {}".format(query))
         exit(-1)
     display.v("Query Orion Existing SerialNumber: {}\n".format(
         rsp['results'][0][rsp['results'][0].keys()[0]]))
     return rsp
Exemplo n.º 22
0
 def run(self, terms, variables=None, **kwargs):
     display.v("Netfilter terms: %s" % terms)
     try:
         if terms[0] == 'as_iif':  # 1 == interface
             return self.as_if('i', terms[1])
         if terms[0] == 'as_oif':  # 1 == interface
             return self.as_if('o', terms[1])
         if terms[0] == 'list_or_single':  # 1 == list
             return self.as_list_or_single(terms[1])
         raise AnsibleParserError("Непонятно что делать")
     except Exception as e:
         raise AnsibleError("Error in nft: %s (%s)" % (terms, e))
Exemplo n.º 23
0
    def run(self, tmp=None, task_vars=None):
        suffix_to_merge = self._task.args.get('suffix_to_merge', '')
        merged_var_name = self._task.args.get('merged_var_name', '')
        dedup = self._task.args.get('dedup', True)
        expected_type = self._task.args.get('expected_type')
        all_keys = task_vars.keys()

        # Validate args
        if expected_type not in ['dict', 'list']:
            raise AnsibleError("expected_type must be set ('dict' or 'list').")
        if not suffix_to_merge.endswith('__to_merge'):
            raise AnsibleError(
                "Merge suffix must end with '__to_merge', sorry!")
        if merged_var_name in all_keys:
            warning = "{} is already defined, are you sure you want to overwrite it?"
            display.warning(warning.format(merged_var_name))
            display.v("The contents of {} are: {}".format(
                merged_var_name, task_vars[merged_var_name]))

        keys = [
            key for key in task_vars.keys() if key.endswith(suffix_to_merge)
        ]

        display.v("Merging vars in this order: {}".format(keys))

        merge_vals = [task_vars[key] for key in keys]

        # Dispatch based on type that we're merging
        if merge_vals == []:
            if expected_type == 'list':
                merged = []
            else:
                merged = {}  # pylint: disable=redefined-variable-type
        elif isinstance(merge_vals[0], list):
            merged = merge_list(merge_vals, dedup)
        elif isinstance(merge_vals[0], dict):
            merged = merge_dict(merge_vals)
        else:
            raise AnsibleError(
                "Don't know how to merge variables of type: {}".format(
                    type(merge_vals[0])))

        # We need to render any jinja in the merged var now, because once it
        # leaves this plugin, ansible will cleanse it by turning any jinja tags
        # into comments.
        merged = self._templar.template(merged)
        return {
            'ansible_facts': {
                merged_var_name: merged
            },
            'changed': False,
        }
Exemplo n.º 24
0
    def run(self):
        """Run the ansible command

        Subclasses must implement this method.  It does the actual work of
        running an Ansible command.
        """

        display.vv(self.parser.get_version())

        if C.CONFIG_FILE:
            display.v(u"Using %s as config file" % to_text(C.CONFIG_FILE))
        else:
            display.v(u"No config file found; using defaults")
Exemplo n.º 25
0
def hooks(hooks, type, run_once, groups):
    suffix = "once.yml" if run_once else "yml"
    hooks.append(cwd)
    display.v('Listing for: %s -> %s' % (hooks, groups))
    groups.append('all')

    files = []
    for hook in hooks:
        for group in groups:
            path = "%s/%s.%s.%s" % (hook, type, group, suffix)
            display.vv(path)
            if os.path.isfile(path):
                files.append(path)
    return files
Exemplo n.º 26
0
    def __init__(self, firewall_policy_path=None):

       self.policy = {}

       try:
           with open(firewall_policy_path, 'r') as stream:
               self.policy = yaml.load(stream)
       except yaml.YAMLError as exc:
           display.warning('%s badly formatted' % firewall_policy_path)
           raise
       except IOError:
           display.warning('%s missing, no firewall policy will be applied' % firewall_policy_path)
           pass
       else:
           display.v("firewall policy loaded: %s" % firewall_policy_path)
Exemplo n.º 27
0
    def _normalize_plugins(self, plugins):
        tmp = {}
        display.vv("_normalize_plugins: %s" % (plugins))

        for plugin in plugins:
            display.v("_normalize_plugin: %s" % (plugin))
            normalized_managed_plugin = {
                "version": plugin.get("version", None),
                "enabled": plugin.get("enabled", True),
                "pinned": plugin.get("pinned", False),
                "absent": plugin.get("absent", False),
                "latest": plugin.get("latest", False),
            }
            tmp[plugin.get('name')] = normalized_managed_plugin
        return tmp
Exemplo n.º 28
0
    def run(self, terms, variables=None, **kwargs):
        if not terms or len(terms) != 2:
            raise AnsibleError('Wrong request format')
        entry_path = terms[0].strip('/')
        entry_attr = terms[1]

        kp_dbx = variables.get('keepass_dbx', '')
        kp_dbx = os.path.realpath(os.path.expanduser(kp_dbx))
        if os.path.isfile(kp_dbx):
            display.v(u"Keepass: database file %s" % kp_dbx)

        kp_soc = "%s.sock" % kp_dbx
        if os.path.exists(kp_soc):
            return self._fetch_socket(kp_soc, entry_path, entry_attr)

        kp_psw = variables.get('keepass_psw', '')
        kp_key = variables.get('keepass_key')
        return self._fetch_file(kp_dbx, str(kp_psw), kp_key, entry_path,
                                entry_attr)
Exemplo n.º 29
0
    def run(self, terms, variables=None, **kwargs):
        if not terms or len(terms) < 2 or len(terms) > 3:
            raise AnsibleError('Wrong request format')
        entry_path = terms[0].strip('/')
        entry_attr = terms[1]
        enable_custom_attr = False
        
        if len(terms) == 3:
            enable_custom_attr = terms[2]
        
        kp_dbx = variables.get('keepass_dbx', '')
        kp_dbx = os.path.realpath(os.path.expanduser(kp_dbx))
        if os.path.isfile(kp_dbx):
            display.v(u"Keepass: database file %s" % kp_dbx)

        kp_soc = "%s/ansible-keepass.sock" % tempfile.gettempdir()
        if os.path.exists(kp_soc):
            display.v(u"Keepass: fetch from socket")
            return self._fetch_socket(kp_soc, entry_path, entry_attr)

        kp_psw = variables.get('keepass_psw', '')
        kp_key = variables.get('keepass_key')
        display.v(u"Keepass: fetch from kdbx file")
        return self._fetch_file(
            kp_dbx, str(kp_psw), kp_key, entry_path, entry_attr, enable_custom_attr)
Exemplo n.º 30
0
 def run(self, terms, variables=None, **kwargs):
     display.v("Ship terms: %s" % terms)
     try:
         if terms[0] == 'ip':  # 1 == номер
             return self.ip(int(terms[1]))
         if terms[0] == 'net':  # 1 == версия ip
             return self._format_net(self._home_net(terms[1]))
         if terms[0] == 'delegated_net':
             return self._format_net(self._delegated_net())
         if terms[0] == 'kis_ip':  # 1 == номер
             return self.prov_ip('ipv4', 'kis', int(terms[1]))
         if terms[0] == 'kis_net':
             return self.prov_net('ipv4', 'kis')
         if terms[0] == 'henet_ip':  # 1 == номер
             return self.prov_ip('ipv6', 'henet', int(terms[1]))
         if terms[0] == 'henet_net':
             return self.prov_net('ipv6', 'henet')
         if terms[0] == 'tor_ip':  # 1 == версия ip, 2 == номер
             return self.prov_ip(terms[1], 'tor', int(terms[2]))
         if terms[0] == 'tor_net':  # 1 == версия ip
             return self.prov_net(terms[1], 'tor')
         raise AnsibleParserError("Непонятно что делать")
     except Exception as e:
         raise AnsibleError("Error in ship: %s (%s)" % (terms, e))
Exemplo n.º 31
0
    def reject_task(self, task, task_vars):

        # is the task action capture by our policy?
        if task.action in self.policy:

            # is the entire action blocked?
            if not isinstance(self.policy[task.action], list) and not isinstance(self.policy[task.action], dict):
                raise TaskFirewallAnsibleError('firewall policy: module (%s) blocked' % task.action)
            display.v('firewall rule: module [%s]' % (self.policy[task.action]))

            # now check the action args
            for key in self.policy[task.action]:

                if key not in task.args:
                    continue

                # is an entire arg of this action blocked?
                if not isinstance(self.policy[task.action][key], list):
                    raise TaskFirewallAnsibleError('firewall policy: module (%s) arg (%s) blocked' % (task.action, key))
                display.v('firewall rule passed: [%s:%s] against %s' % (self.policy[task.action], self.policy[task.action][key], task.args[key]))

                # check if the task arg contains a var that needs to be expanded
                if isinstance(task.args[key], str) and task.args[key].find('\{\{'):
                    # TODO: resolve variables to actual values. This is pretty complicated for an Ansible outsider,
                    #       as I don't want to simply copy/paste/mod the task executor code into here.   It's also 
                    #       pretty essential to the concept of a firewall.
                    pass

                # for each rule in the policy module:arg:[value] list, compare the current task arg
                for rule in self.policy[task.action][key]:

                    # do we have the 'contains' verb option in policy
                    if str(rule).startswith('contains'):
                        if str(task.args[key]).find(rule[9:]) != -1:
                            raise TaskFirewallAnsibleError('firewall policy: module (%s) arg (%s) (%s) blocked' % (task.action, key, rule))

                    # check if the policy arg is an exact match for the task arg
                    elif task.args[key] == rule:
                        raise TaskFirewallAnsibleError('firewall policy: module (%s) arg (%s) value (%s) blocked' % (task.action, key, rule))

                    display.v('firewall rule passed: [%s:%s %s] against %s' % (task.action, key, rule, task.args[key]))
Exemplo n.º 32
0
    def _calculate_present_plugins(self, managed_plugins, existing_plugins):
        tmp = {}

        for key in managed_plugins:
            managed_plugin = managed_plugins.get(key)

            try:
                managed_plugin_absent = managed_plugin.get("absent", False)
                managed_plugin_version = managed_plugin.get("version", None)
                managed_plugin_latest = managed_plugin.get("latest", False)
            except AnsibleOptionsError:
                managed_plugin_version = None
                managed_plugin_latest = False
                managed_plugin_absent = False

            if managed_plugin_absent is True:
                continue

            existing_plugin = existing_plugins.get(key, None)

            plugin_facts = False

            if existing_plugin is None:
                display.v("needs installation: [%s] %s" % (key, managed_plugin))
                if managed_plugin_latest is True:
                    # install plugin in lastest version
                    plugin_facts = {
                        "state": "latest"
                    }
                elif managed_plugin_version is not None:
                    # install plugin in specific version
                    plugin_facts = {
                        "state": "present",
                        "version": managed_plugin_version
                    }
                else:
                    # no specific version, just make it present
                    plugin_facts = {
                        "state": "present",
                    }
            else:
                display.v("already installed, checking versions: [%s] %s" % (key, managed_plugin))
                existing_plugin_version = existing_plugin.get("version")
                existing_plugin_hasUpdate = existing_plugin.get("hasUpdate")

                # update plugin when possible
                if managed_plugin_latest is True and existing_plugin_hasUpdate is True:
                    # update plugin to latest when update is available
                    plugin_facts = {
                        "state": "latest"
                    }
                # install plugin with specific version
                elif managed_plugin_version is not None and managed_plugin_version != existing_plugin_version:
                    # change plugin to specific version if defined
                    plugin_facts = {
                        "state": "present",
                        "version": managed_plugin_version
                    }

            if plugin_facts is not False:
                display.vv("Change required for plugin: [%s], plugin facts: %s, new: %s, old: %s" %
                           (key, plugin_facts, managed_plugin, existing_plugin))
                tmp[key] = plugin_facts

        return tmp
Exemplo n.º 33
0
    def run(self, terms, variables=None, **kwargs):

        npm_server = kwargs.get('npm_server', '172.19.128.111')
        column = kwargs.get('column', 'nodes.customproperties.serialNumber')
        user_id = kwargs.get('user_id', '**')
        passwd = kwargs.get('passwd', '**')
        update_flag = kwargs.get('update_flag', False)
        new_value = kwargs.get('new_value', '')

        # lookups in general are expected to both take a list as input terms[], and output a list, ret[]
        # this is done so they work with the looping construct 'with_'.
        ret = []

        for hostname in terms:
            display.v("value to return %s" % column)
            query = "SELECT {} FROM Orion.Nodes WHERE Caption = '{}'".format(
                column, hostname)

            display.v("query: {}".format(query))

            try:
                orion = self.orion_connect(npm_server, user_id, passwd)
                rsp = self.orion_query(orion, query)
                display.v("result: {}".format(
                    rsp['results'][0][rsp['results'][0].keys()[0]]))
                if update_flag:
                    display.v("update {} with {}".format(column, new_value))
                    uri_query = "SELECT URI from Orion.Nodes WHERE Caption = '{}'".format(
                        hostname)
                    uri = self.orion_query(orion, uri_query)
                    url = "{}/{}".format(uri['results'][0]['URI'],
                                         column.split('.')[-2])
                    display.v("url: {}".format(url))
                    orion.update(url, **{column.split('.')[-1]: new_value})

            except HTTPError as e:
                raise AnsibleError("Received HTTP error for %s : %s" %
                                   (hostname, str(e)))
            except URLError as e:
                raise AnsibleError("Failed lookup url for %s : %s" %
                                   (hostname, str(e)))
            except SSLValidationError as e:
                raise AnsibleError(
                    "Error validating the server's certificate for %s: %s" %
                    (hostname, str(e)))
            except ConnectionError as e:
                raise AnsibleError("Error connecting to %s: %s" %
                                   (hostname, str(e)))
            except Exception as e:
                raise AnsibleError("Error:  %s: %s" % (hostname, str(e)))
            else:
                display.v("response {}".format(rsp['results'][0].keys()[0]))
                ret.append(
                    to_text(rsp['results'][0][rsp['results'][0].keys()[0]]))
        return ret
Exemplo n.º 34
0
    def parse_source(self, source, cache=False):
        ''' Generate or update inventory for the source provided '''

        parsed = False
        display.debug(u'Examining possible inventory source: %s' % source)

        # use binary for path functions
        b_source = to_bytes(source)

        # process directories as a collection of inventories
        if os.path.isdir(b_source):
            display.debug(u'Searching for inventory files in directory: %s' %
                          source)
            for i in sorted(os.listdir(b_source)):

                display.debug(u'Considering %s' % i)
                # Skip hidden files and stuff we explicitly ignore
                if IGNORED.search(i):
                    continue

                # recursively deal with directory entries
                fullpath = to_text(os.path.join(b_source, i),
                                   errors='surrogate_or_strict')
                parsed_this_one = self.parse_source(fullpath, cache=cache)
                display.debug(u'parsed %s as %s' % (fullpath, parsed_this_one))
                if not parsed:
                    parsed = parsed_this_one
        else:
            # left with strings or files, let plugins figure it out

            # set so new hosts can use for inventory_file/dir vasr
            self._inventory.current_source = source

            # get inventory plugins if needed, there should always be at least one generator
            if not self._inventory_plugins:
                self._setup_inventory_plugins()

            # try source with each plugin
            failures = []
            for plugin in self._inventory_plugins:
                plugin_name = to_text(
                    getattr(plugin, '_load_name',
                            getattr(plugin, '_original_path', '')))
                display.debug(u'Attempting to use plugin %s (%s)' %
                              (plugin_name, plugin._original_path))

                # initialize and figure out if plugin wants to attempt parsing this file
                try:
                    plugin_wants = bool(plugin.verify_file(source))
                except Exception:
                    plugin_wants = False

                if plugin_wants:
                    try:
                        # in case plugin fails 1/2 way we dont want partial inventory
                        plugin.parse(self._inventory,
                                     self._loader,
                                     source,
                                     cache=cache)
                        parsed = True
                        display.vvv(
                            'Parsed %s inventory source with %s plugin' %
                            (source, plugin_name))
                        break
                    except AnsibleParserError as e:
                        display.debug('%s was not parsable by %s' %
                                      (source, plugin_name))
                        failures.append({
                            'src': source,
                            'plugin': plugin_name,
                            'exc': e
                        })
                    except Exception as e:
                        display.debug('%s failed to parse %s' %
                                      (plugin_name, source))
                        failures.append({
                            'src': source,
                            'plugin': plugin_name,
                            'exc': AnsibleError(e)
                        })
                else:
                    display.v(
                        '%s did not meet %s requirements, check plugin documentation if this is unexpected'
                        % (source, plugin_name))
            else:
                if not parsed and failures:
                    # only if no plugin processed files should we show errors.
                    for fail in failures:
                        display.warning(
                            u'\n* Failed to parse %s with %s plugin: %s' %
                            (to_text(fail['src']), fail['plugin'],
                             to_text(fail['exc'])))
                        if hasattr(fail['exc'], 'tb'):
                            display.vvv(to_text(fail['exc'].tb))
                    if C.INVENTORY_ANY_UNPARSED_IS_FAILED:
                        raise AnsibleError(
                            u'Completely failed to parse inventory source %s' %
                            (source))
        if not parsed:
            display.warning("Unable to parse %s as an inventory source" %
                            source)

        # clear up, jic
        self._inventory.current_source = None

        return parsed
Exemplo n.º 35
0
    def run(self, tmp=None, task_vars=None):
        if task_vars is None:
            task_vars = dict()

        # uncomment to enable request debugging
        #try:
        #    import http.client as http_client
        #except ImportError:
        #    # Python 2
        #    import httplib as http_client
        #    http_client.HTTPConnection.debuglevel = 1
##
#logLevel = logging.DEBUG
#logging.basicConfig()
#logging.getLogger().setLevel(logLevel)
#requests_log = logging.getLogger("requests.packages.urllib3")
#requests_log.setLevel(logLevel)
#requests_log.propagate = True

        result = super(ActionModule, self).run(tmp, task_vars)

        self._task_vars = task_vars
        changed = False

        display.v("args: %s" % (self._task.args))

        try:
            # Get the tasmota host
            tasmota_host = self._get_arg_or_var('tasmota_host',
                                                task_vars['ansible_host'])
            command = self._get_arg_or_var('command')
            incoming_value = self._get_arg_or_var('value')

        except Exception as err:
            display.v("got an exception: %s" % (err))
            display.v("got an exception: " + err.message)
            return self._fail_result(
                result,
                "error during retrieving parameter '%s'" % (err.message))

        endpoint_uri = "http://%s/cm" % (tasmota_host)
        status_params = {'cmnd': command}

        # execute command
        status_response = requests.get(url=endpoint_uri, params=status_params)
        # get response data
        data = status_response.json()
        display.v("data: %s" % (data))
        existing_value = unicode(data.get(command))

        if (command.startswith('Rule')):
            display.vv("rule found!")
            existing_once = data.get("Once")
            existing_rules = data.get("Rules")
            existing_rule = data.get(command)
            existing_stop_on_error = data.get("StopOnError")
            if incoming_value in ["0", "1", "2"]:
                display.vv("disable, enable, toggle rule found")
                existing_value = self._translateResultStr(existing_value)
            elif incoming_value in ["4", "5"]:
                display.vv("disable, enable oneshot")
                existing_value = self._translateResultStr(
                    existing_once, "4", "5")
            elif incoming_value.startswith("on"):
                display.vv("rule value found")
                existing_value = existing_rules
        elif (command.startswith('SetOption')):
            existing_value = self._translateResultStr(existing_value)
        elif (command.startswith('PowerRetain')):
            existing_value = self._translateResultStr(existing_value)

        display.v(
            "[%s] command: %s, existing_value: '%s', incoming_value: '%s'" %
            (tasmota_host, command, existing_value, incoming_value))

        display.v("[%s] existing_uri: %s" % (tasmota_host, endpoint_uri))
        if existing_value != incoming_value:
            changed = True
            change_params = {'cmnd': ("%s %s" % (command, incoming_value))}
            change_response = requests.get(url=endpoint_uri,
                                           params=change_params)

        result["changed"] = changed
        result["command"] = command
        result["tasmota_host"] = tasmota_host
        result["raw_data"] = data
        result["endpoint_uri"] = endpoint_uri
        result["incoming_value"] = incoming_value
        result["existing_value"] = existing_value

        return result
Exemplo n.º 36
0
 def _fail_result(result, message):
     display.v("_fail_result")
     result['failed'] = True
     result['msg'] = message
     return result
    def run(self, tmp=None, task_vars=None):
        suffix_to_merge = self._task.args.get('suffix_to_merge', '')
        merged_var_name = self._task.args.get('merged_var_name', '')
        dedup = self._task.args.get('dedup', True)
        expected_type = self._task.args.get('expected_type')
        recursive_dict_merge = bool(
            self._task.args.get('recursive_dict_merge', False))

        if 'cacheable' in self._task.args.keys():
            display.deprecated(
                "The `cacheable` option does not actually do anything, since Ansible 2.5. "
                "No matter what, the variable set by this plugin will be set in the fact "
                "cache if you have fact caching enabled.  To get rid of this warning, "
                "remove the `cacheable` argument from your merge_vars task.  This warning "
                "will be removed in a future version of this plugin.")

        # Validate args
        if expected_type not in ['dict', 'list']:
            raise AnsibleError("expected_type must be set ('dict' or 'list').")
        if not merged_var_name:
            raise AnsibleError("merged_var_name must be set")
        if not isidentifier(merged_var_name):
            raise AnsibleError(
                "merged_var_name '%s' is not a valid identifier" %
                merged_var_name)
        if not suffix_to_merge.endswith('__to_merge'):
            raise AnsibleError(
                "Merge suffix must end with '__to_merge', sorry!")

        keys = sorted(
            [key for key in task_vars.keys() if key.endswith(suffix_to_merge)])

        display.v("Merging vars in this order: {}".format(keys))

        # We need to render any jinja in the merged var now, because once it
        # leaves this plugin, ansible will cleanse it by turning any jinja tags
        # into comments.
        # And we need it done before merging the variables,
        # in case any structured data is specified with templates.
        merge_vals = [self._templar.template(task_vars[key]) for key in keys]

        # Dispatch based on type that we're merging
        if merge_vals == []:
            if expected_type == 'list':
                merged = []
            else:
                merged = {}
        elif isinstance(merge_vals[0], list):
            merged = merge_list(merge_vals, dedup)
        elif isinstance(merge_vals[0], dict):
            merged = merge_dict(merge_vals, dedup, recursive_dict_merge)
        else:
            raise AnsibleError(
                "Don't know how to merge variables of type: {}".format(
                    type(merge_vals[0])))

        return {
            'ansible_facts': {
                merged_var_name: merged
            },
            'changed': False,
        }
Exemplo n.º 38
0
    def run(self, tmp=None, task_vars=None):
        if task_vars is None:
            task_vars = dict()

        # uncomment to enable request debugging
        #try:
        #    import http.client as http_client
        #except ImportError:
        #    # Python 2
        #    import httplib as http_client
        #    http_client.HTTPConnection.debuglevel = 1
##
#import logging
#logLevel = logging.DEBUG
#logging.basicConfig()
#logging.getLogger().setLevel(logLevel)
#requests_log = logging.getLogger("requests.packages.urllib3")
#requests_log.setLevel(logLevel)
#requests_log.propagate = True

        result = super(ActionModule, self).run(tmp, task_vars)

        self._task_vars = task_vars
        changed = False
        no_log = self._play_context.no_log

        if not no_log:
            display.v("args: %s" % (self._task.args))

        check_mode = task_vars['ansible_check_mode']
        display.v("check_mode: %s" % (check_mode))

        try:
            # Get the tasmota host
            tasmota_host = self._get_arg_or_var('tasmota_host',
                                                task_vars['ansible_host'])
            command = self._get_arg_or_var('command')
            incoming_value = self._get_arg_or_var('value', None, False)

            if incoming_value is None:

                # early return when incoming_value is not provided
                result["changed"] = False
                result["skipped"] = True

                return result

        except Exception as err:
            display.v("got an exception: %s" % (err))
            display.v("got an exception: " + err.message)
            return self._fail_result(
                result,
                "error during retrieving parameter '%s'" % (err.message))

        if not no_log:
            display.v("incoming_value %s" % (incoming_value))

        auth_params = {}
        try:
            user = self._get_arg_or_var("tasmota_user")
            password = self._get_arg_or_var('tasmota_password')
            auth_params = {'user': user, 'password': password}
            display.v("authentication parameters: %s" % (auth_params))
        except:
            pass

        # Enable retries due to reboot of the devices
        session = requests.Session()
        session.mount("http://%s" % (tasmota_host),
                      HTTPAdapter(Retry(total=5, backoff_factor=1.0)))

        endpoint_uri = "http://%s/cm" % (tasmota_host)
        status_params = copy.deepcopy(auth_params)
        status_params.update({'cmnd': command})

        # execute command
        status_response = requests.get(url=endpoint_uri, params=status_params)
        # get response data
        data = status_response.json()
        display.v("data: %s, response code: %s" %
                  (data, status_response.status_code))

        warnings = []
        resp_warn = data.get("WARNING")
        if resp_warn:
            # Prior to v8.2.3 authorization error has 200 ok status
            if status_response.status_code == 401 or resp_warn == "Need user=<username>&password=<password>":
                raise AnsibleAuthenticationFailure(
                    "Missing/Invalid credentials")
            warnings.append(resp_warn)

        if status_response.status_code != 200:
            raise AnsibleRuntimeError("Unexpected response code: %s" %
                                      (status_response.status_code))

        existing_value = unicode(data.get(command))

        if (command.startswith('Rule')):
            display.vv("rule found!")
            existing_once = data.get("Once")
            existing_rules = data.get("Rules")
            existing_rule = data.get(command)
            existing_stop_on_error = data.get("StopOnError")
            if incoming_value in ["0", "1", "2"]:
                display.vv("disable, enable, toggle rule found")
                existing_value = self._translateResultStr(existing_value)
            elif incoming_value in ["4", "5"]:
                display.vv("disable, enable oneshot")
                existing_value = self._translateResultStr(
                    existing_once, "4", "5")
            elif incoming_value.startswith("on"):
                display.vv("rule value found")
                existing_value = existing_rules
        elif (command.startswith('SetOption')):
            existing_value = self._translateResultStr(existing_value)
        elif (command.startswith('PowerRetain')):
            existing_value = self._translateResultStr(existing_value)
        elif (command == 'Module'):
            modules_ids = data.get(command).keys()
            existing_value = next(iter(modules_ids))
        elif (command.startswith('Gpio')):
            gpios = data.get(command.upper()).keys()
            existing_value = next(iter(gpios))
        elif (command == 'Template'):
            existing_value = data
        elif (command.startswith('Timers')):
            existing_value = self._translateResultStr(data.get('Timers'))
        elif (re.findall('Timer\d', command)):
            existing_value = data.get(command)
        elif (command == 'TimeStd' or command == 'TimeDst'):
            display.vv("TimeStd/TimeDst found!")
            existing_data = data.get(command)
            existing_day = existing_data.get("Day")
            existing_hemisphere = existing_data.get("Hemisphere")
            existing_hour = existing_data.get("Hour")
            existing_month = existing_data.get("Month")
            existing_offset = existing_data.get("Offset")
            existing_week = existing_data.get("Week")
            existing_value = "%s,%s,%s,%s,%s,%s" % (
                existing_hemisphere, existing_week, existing_month,
                existing_day, existing_hour, existing_offset)
        elif (command == 'TuyaMCU'):
            # Return only relevant subset of fn/dp ids, ignoring the rest
            try:
                fn_id, dp_id = (int(x) for x in incoming_value.split(','))
            except Exception as e:
                raise AnsibleOptionsError(
                    "Invalid value '%s' for TuyaMCU: %s" % (incoming_value, e))

            try:

                def our_entry(x):
                    return fn_id == x['fnId'] or dp_id == x['dpId']

                relevant_entries = list(filter(our_entry, data['TuyaMCU']))
                relevant_entries = [
                    "%s,%s" % (x['fnId'], x['dpId']) for x in relevant_entries
                ]
            except KeyError as e:
                raise AnsibleRuntimeError("Invalid response: %s, error: %s" %
                                          (data, e))

            if dp_id != 0:
                if len(relevant_entries) == 1:
                    existing_value = relevant_entries[0]
                else:
                    existing_value = relevant_entries
            else:
                if not relevant_entries:
                    # Missing entries equals to disabled entry
                    existing_value = incoming_value
                else:
                    existing_value = relevant_entries
        elif (command == 'DimmerRange'):
            try:
                existing_value = "%s,%s" % (data[command]['Min'],
                                            data[command]['Max'])
            except Exception as e:
                raise AnsibleRuntimeError(
                    "Invalid response payload: %s, error: %s" % (data, e))

        display.v(
            "[%s] command: %s,\n\t existing_value: '%s',\n\t incoming_value: '%s'"
            % (tasmota_host, command, existing_value,
               incoming_value if not no_log else ""))

        display.v("[%s] existing_uri: %s" % (tasmota_host, endpoint_uri))

        if existing_value != incoming_value:
            changed = True

            if not check_mode:
                change_params = copy.deepcopy(auth_params)
                # encode json if required
                if isinstance(incoming_value, dict):
                    change_params.update({
                        'cmnd':
                        ("%s %s" % (command, json.dumps(incoming_value)))
                    })
                else:
                    change_params.update(
                        {'cmnd': ("%s %s" % (command, incoming_value))})

                change_response = requests.get(url=endpoint_uri,
                                               params=change_params)
                if status_response.status_code != 200:
                    raise AnsibleRuntimeError("Unexpected response code: %s" %
                                              (status_response.status_code))

        if warnings:
            display.warning(warnings)
            result["warning"] = warnings

        result["changed"] = changed
        result["command"] = command
        result["tasmota_host"] = tasmota_host
        result["raw_data"] = data
        result["endpoint_uri"] = endpoint_uri
        result["incoming_value"] = incoming_value
        result["existing_value"] = existing_value

        return result