Exemple #1
0
    def get_system_boot_time(self, distribution):
        boot_time_command = self._get_value_from_facts(
            'BOOT_TIME_COMMANDS', distribution, 'DEFAULT_BOOT_TIME_COMMAND')
        if self._task.args.get('boot_time_command'):
            boot_time_command = self._task.args.get('boot_time_command')

            try:
                check_type_str(boot_time_command, allow_conversion=False)
            except TypeError as e:
                raise AnsibleError(
                    "Invalid value given for 'boot_time_command': %s." %
                    to_native(e))

        display.debug(
            "{action}: getting boot time with command: '{command}'".format(
                action=self._task.action, command=boot_time_command))
        command_result = self._low_level_execute_command(
            boot_time_command, sudoable=self.DEFAULT_SUDOABLE)

        if command_result['rc'] != 0:
            stdout = command_result['stdout']
            stderr = command_result['stderr']
            raise AnsibleError(
                "{action}: failed to get host boot time info, rc: {rc}, stdout: {out}, stderr: {err}"
                .format(action=self._task.action,
                        rc=command_result['rc'],
                        out=to_native(stdout),
                        err=to_native(stderr)))
        display.debug("{action}: last boot time: {boot}".format(
            action=self._task.action, boot=command_result['stdout'].strip()))
        return command_result['stdout'].strip()
Exemple #2
0
    def _check_type_str(self, value, param=None, prefix=''):
        opts = {
            'error': False,
            'warn': False,
            'ignore': True
        }

        # Ignore, warn, or error when converting to a string.
        allow_conversion = opts.get(self._string_conversion_action, True)
        try:
            return check_type_str(value, allow_conversion)
        except TypeError:
            common_msg = 'quote the entire value to ensure it does not change.'
            from_msg = '{0!r}'.format(value)
            to_msg = '{0!r}'.format(to_text(value))

            if param is not None:
                if prefix:
                    param = '{0}{1}'.format(prefix, param)

                from_msg = '{0}: {1!r}'.format(param, value)
                to_msg = '{0}: {1!r}'.format(param, to_text(value))

            if self._string_conversion_action == 'error':
                msg = common_msg.capitalize()
                raise TypeError(to_native(msg))
            elif self._string_conversion_action == 'warn':
                msg = ('The value "{0}" (type {1.__class__.__name__}) was converted to "{2}" (type string). '
                       'If this does not look like what you expect, {3}').format(from_msg, value, to_msg, common_msg)
                self.warn(to_native(msg))
                return to_native(value, errors='surrogate_or_strict')
Exemple #3
0
def check_type_access_endpoint(endpoint: 'Any') -> str:
    '''
    >>> check_type_access_endpoint('/me')
    '/me'
    >>> check_type_access_endpoint('/me/api/application')
    '/me/api/application'
    >>> check_type_access_endpoint('/me/api/application/*')
    '/me/api/application/*'
    >>> check_type_access_endpoint({})
    '%7B%7D'
    >>> check_type_access_endpoint(0.3)
    '0.3'
    >>> import warnings
    >>> warnings.simplefilter("ignore")
    >>> check_type_access_endpoint('/test-with/{{ ansible_value | default(default_value) }}')
    '/test-with/%7B%7B%20ansible_value%20%7C%20default%28default_value%29%20%7D%7D'
    >>> warnings.simplefilter("error")
    >>> check_type_access_endpoint('/test-with/{{ ansible_value | default(default_value) }}')
    Traceback (most recent call last):
        ...
    UserWarning: endpoint has brackets
    '''
    endpoint = check_type_str(endpoint)
    if '{{' in endpoint and '}}' in endpoint:
        warn("endpoint has brackets", UserWarning)
    endpoint = urlquote(endpoint, safe='*/')

    return endpoint
Exemple #4
0
def check_type_access_method(method: 'Any') -> str:
    '''
    >>> check_type_access_method('GET')
    'GET'
    >>> check_type_access_method('poSt')
    'POST'
    >>> check_type_access_method('invalid')
    Traceback (most recent call last):
        ...
    ValueError: INVALID must be one of (GET,POST,PUT,DELETE)
    >>> check_type_access_method({})
    Traceback (most recent call last):
        ...
    ValueError: {} must be one of (GET,POST,PUT,DELETE)
    >>> check_type_access_method(0.3)
    Traceback (most recent call last):
        ...
    ValueError: 0.3 must be one of (GET,POST,PUT,DELETE)
    '''
    method = check_type_str(method).upper()
    if method not in ovh.API_READ_WRITE:
        raise ValueError('%s must be one of (%s)' %
                         (method, ','.join(ovh.API_READ_WRITE)))

    return method
Exemple #5
0
    def get_shutdown_command_args(self, distribution):
        reboot_command = self._task.args.get('reboot_command')
        if reboot_command is not None:
            try:
                reboot_command = check_type_str(reboot_command,
                                                allow_conversion=False)
            except TypeError as e:
                raise AnsibleError(
                    "Invalid value given for 'reboot_command': %s." %
                    to_native(e))

            # No args were provided
            try:
                return reboot_command.split(' ', 1)[1]
            except IndexError:
                return ''
        else:
            args = self._get_value_from_facts('SHUTDOWN_COMMAND_ARGS',
                                              distribution,
                                              'DEFAULT_SHUTDOWN_COMMAND_ARGS')

            # Convert seconds to minutes. If less that 60, set it to 0.
            delay_min = self.pre_reboot_delay // 60
            reboot_message = self._task.args.get('msg',
                                                 self.DEFAULT_REBOOT_MESSAGE)
            return args.format(delay_sec=self.pre_reboot_delay,
                               delay_min=delay_min,
                               message=reboot_message)
    def process_playbook_values(self):
        ''' Get playbook values and perform input validation '''
        argument_spec = dict(
            vrf=dict(type='str', default='management'),
            connect_ssh_port=dict(type='int', default=22),
            file_system=dict(type='str', default='bootflash:'),
            file_pull=dict(type='bool', default=False),
            file_pull_timeout=dict(type='int', default=300),
            file_pull_compact=dict(type='bool', default=False),
            file_pull_kstack=dict(type='bool', default=False),
            local_file=dict(type='path'),
            local_file_directory=dict(type='path'),
            remote_file=dict(type='path'),
            remote_scp_server=dict(type='str'),
            remote_scp_server_user=dict(type='str'),
            remote_scp_server_password=dict(no_log=True),
        )

        playvals = {}
        # Process key value pairs from playbook task
        for key in argument_spec.keys():
            playvals[key] = self._task.args.get(key, argument_spec[key].get('default'))
            if playvals[key] is None:
                continue

            option_type = argument_spec[key].get('type', 'str')
            try:
                if option_type == 'str':
                    playvals[key] = validation.check_type_str(playvals[key])
                elif option_type == 'int':
                    playvals[key] = validation.check_type_int(playvals[key])
                elif option_type == 'bool':
                    playvals[key] = validation.check_type_bool(playvals[key])
                elif option_type == 'path':
                    playvals[key] = validation.check_type_path(playvals[key])
                else:
                    raise AnsibleError('Unrecognized type <{0}> for playbook parameter <{1}>'.format(option_type, key))

            except (TypeError, ValueError) as e:
                raise AnsibleError("argument %s is of type %s and we were unable to convert to %s: %s"
                                   % (key, type(playvals[key]), option_type, to_native(e)))

        # Validate playbook dependencies
        if playvals['file_pull']:
            if playvals.get('remote_file') is None:
                raise AnsibleError('Playbook parameter <remote_file> required when <file_pull> is True')
            if playvals.get('remote_scp_server') is None:
                raise AnsibleError('Playbook parameter <remote_scp_server> required when <file_pull> is True')

        if playvals['remote_scp_server'] or \
           playvals['remote_scp_server_user']:

            if None in (playvals['remote_scp_server'],
                        playvals['remote_scp_server_user']):
                params = '<remote_scp_server>, <remote_scp_server_user>'
                raise AnsibleError('Playbook parameters {0} must be set together'.format(params))

        return playvals
Exemple #7
0
    def get_shutdown_command(self, task_vars, distribution):
        reboot_command = self._task.args.get('reboot_command')
        if reboot_command is not None:
            try:
                reboot_command = check_type_str(reboot_command,
                                                allow_conversion=False)
            except TypeError as e:
                raise AnsibleError(
                    "Invalid value given for 'reboot_command': %s." %
                    to_native(e))
            shutdown_bin = reboot_command.split(' ', 1)[0]
        else:
            shutdown_bin = self._get_value_from_facts(
                'SHUTDOWN_COMMANDS', distribution, 'DEFAULT_SHUTDOWN_COMMAND')

        if shutdown_bin[0] == '/':
            return shutdown_bin
        else:
            default_search_paths = [
                '/sbin', '/bin', '/usr/sbin', '/usr/bin', '/usr/local/sbin'
            ]
            search_paths = self._task.args.get('search_paths',
                                               default_search_paths)

            try:
                # Convert bare strings to a list
                search_paths = check_type_list(search_paths)
            except TypeError:
                err_msg = "'search_paths' must be a string or flat list of strings, got {0}"
                raise AnsibleError(err_msg.format(search_paths))

            display.debug(
                '{action}: running find module looking in {paths} to get path for "{command}"'
                .format(action=self._task.action,
                        command=shutdown_bin,
                        paths=search_paths))

            find_result = self._execute_module(
                task_vars=task_vars,
                # prevent collection search by calling with ansible.legacy (still allows library/ override of find)
                module_name='ansible.legacy.find',
                module_args={
                    'paths': search_paths,
                    'patterns': [shutdown_bin],
                    'file_type': 'any'
                })

            full_path = [x['path'] for x in find_result['files']]
            if not full_path:
                raise AnsibleError(
                    'Unable to find command "{0}" in search paths: {1}'.format(
                        shutdown_bin, search_paths))
            return full_path[0]
def ensure_type(value, type_name):
    if type_name == 'str':
        return check_type_str(value)
    if type_name == 'list':
        return check_type_list(value)
    if type_name == 'dict':
        return check_type_dict(value)
    if type_name == 'bool':
        return check_type_bool(value)
    if type_name == 'int':
        return check_type_int(value)
    if type_name == 'float':
        return check_type_float(value)
    return value
 def _get_option(self, name, type_name, default=None, accept_none=False):
     value = self._task.args.get(name)
     if value is None:
         if accept_none:
             return value
         elif default is not None:
             value = default
         else:
             raise Exception("Option %s must be specified" % name)
     checkers = {
         'str': lambda v: check_type_str(v, allow_conversion=False),
         'bool': check_type_bool,
     }
     try:
         return checkers[type_name](value)
     except TypeError as e:
         msg = "Value for option %s" % name
         msg += " is of type %s and we were unable to convert to %s: %s" % (
             type(value), type_name, to_native(e))
         raise Exception(msg)
Exemple #10
0
    def __init__(self):
        arg_spec = dict(
            port=dict(
                type='int',
                required=True,
            ),
            address=dict(
                type=str,
                required=False,
                default='0.0.0.0'
            ),
            response_body=dict(
                type=lambda v: check_type_str(v).encode('utf-8'),
                required=False,
                default='Success',
                no_log=True,
            ),
            response_headers=dict(
                type=dict,
                required=False,
                no_log=True,
                default={
                    "Content-Type": self.default_content_type,
                    "Server": "Ansible - holyhole.ovh.wait_for_request",
                },
            ),
            response_status=dict(
                type=int,
                required=False,
                default=HTTPStatus.OK,
            ),
        )

        self.request: 'Optional[BaseHTTPRequestHandler]' = None

        self.module = AnsibleModule(argument_spec=arg_spec, supports_check_mode=True)
        self.exec()
    def _process_option_proxies(self):
        '''check if 'proxies' option is dict or str and set it appropriately'''

        proxies_opt = self._options.get_option('proxies')

        if proxies_opt is None:
            return

        try:
            # if it can be interpreted as dict
            # do it
            proxies = check_type_dict(proxies_opt)
        except TypeError:
            # if it can't be interpreted as dict
            proxy = check_type_str(proxies_opt)
            # but can be interpreted as str
            # use this str as http and https proxy
            proxies = {
                'http': proxy,
                'https': proxy,
            }

        # record the new/interpreted value for 'proxies' option
        self._options.set_option('proxies', proxies)
    def process_playbook_values(self):
        """ Get playbook values and perform input validation """
        argument_spec = dict(
            vrf=dict(type="str", default="management"),
            connect_ssh_port=dict(type="int", default=22),
            file_system=dict(type="str", default="bootflash:"),
            file_pull=dict(type="bool", default=False),
            file_pull_timeout=dict(type="int", default=300),
            file_pull_protocol=dict(
                type="str",
                default="scp",
                choices=["scp", "sftp", "http", "https", "tftp", "ftp"],
            ),
            file_pull_compact=dict(type="bool", default=False),
            file_pull_kstack=dict(type="bool", default=False),
            local_file=dict(type="path"),
            local_file_directory=dict(type="path"),
            remote_file=dict(type="path"),
            remote_scp_server=dict(type="str"),
            remote_scp_server_user=dict(type="str"),
            remote_scp_server_password=dict(no_log=True),
        )

        playvals = {}
        # Process key value pairs from playbook task
        for key in argument_spec.keys():
            playvals[key] = self._task.args.get(
                key, argument_spec[key].get("default"))
            if playvals[key] is None:
                continue

            option_type = argument_spec[key].get("type", "str")
            try:
                if option_type == "str":
                    playvals[key] = validation.check_type_str(playvals[key])
                elif option_type == "int":
                    playvals[key] = validation.check_type_int(playvals[key])
                elif option_type == "bool":
                    playvals[key] = validation.check_type_bool(playvals[key])
                elif option_type == "path":
                    playvals[key] = validation.check_type_path(playvals[key])
                else:
                    raise AnsibleError(
                        "Unrecognized type <{0}> for playbook parameter <{1}>".
                        format(option_type, key))

            except (TypeError, ValueError) as e:
                raise AnsibleError(
                    "argument %s is of type %s and we were unable to convert to %s: %s"
                    % (key, type(playvals[key]), option_type, to_native(e)))

            if "choices" in argument_spec[key] and playvals[
                    key] not in argument_spec[key].get("choices"):
                raise AnsibleError(
                    "argument {0} with value {1} is not valid. Allowed values are {2}"
                    .format(
                        key,
                        playvals[key],
                        ", ".join(argument_spec[key].get("choices")),
                    ))

        # Validate playbook dependencies
        if playvals["file_pull"]:
            if playvals.get("remote_file") is None:
                raise AnsibleError(
                    "Playbook parameter <remote_file> required when <file_pull> is True"
                )
            if playvals.get("remote_scp_server") is None:
                raise AnsibleError(
                    "Playbook parameter <remote_scp_server> required when <file_pull> is True"
                )

        if playvals["remote_scp_server"] or playvals["remote_scp_server_user"]:

            if None in (
                    playvals["remote_scp_server"],
                    playvals["remote_scp_server_user"],
            ):
                params = "<remote_scp_server>, <remote_scp_server_user>"
                raise AnsibleError(
                    "Playbook parameters {0} must be set together".format(
                        params))

        return playvals
Exemple #13
0
def test_check_type_str_no_conversion(value, expected):
    with pytest.raises(TypeError) as e:
        check_type_str(value, allow_conversion=False)
    assert 'is not a string and conversion is not allowed' in to_native(e.value)
Exemple #14
0
def test_check_type_str(value, expected):
    assert expected == check_type_str(value)