Beispiel #1
0
    def commit_config(self):
        """
        Commit candidate_config to the device.

        :return: None
        :raises: EXOSException, ValueError, NetMikoTimeoutException
        """

        if self.candidate_config is None:
            msg = "Candidate config not loaded"
            self.log.error(msg)
            raise EXOSException(msg)

        try:
            # make a backup of the running_config
            self.get_running_config()
            # send candidate_config
            commands = list(set(self.candidate_config))
            commands.append('save')
            for command in commands:
                output = self.device.send_command_timing(command)
                if 'Invalid input detected' in output:
                    msg = "Error while sending the '{0}' command: \n{1}".format(
                        command, output)
                    self.log.error(msg)
                    raise EXOSException(msg)
            self.candidate_config = None
        except (EXOSException, ValueError, NetMikoTimeoutException):
            self.log.error('error', exc_info=True)
            raise
        self.log.info("commit merge done")
Beispiel #2
0
    def commit_config(self):
        """
        Commit candidate_config to the device.

        :return: None
        :raises: EXOSException, ValueError, NetMikoTimeoutException
        """

        # load file in the future
        # save configuration as-script backup
        # load script configuration candidate

        if self.candidate_config is None:
            raise EXOSException("Candidate config not loaded")

        try:
            # make a backup of the running_config
            self.get_running_config()
            # send candidate_config
            commands = list(set(self.candidate_config))
            commands.append('save')
            for command in commands:
                output = self.device.send_command_timing(command)
                if 'Invalid input detected' in output:
                    raise EXOSException(
                        "Error while sending the '{0}' command:"
                        "\n{1}".format(command, output))
            self.candidate_config = None
        except (EXOSException, ValueError, NetMikoTimeoutException):
            raise
Beispiel #3
0
    def load_candidate_config(self, filename=None, config=None):
        """
        Populate candidate_config from str or file as a list of commands.

        :param filename:  Path to the file containing the desired
                          configuration. Default: None.
        :param config:    String containing the desired configuration.
                          Default: None.

        :return: None
        :raises: EXOSException
        """

        if filename is None and config is None:
            msg = "at least one of the following attributes has to be \
                  provided: 'filename' or 'config'"

            self.log.error(msg)
            raise EXOSException(msg)

        self.candidate_config = ''

        if filename is not None:
            with open(filename) as file:
                self.candidate_config = file.read().splitlines()
        else:
            self.candidate_config = config.splitlines()

        self.candidate_config = [
            line.strip() for line in self.candidate_config
        ]
        self.log.info("candidate_config loaded")
Beispiel #4
0
    def rollback(self):
        """
        Rollback the last committed configuration.

        :return: None
        :raises: EXOSException, ValueError, NetMikoTimeoutException
        """
        if self.running_config is None:
            msg = "No previous running_config to roll back to present"
            self.log.error(msg)
            raise EXOSException(msg)

        try:
            # load the previous running_config to get back to the previous state
            self.candidate_config = self.running_config

            # remove all comments and empty lines
            self.candidate_config = [
                x for x in self.candidate_config if not x.startswith('#')
            ]
            self.candidate_config = [
                x for x in self.candidate_config if not x == ''
            ]

            # commit_replace the config
            self.commit_replace_config()
        except (EXOSException, ValueError, NetMikoTimeoutException):
            self.log.error('error', exc_info=True)
            raise
Beispiel #5
0
    def compare_replace_config(self):
        """
        Generate replace diff to be used to build delete commands

        :return: config diff
        :raises: EXOSException
        """
        if self.candidate_config is None:
            msg = "Candidate config not loaded"
            self.log.error(msg)
            raise EXOSException(msg)

        self.log.info("comparing config for commit replace")

        # make sure we have the running_config
        self.get_running_config()

        replace_diff = difflib.unified_diff(self.running_config,
                                            self.candidate_config,
                                            fromfile='running_config.conf',
                                            tofile='candidate_config.conf',
                                            lineterm='')
        self.log.info("diff aquired")
        replace_diff = '\n'.join(replace_diff)
        return replace_diff
Beispiel #6
0
    def compare_merge_config(self):
        """
        Compare configuration to be merged, with the one on the device.

        Compare executed candidate config with the running config and
        return a diff, assuming the loaded config will be merged with the
        existing one.

        :return: config diff
        :raises: EXOSException
        """
        if self.candidate_config is None:
            msg = "Candidate config not loaded"
            self.log.error(msg)
            raise EXOSException(msg)

        self.log.info("comparing config for commit merge")

        # make sure we have the running_config
        self.get_running_config()

        old_conf = list(set(self.running_config))
        new_conf = self.running_config + self.candidate_config
        new_conf = list(set(new_conf))

        diff = difflib.unified_diff(old_conf,
                                    new_conf,
                                    fromfile='running_config.conf',
                                    tofile='candidate_config.conf',
                                    n=0,
                                    lineterm='')
        self.log.info("diff aquired")
        return '\n'.join(list(diff))
Beispiel #7
0
    def load_candidate_config(self, filename=None, config=None):
        """
        Populate candidate_config from str or file as a list of commands.

        :param filename:  Path to the file containing the desired
                          configuration. Default: None.
        :param config:    String containing the desired configuration.
                          Default: None.

        :return: None
        :raises: EXOSException
        """

        # scp to device in the future candidate.xsf

        if filename is None and config is None:
            raise EXOSException(
                "at least one of the following attributes has to be \
                provided: 'filename' or 'confg'")

        self.candidate_config = ''

        if filename is not None:
            with open(filename) as file:
                self.candidate_config = file.read().splitlines()
        else:
            self.candidate_config = config.splitlines()
Beispiel #8
0
 def test_pyexos_commit_replace_config_exception(self, mock_con):
     """ testing pyEXOS load_replace_candidate_config EXOSException """
     with mock.patch.object(EXOS, 'commit_config') as mock_commit:
         mock_commit.side_effect = EXOSException('error')
         self.device.open()
         config = 'config'
         self.device.load_candidate_config(config=config)
         self.assertRaises(EXOSException, self.device.commit_replace_config)
Beispiel #9
0
    def commit_replace_config(self):
        """
        Commit candidate_config to the device, by replaceing the previous
        running configuration.

        :return: None
        :raises: EXOSException, ValueError, NetMikoTimeoutException
        """
        if self.candidate_config is None:
            raise EXOSException("Candidate config not loaded")

        try:
            # fetch running_config to generate delete commands for it
            self.get_running_config()

            # generate delta commands
            self.candidate_config = self._generate_commands()

            # commit new candidate_config
            self.commit_config()
        except (EXOSException, ValueError, NetMikoTimeoutException):
            raise
Beispiel #10
0
    def compare_replace_config(self):
        """
        Generate replace diff to be used to build delete commands

        :return: config diff
        :raises: EXOSException
        """
        if self.candidate_config is None:
            raise EXOSException("Candidate config not loaded")

        # make sure we have the running_config
        self.get_running_config()

        replace_diff = difflib.unified_diff(
            [x.strip() for x in self.running_config],
            [x.strip() for x in self.candidate_config],
            fromfile='running_config.conf',
            tofile='candidate_config.conf',
            lineterm='')

        replace_diff = '\n'.join(replace_diff)
        return replace_diff
Beispiel #11
0
    def commit_replace_config(self):
        """
        Commit candidate_config to the device, by replacing the previous
        running configuration.

        :return: None
        :raises: EXOSException, ValueError, NetMikoTimeoutException
        """
        if self.candidate_config is None:
            msg = "Candidate config not loaded"
            self.log.error(msg)
            raise EXOSException(msg)

        try:
            # fetch running_config to generate delete commands for it
            self.get_running_config()
            # generate delta commands
            self.candidate_config = self._generate_commands()
            # commit new candidate_config
            self.commit_config()
        except (EXOSException, ValueError, NetMikoTimeoutException):
            self.log.error('error', exc_info=True)
            raise
        self.log.info("commit replace done")