Пример #1
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
Пример #2
0
def get_config(module, flags=None):
    flag_str = ' '.join(to_list(flags))

    try:
        return _DEVICE_CONFIGS[flag_str]
    except KeyError:
        connection = get_connection(module)
        try:
            out = connection.get_config(flags=flags)
        except ConnectionError as exc:
            module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
        cfg = to_text(out, errors='surrogate_then_replace').strip()
        _DEVICE_CONFIGS[flag_str] = cfg
        return cfg
    def set_config(self, existing_lacp_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.get("config")
        if not want:
            want = {}
        have = existing_lacp_facts
        resp = self.set_state(want, have)
        return to_list(resp)
Пример #4
0
    def edit_config(self, command):
        for cmd in chain(['configure terminal'], to_list(command), ['end']):
            if isinstance(cmd, dict):
                command = cmd['command']
                prompt = cmd['prompt']
                answer = cmd['answer']
                newline = cmd.get('newline', True)
            else:
                command = cmd
                prompt = None
                answer = None
                newline = True

            self.send_command(command, prompt, answer, False, newline)
Пример #5
0
def load_config(module, commands):

    rc, out, err = exec_command(module, 'configure terminal')
    if rc != 0:
        module.fail_json(msg='unable to enter configuration mode', err=to_text(out, errors='surrogate_then_replace'))

    for command in to_list(commands):
        if command == 'end':
            continue
        rc, out, err = exec_command(module, command)
        if rc != 0:
            module.fail_json(msg=to_text(err, errors='surrogate_then_replace'), command=command, rc=rc)

    exec_command(module, 'end')
Пример #6
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
Пример #7
0
    def set_config(self, existing_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']
        normalize_interface_name(want, self._module)
        have = existing_interfaces_facts

        resp = self.set_state(want, have)
        return to_list(resp)
Пример #8
0
def load_config(module, commands):
    response = {}
    results = []
    requests = []
    for line in to_list(commands):
        requests.append(line)
        out = run_commands(module, commands=line)
        results.append("\n".join(out))
        reset_config(line)

    response["results"] = results
    response["requests"] = requests

    return response
Пример #9
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
Пример #10
0
    def send_requests(self, requests):
        """Send a list of http requests to remote device and return results
        """
        if requests is None:
            raise ValueError("'requests' value is required")

        responses = list()
        for req in to_list(requests):
            try:
                response = self._connection.send_request(**req)
            except ConnectionError as exc:
                self._module.fail_json(msg=to_text(exc, errors='surrogate_then_replace'))
            responses.append(response)
        return responses
Пример #11
0
    def run_commands(self, commands, check_rc=True):
        """Runs list of commands on remote device and returns results"""
        output = None
        queue = list()
        responses = list()

        def run_queue(queue, output, version):
            try:
                response = to_list(
                    self._connection.send_request(
                        queue, output=output, version=version
                    )
                )
            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

        for item in to_list(commands):
            cmd_output = "text"
            if isinstance(item, dict):
                command = item["command"]
                if "output" in item:
                    cmd_output = item["output"]
                if "version" in item:
                    version = item["version"]
            else:
                command = item

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

            if output and output != cmd_output:
                responses.extend(run_queue(queue, output, version))
                queue = list()

            output = cmd_output
            queue.append(command)

        if queue:
            responses.extend(run_queue(queue, output, version))

        return responses
Пример #12
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 not self.is_classic_mode():
            raise ValueError(
                "Nokia SROS node is not running in classic mode. Use ansible_network_os=nokia.sros.md"
            )

        if not commit:
            raise ValueError(
                "Changes without commit or in --check mode are not supported by light plugin."
            )

        requests = []
        responses = []

        try:
            self.send_command('exit all')
            for cmd in to_list(candidate):
                if isinstance(cmd, Mapping):
                    requests.append(cmd['command'])
                    responses.append(self.send_command(**cmd))
                else:
                    requests.append(cmd)
                    responses.append(self.send_command(cmd))

        except AnsibleConnectionFailure as exc:
            self.send_command('exit all')
            raise exc

        self.send_command('exit all')
        prompt = self._connection.get_prompt()
        match = re.search(
            r'^\*',
            to_text(prompt, errors='surrogate_or_strict').strip())
        if match:
            return {
                'request': requests,
                'response': responses,
                'diff': match.group(0)
            }
        else:
            return {'request': requests, 'response': responses}
Пример #13
0
    def get_config(self, source="running", flags=None, format=None):
        if source not in ("running", "startup"):
            raise ValueError(
                "fetching configuration from %s is not supported" % source
            )
        if not flags:
            flags = []
        if source == "running":
            cmd = "show running-config "
        else:
            cmd = "show startup-config "

        cmd += " ".join(to_list(flags))
        cmd = cmd.strip()
        return self.send_command(cmd)
Пример #14
0
    def get_config(self, source='running', flags=None):
        if source not in ('running', 'startup'):
            raise ValueError(
                "fetching configuration from %s is not supported" % source)

        if source == 'running':
            cmd = 'show running-config '
        else:
            cmd = 'show startup-config '

        if flags:
            cmd += ' '.join(to_list(flags))
            cmd = cmd.strip()

        return self.send_command(cmd)
Пример #15
0
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
Пример #16
0
 def _set_config(self, existing):
     """ 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 deisred configuration
     """
     config = self._module.params.get("config")
     want = []
     if config:
         for each in config:
             want.append(each)
     have = existing
     resp = self._set_state(want, have)
     return to_list(resp)
    def set_config(self, existing_acl_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 deisred configuration
        """
        want = self._module.params["config"]
        if want:
            for item in want:
                item["name"] = normalize_interface(item["name"])

        have = existing_acl_interfaces_facts
        resp = self.set_state(want, have)
        return to_list(resp)
def get_startup_config(module, flags=None):
    reply = run_commands(module, {'command': 'show switch', 'output': 'text'})
    match = re.search(r'Config Selected: +(\S+)\.cfg',
                      to_text(reply, errors='surrogate_or_strict').strip(),
                      re.MULTILINE)
    if match:
        cfgname = match.group(1).strip()
        command = ' '.join(['debug cfgmgr show configuration file', cfgname])
        if flags:
            command += ' '.join(to_list(flags)).strip()
        reply = run_commands(module, {'command': command, 'output': 'text'})
        data = reply[0]
    else:
        data = ''
    return data
Пример #19
0
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
Пример #20
0
 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
     """
     config = self._module.params.get("config")
     want = []
     if config:
         for each in config:
             each.update({"name": normalize_interface(each["name"])})
             want.append(each)
     have = existing_l3_interfaces_facts
     resp = self.set_state(want, have)
     return to_list(resp)
Пример #21
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
Пример #22
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)
Пример #23
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 not self.is_classic_mode():
            raise ValueError("Nokia SROS node is not running in classic mode. Use ansible_network_os=nokia.sros.md")

        requests = []
        responses = []

        try:
            self.send_command('exit all')
            self.send_command('admin rollback save')  # Save rollback to compare if changes occur. This rollback will be removed upon module completion.
            for cmd in to_list(candidate):
                if isinstance(cmd, Mapping):
                    requests.append(cmd['command'])
                    responses.append(self.send_command(**cmd))
                else:
                    requests.append(cmd)
                    responses.append(self.send_command(cmd))

        except AnsibleConnectionFailure as exc:
            self.send_command('exit all')
            self.send_command('admin rollback revert latest-rb')
            self.send_command('admin rollback delete latest-rb')
            raise exc

        self.send_command('exit all')
        rawdiffs = self.send_command('admin rollback compare')
        match = re.search(r'\r?\n-+\r?\n(.*)\r?\n-+\r?\n', rawdiffs, re.DOTALL)
        if match:
            if commit:
                pass
            else:
                # Special hack! We load the config to running and rollback
                # to just figure out the delta. this might be risky in
                # check-mode, because it causes the changes contained to
                # become temporary active.

                self.send_command('admin rollback revert latest-rb')
            # Remove latest rollback to leave rollback history intact.
            self.send_command('admin rollback delete latest-rb')
            return {'request': requests, 'response': responses, 'diff': match.group(1)}
        else:
            # Remove latest rollback to leave rollback history intact.
            self.send_command('admin rollback delete latest-rb')
            return {'request': requests, 'response': responses}
Пример #24
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 = []
        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
Пример #25
0
    def edit_config(
        self,
        candidate=None,
        commit=True,
        admin=False,
        exclusive=False,
        replace=None,
        comment=None,
        label=None,
    ):
        operations = self.get_device_operations()
        self.check_edit_config_capability(
            operations, candidate, commit, replace, comment
        )

        resp = {}
        results = []
        requests = []

        self.configure(admin=admin, exclusive=exclusive)

        if replace:
            candidate = "load {0}".format(replace)

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

        # Before any commit happend, we can get a real configuration
        # diff from the device and make it available by the iosxr_config module.
        # This information can be usefull either in check mode or normal mode.
        resp["show_commit_config_diff"] = self.get("show commit changes diff")

        if commit:
            self.commit(comment=comment, label=label, replace=replace)
        else:
            self.discard_changes()

        self.abort(admin=admin)

        resp["request"] = requests
        resp["response"] = results
        return resp
Пример #26
0
    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)
Пример #27
0
    def get_config(self, source='running', flags=None, format=None):
        if source not in ('running', 'startup'):
            raise ValueError("fetching configuration from %s is not supported" % source)

        if format:
            raise ValueError("'format' value %s is not supported for get_config" % format)

        if not flags:
            flags = []
        if source == 'running':
            cmd = 'show running-config '
            cmd += ' '.join(to_list(flags))
            cmd = cmd.strip()
        else:
            cmd = 'more /intflash/config.cfg'

        return self.send_command(cmd)
Пример #28
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)

        resp = {}
        results = []
        requests = []

        if replace:
            candidate = "load override {0}".format(replace)

        for line in to_list(candidate):
            if not isinstance(line, Mapping):
                line = {"command": line}
            cmd = line["command"]
            try:
                results.append(self.send_command(**line))
            except AnsibleConnectionFailure as exc:
                if "error: commit failed" in exc.message:
                    self.discard_changes()
                raise
            requests.append(cmd)

        diff = self.compare_configuration()
        if diff:
            resp["diff"] = diff

            if commit:
                self.commit(comment=comment)
            else:
                self.discard_changes()

        else:
            self.send_command("top")
            self.discard_changes()

        resp["request"] = requests
        resp["response"] = results
        return resp
Пример #29
0
    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.neighbors"):
            context_commands = list()

            neighbor = item["neighbor"]

            try:
                socket.inet_aton(neighbor)
                context = "neighbor %s" % neighbor
            except socket.error:
                context = "neighbor-group %s" % neighbor

            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 and safe_list:
            commands.extend(self._negate_config(config, safe_list))

        return commands
Пример #30
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:
                if int(w['vlan_id']) == 1:
                    self._module.fail_json(msg="Vlan 1 is not allowed to be managed by this module")
                want.append(remove_empties(w))
        have = existing_vlans_facts
        resp = self.set_state(want, have)
        return to_list(resp)