示例#1
0
 def send(self,
          command,
          prompt=None,
          answer=None,
          newline=True,
          sendonly=False,
          prompt_retry_check=False,
          check_all=False):
     '''
     Sends the command to the device in the opened shell
     '''
     if check_all:
         prompt_len = len(to_list(prompt))
         answer_len = len(to_list(answer))
         if prompt_len != answer_len:
             raise AnsibleConnectionFailure(
                 "Number of prompts (%s) is not same as that of answers (%s)"
                 % (prompt_len, answer_len))
     try:
         cmd = b'%s\r' % command
         self._history.append(cmd)
         self._ssh_shell.sendall(cmd)
         self._log_messages('send command: %s' % cmd)
         if sendonly:
             return
         response = self.receive(command, prompt, answer, newline,
                                 prompt_retry_check, check_all)
         return to_text(response, errors='surrogate_then_replace')
     except (socket.timeout, AttributeError):
         self.queue_message('error', traceback.format_exc())
         raise AnsibleConnectionFailure(
             "timeout value %s seconds reached while trying to send command: %s"
             % (self._ssh_shell.gettimeout(), command.strip()))
示例#2
0
def test_to_list():
    for scalar in ('string', 1, True, False, None):
        assert isinstance(to_list(scalar), list)

    for container in ([1, 2, 3], {'one': 1}):
        assert isinstance(to_list(container), list)

    test_list = [1, 2, 3]
    assert id(test_list) != id(to_list(test_list))
示例#3
0
        def run_queue(queue, output):
            try:
                response = to_list(
                    self._connection.send_request(queue, output=output))
            except ConnectionError as exc:
                if check_rc:
                    raise
                return to_list(to_text(exc))

            if output == 'json':
                response = [json.loads(item) for item in response]
            return response
示例#4
0
    def run_commands(self, commands=None, check_rc=True):
        if commands is None:
            raise ValueError("'commands' value is required")
        responses = list()
        for cmd in to_list(commands):
            if not isinstance(cmd, Mapping):
                cmd = {'command': cmd}

            output = cmd.pop('output', None)
            if output:
                cmd['command'] = self._get_command_with_output(cmd['command'], output)

            try:
                out = self.send_command(**cmd)
            except AnsibleConnectionFailure as e:
                if check_rc:
                    raise
                out = getattr(e, 'err', e)
            out = to_text(out, errors='surrogate_or_strict')

            if out is not None:
                try:
                    out = json.loads(out)
                except ValueError:
                    out = out.strip()

                responses.append(out)
        return responses
示例#5
0
    def send_request(self, data, **message_kwargs):
        data = to_list(data)
        become = self._become
        if become:
            self.connection.queue_message('vvvv', 'firing event: on_become')
            data.insert(0, {"cmd": "enable", "input": self._become_pass})

        output = message_kwargs.get('output', 'text')
        request = request_builder(data, output)
        headers = {'Content-Type': 'application/json-rpc'}

        response, response_data = self.connection.send('/command-api',
                                                       request,
                                                       headers=headers,
                                                       method='POST')

        try:
            response_data = json.loads(to_text(response_data.getvalue()))
        except ValueError:
            raise ConnectionError(
                'Response was not valid JSON, got {0}'.format(
                    to_text(response_data.getvalue())))

        results = handle_response(response_data)

        if become:
            results = results[1:]
        if len(results) == 1:
            results = results[0]

        return results
    def send_request(self, data, **message_kwargs):
        output = None
        queue = list()
        responses = list()

        for item in to_list(data):
            cmd_output = message_kwargs.get('output', 'text')
            if isinstance(item, dict):
                command = item['command']
                if 'output' in item:
                    cmd_output = item['output']
            else:
                command = item

            # Emulate '| json' from CLI
            if command.endswith('| json'):
                command = command.rsplit('|', 1)[0]
                cmd_output = 'json'

            if output and output != cmd_output:
                responses.extend(self._run_queue(queue, output))
                queue = list()

            output = cmd_output
            queue.append(command)

        if queue:
            responses.extend(self._run_queue(queue, output))

        if len(responses) == 1:
            return responses[0]
        return responses
    def execute_module(self):
        """ Execute the module

        :rtype: A dictionary
        :returns: The result from module execution
        """
        result = {'changed': False}

        existing_interfaces_facts = self.get_interfaces_facts()

        config_xmls = self.set_config(existing_interfaces_facts)
        with locked_config(self._module):
            for config_xml in to_list(config_xmls):
                diff = load_config(self._module, config_xml, [])

            commit = not self._module.check_mode
            if diff:
                if commit:
                    commit_configuration(self._module)
                else:
                    discard_changes(self._module)
                result['changed'] = True

                if self._module._diff:
                    result['diff'] = {'prepared': diff}

        result['commands'] = config_xmls

        changed_interfaces_facts = self.get_interfaces_facts()

        result['before'] = existing_interfaces_facts
        if result['changed']:
            result['after'] = changed_interfaces_facts

        return result
    def run_commands(self, commands=None, check_rc=True):
        if commands is None:
            raise ValueError("'commands' value is required")

        responses = list()
        for cmd in to_list(commands):
            if not isinstance(cmd, Mapping):
                cmd = {'command': cmd}

            output = cmd.pop('output', None)
            if output:
                raise ValueError(
                    "'output' value %s is not supported for run_commands" %
                    output)

            try:
                out = self.send_command(**cmd)
            except AnsibleConnectionFailure as e:
                if check_rc:
                    raise
                out = getattr(e, 'err', e)

            responses.append(out)

        return responses
示例#9
0
    def render(self, config=None, nbr_list=None):
        commands = list()
        safe_list = list()
        if not nbr_list:
            nbr_list = self.get_value('config.neighbors')

        for item in nbr_list:
            neighbor_commands = list()
            context = 'neighbor %s' % item['neighbor']
            cmd = '%s remote-as %s' % (context, item['remote_as'])

            if not config or cmd not in config:
                neighbor_commands.append(cmd)

            for key, value in iteritems(item):
                if value is not None:
                    meth = getattr(self, '_render_%s' % key, None)
                    if meth:
                        resp = meth(item, config)
                        if resp:
                            neighbor_commands.extend(to_list(resp))

            commands.extend(neighbor_commands)
            safe_list.append(context)

        if self.params['operation'] == 'replace':
            if config and safe_list:
                commands.extend(self._negate_config(config, safe_list))

        return commands
示例#10
0
    def set_config(self, existing_bfd_interfaces_facts, platform):
        """ Collect the configuration from the args passed to the module,
            collect the current configuration (as a dict from facts)

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        if re.search('N[56]K', platform):
            # Some platforms do not support the 'bfd' interface keyword;
            # remove the 'bfd' key from each want/have interface.
            orig_want = self._module.params['config']
            want = []
            for w in orig_want:
                del w['bfd']
                want.append(w)
            orig_have = existing_bfd_interfaces_facts
            have = []
            for h in orig_have:
                del h['bfd']
                have.append(h)
        else:
            want = self._module.params['config']
            have = existing_bfd_interfaces_facts

        resp = self.set_state(want, have)
        return to_list(resp)
示例#11
0
    def run_commands(self, commands, check_rc=True):
        """Run list of commands on remote device and return results
        """
        output = None
        queue = list()
        responses = list()

        def _send(commands, output):
            return self.send_request(commands, output, check_status=check_rc)

        for item in to_list(commands):
            if is_json(item['command']):
                item['command'] = str(item['command']).rsplit('|', 1)[0]
                item['output'] = 'json'

            if all((output == 'json', item['output'] == 'text')) or all((output == 'text', item['output'] == 'json')):
                responses.extend(_send(queue, output))
                queue = list()

            output = item['output'] or 'json'
            queue.append(item['command'])

        if queue:
            responses.extend(_send(queue, output))

        return responses
    def render(self, config=None):
        commands = list()
        safe_list = list()

        router_context = 'router bgp %s' % self.get_value('config.bgp_as')
        context_config = None

        for item in self.get_value('config.address_family'):
            context = 'address-family %s %s' % (item['afi'], item['safi'])
            context_commands = list()

            if config:
                context_path = [router_context, context]
                context_config = self.get_config_context(config, context_path, indent=1)

            for key, value in iteritems(item):
                if value is not None:
                    meth = getattr(self, '_render_%s' % key, None)
                    if meth:
                        resp = meth(item, context_config)
                        if resp:
                            context_commands.extend(to_list(resp))

            if context_commands:
                commands.append(context)
                commands.extend(context_commands)
                commands.append('exit')

            safe_list.append(context)

        if config:
            resp = self._negate_config(config, safe_list)
            commands.extend(resp)

        return commands
示例#13
0
    def edit_config(self,
                    candidate=None,
                    commit=True,
                    replace=None,
                    comment=None):
        resp = {}
        operations = self.get_device_operations()
        self.check_edit_config_capability(operations, candidate, commit,
                                          replace, comment)

        results = []
        requests = []
        if commit:
            self.send_command('configure terminal')
            for line in to_list(candidate):
                if not isinstance(line, Mapping):
                    line = {'command': line}

                cmd = line['command']
                if cmd != 'end' and cmd[0] != '!':
                    results.append(self.send_command(**line))
                    requests.append(cmd)

            self.send_command('end')
        else:
            raise ValueError('check mode is not supported')

        resp['request'] = requests
        resp['response'] = results
        return resp
示例#14
0
    def edit_config(self, candidate=None, commit=True, replace=None, comment=None):

        operations = self.get_device_operations()
        self.check_edit_config_capability(operations, candidate, commit, replace, comment)

        if (commit is False) and (not self.supports_sessions()):
            raise ValueError('check mode is not supported without configuration session')

        resp = {}
        session = None
        if self.supports_sessions():
            session = 'ansible_%s' % int(time.time())
            resp.update({'session': session})
            self.send_command('configure session %s' % session)
            if replace:
                self.send_command('rollback clean-config')
        else:
            self.send_command('configure')

        results = []
        requests = []
        multiline = False
        for line in to_list(candidate):
            if not isinstance(line, Mapping):
                line = {'command': line}

            cmd = line['command']
            if cmd == 'end':
                continue
            elif cmd.startswith('banner') or multiline:
                multiline = True
            elif cmd == 'EOF' and multiline:
                multiline = False

            if multiline:
                line['sendonly'] = True

            if cmd != 'end' and cmd[0] != '!':
                try:
                    results.append(self.send_command(**line))
                    requests.append(cmd)
                except AnsibleConnectionFailure as e:
                    self.discard_changes(session)
                    raise AnsibleConnectionFailure(e.message)

        resp['request'] = requests
        resp['response'] = results
        if self.supports_sessions():
            out = self.send_command('show session-config diffs')
            if out:
                resp['diff'] = out.strip()

            if commit:
                self.commit()
            else:
                self.discard_changes(session)
        else:
            self.send_command('end')
        return resp
示例#15
0
 def get_section(self, config, section):
     if config is not None:
         netcfg = NetworkConfig(indent=1, contents=config)
         try:
             config = netcfg.get_block_config(to_list(section))
         except ValueError:
             config = None
         return config
示例#16
0
 def get_config_context(self, config, path, indent=1):
     if config is not None:
         netcfg = NetworkConfig(indent=indent, contents=config)
         try:
             config = netcfg.get_block_config(to_list(path))
         except ValueError:
             config = None
         return config
def load_config(module, config, commit=False):
    conn = get_connection(module)
    try:
        resp = conn.edit_config(to_list(config) + ['top'], commit)
    except ConnectionError as exc:
        module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))

    diff = resp.get('diff', '')
    return to_text(diff, errors='surrogate_then_replace').strip()
示例#18
0
def execute_show_commands(module, commands, output='text'):
    cmds = []
    for command in to_list(commands):
        cmd = {'command': command,
               'output': output,
               }
        cmds.append(cmd)
    body = run_commands(module, cmds)
    return body
def parse_roles(data):
    configured_roles = None
    if 'TABLE_role' in data:
        configured_roles = data.get('TABLE_role')['ROW_role']

    roles = list()
    if configured_roles:
        for item in to_list(configured_roles):
            roles.append(item['role'])
    return roles
 def set_config(self, existing_l3_interfaces_facts):
     """ Collect the configuration from the args passed to the module,
         collect the current configuration (as a dict from facts)
     :rtype: A list
     :returns: the commands necessary to migrate the current configuration
               to the desired configuration
     """
     want = self._module.params['config']
     have = existing_l3_interfaces_facts
     resp = self.set_state(want, have)
     return to_list(resp)
示例#21
0
 def set_config(self, existing_tms_global_facts):
     """ Collect the configuration from the args passed to the module,
         collect the current configuration (as a dict from facts)
     :rtype: A list
     :returns: the commands necessary to migrate the current configuration
               to the desired configuration
     """
     config = self._module.params['config']
     want = dict((k, v) for k, v in config.items() if v is not None)
     have = existing_tms_global_facts
     resp = self.set_state(want, have)
     return to_list(resp)
    def set_config(self, existing_lldp_global_facts):
        """ Collect the configuration from the args passed to the module,
            collect the current configuration (as a dict from facts)

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        want = self._module.params['config']
        if not want and self._module.params['state'] == 'deleted':
            want = {}
        have = existing_lldp_global_facts
        resp = self.set_state(want, have)
        return to_list(resp)
示例#23
0
 def wrapper(cls):
     _provider_lock.acquire()
     try:
         if network_os not in _registered_providers:
             _registered_providers[network_os] = {}
         for ct in cls.supported_connections:
             if ct not in _registered_providers[network_os]:
                 _registered_providers[network_os][ct] = {}
         for item in to_list(module_name):
             for entry in itervalues(_registered_providers[network_os]):
                 entry[item] = cls
     finally:
         _provider_lock.release()
     return cls
示例#24
0
    def render(self, config=None):
        commands = list()

        existing_as = None
        if config:
            match = re.search(r'router bgp (\d+)', config, re.M)
            if match:
                existing_as = match.group(1)

        operation = self.params['operation']

        context = None
        if self.params['config']:
            context = 'router bgp %s' % self.get_value('config.bgp_as')

        if operation == 'delete':
            if existing_as:
                commands.append('no router bgp %s' % existing_as)
            elif context:
                commands.append('no %s' % context)

        else:
            self._validate_input(config)
            if operation == 'replace':
                if existing_as and int(existing_as) != self.get_value(
                        'config.bgp_as'):
                    commands.append('no router bgp %s' % existing_as)
                    config = None

            elif operation == 'override':
                if existing_as:
                    commands.append('no router bgp %s' % existing_as)
                config = None

            context_commands = list()

            for key, value in iteritems(self.get_value('config')):
                if value is not None:
                    meth = getattr(self, '_render_%s' % key, None)
                    if meth:
                        resp = meth(config)
                        if resp:
                            context_commands.extend(to_list(resp))

            if context and context_commands:
                commands.append(context)
                commands.extend(context_commands)
                commands.append('exit')
        return commands
def map_config_to_obj(module):
    out = run_commands(module, ['show user-account | json'])
    data = out[0]

    objects = list()

    for item in to_list(data['TABLE_template']['ROW_template']):
        objects.append({
            'name': item['usr_name'],
            'configured_password': parse_password(item),
            'sshkey': item.get('sshkey_info'),
            'roles': parse_roles(item),
            'state': 'present'
        })
    return objects
示例#26
0
    def set_config(self, existing_vlans_facts):
        """ Collect the configuration from the args passed to the module,
            collect the current configuration (as a dict from facts)

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        config = self._module.params.get('config')
        want = []
        if config:
            for w in config:
                want.append(remove_empties(w))
        have = existing_vlans_facts
        resp = self.set_state(want, have)
        return to_list(resp)
示例#27
0
    def get_config(self, source='running', format='text', flags=None):
        options_values = self.get_option_values()
        if format not in options_values['format']:
            raise ValueError("'format' value %s is invalid. Valid values are %s" % (format, ','.join(options_values['format'])))

        lookup = {'running': 'running-config', 'startup': 'startup-config'}
        if source not in lookup:
            raise ValueError("fetching configuration from %s is not supported" % source)

        cmd = 'show %s ' % lookup[source]
        if format and format != 'text':
            cmd += '| %s ' % format

        cmd += ' '.join(to_list(flags))
        cmd = cmd.strip()
        return self.send_command(cmd)
示例#28
0
    def edit_config(self, candidate=None, commit=True, replace=None, comment=None):
        resp = list()

        self.check_edit_config_capability(candidate, commit, replace, comment)

        if replace:
            candidate = 'config replace {0}'.format(replace)

        responses = self._connection.send_request(candidate, output='config')
        for response in to_list(responses):
            if response != '{}':
                resp.append(response)
        if not resp:
            resp = ['']

        return resp
    def edit_config(self,
                    candidate=None,
                    commit=True,
                    replace=None,
                    comment=None):
        resp = {}
        operations = self.get_device_operations()
        self.check_edit_config_capability(operations, candidate, commit,
                                          replace, comment)

        results = []
        requests = []
        self.send_command('configure')
        for cmd in to_list(candidate):
            if not isinstance(cmd, Mapping):
                cmd = {'command': cmd}

            results.append(self.send_command(**cmd))
            requests.append(cmd['command'])
        out = self.get('compare')
        out = to_text(out, errors='surrogate_or_strict')
        diff_config = out if not out.startswith('No changes') else None

        if diff_config:
            if commit:
                try:
                    self.commit(comment)
                except AnsibleConnectionFailure as e:
                    msg = 'commit failed: %s' % e.message
                    self.discard_changes()
                    raise AnsibleConnectionFailure(msg)
                else:
                    self.send_command('exit')
            else:
                self.discard_changes()
        else:
            self.send_command('exit')
            if to_text(self._connection.get_prompt(),
                       errors='surrogate_or_strict').strip().endswith('#'):
                self.discard_changes()

        if diff_config:
            resp['diff'] = diff_config
        resp['response'] = results
        resp['request'] = requests
        return resp
    def set_config(self, existing_hsrp_interfaces_facts):
        """ Collect the configuration from the args passed to the module,
            collect the current configuration (as a dict from facts)

        :rtype: A list
        :returns: the commands necessary to migrate the current configuration
                  to the desired configuration
        """
        config = self._module.params['config']
        want = []
        if config:
            for w in config:
                w.update({'name': normalize_interface(w['name'])})
                want.append(w)
        have = existing_hsrp_interfaces_facts
        resp = self.set_state(want, have)
        return to_list(resp)