Beispiel #1
0
    def call_service(self, command='redundancy switchover',
                     dialog=Dialog([]),
                     timeout=None,
                     sync_standby=True,
                     error_pattern=None,
                     *args,
                     **kwargs):
        # create an alias for connection.
        con = self.connection

        if error_pattern is None:
            self.error_pattern = con.settings.ERROR_PATTERN
        else:
            self.error_pattern = error_pattern

        start_time = datetime.now()
        timeout = timeout or self.timeout

        con.log.debug("+++ Issuing switchover on  %s  with "
                      "switchover_command %s and timeout is %s +++"
                      % (con.hostname, command, timeout))

        dialog += self.dialog

        # Issue switchover command
        con.active.spawn.sendline(command)
        try:
            self.result = dialog.process(con.active.spawn,
                           timeout=self.timeout,
                           prompt_recovery=self.prompt_recovery,
                           context=con.context)
        except SubCommandFailure as err:
            raise SubCommandFailure("Switchover Failed %s" % str(err))

        output = ""
        if self.result:
            self.result = self.get_service_result()
            output += self.result.match_output

        con.log.info('Switchover done, switching sessions')
        con.active.spawn.sendline()
        con.standby.spawn.sendline()
        con.connection_provider.prompt_recovery = True
        con.connection_provider.connect()
        con.connection_provider.prompt_recovery = False

        if sync_standby:
            con.log.info('Waiting for standby state')

            delta_time = timedelta(seconds=timeout)
            current_time = datetime.now()
            while (current_time - start_time) < delta_time:
                show_redundancy = con.execute('show redundancy', prompt_recovery=True)
                standby_state = re.findall(con.settings.STANDBY_STATE_REGEX, show_redundancy)
                standby_state = [s.strip() for s in standby_state]
                con.log.info('Standy state: %s' % standby_state)
                if standby_state == con.settings.STANDBY_EXPECTED_STATE:
                    break
                wait_time = con.settings.STANDBY_STATE_INTERVAL
                con.log.info('Waiting %s seconds' % wait_time)
                sleep(wait_time)
                current_time = datetime.now()

            if current_time - start_time > delta_time:
                raise SubCommandFailure('Switchover timed out, standby state: %s' % standby_state)

        # TODO: return all/most console output, not only from the switchover
        # This requires work on the bases.router.connection_provider BaseDualRpConnectionProvider implementation
        self.result = output
Beispiel #2
0
class WebserverDialog:
    ssh_connect_dialog = Dialog([
        ['continue connecting (yes/no)?', 'sendline(yes)', None, True, False],
        ['Password:'******'sendline_ctx(password)', None, True, False],
        ['Last login:', None, None, True, False],
    ])
def configure_crypto_pki_server(
    device,
    domain_name,
    database_level,
    issuer_name,
    hash,
    modulus_size,
    password,
    server_name,
):
    """Configures crypto pki server on device

    Args:
        device (`obj`): Device object
        domain_name ('str'): Name of the domain to be configured
        database_level ('str'): Database level to be configured
        issuer_name ('str'): Issuer name to be configured
        hash ('str'): Hash to be configured
        modulus_size ('str'): Modulus size to be configured
        Password ('str'): Password to be configured
        server_name ('str'): Name of the server to be configured

    Returns:
        None

    Raise:
        SubCommandFailure: Failed to configure crypto pki server on device
    """
    def send_password(spawn, password):
        spawn.sendline(password)

    dialog_1 = Dialog([
        Statement(
            r"^.*Destination filename \[nvram\.pub\]\?.*$",
            action="sendline(\r)",
            loop_continue=True,
        ),
        Statement(
            r"^.*Do you really want to overwrite it\? \[yes/no\]:.*$",
            action="sendline(yes)",
            loop_continue=True,
        ),
        Statement(
            r"^.*Destination filename \[nvram\.prv\]\?.*$",
            action="sendline(\r)",
            loop_continue=True,
        ),
        Statement(
            r"^.*Do you really want to overwrite it\? \[yes/no\]:.*$",
            action="sendline(yes)",
            loop_continue=True,
        ),
    ])
    try:
        device.configure([
            f"ip domain-name {domain_name}",
            f"crypto pki server {server_name}",
            f"database level {database_level}",
            f"issuer-name {issuer_name}",
            f"hash {hash}",
            "shut",
            "exit",
        ])

        time.sleep(10)

        device.configure([
            f"crypto key generate  rsa modulus {modulus_size} label  cisco exportable",
            f"crypto key export rsa cisco pem url nvram 3des {password}",
        ],
                         timeout=5,
                         reply=dialog_1)

        time.sleep(20)

        dialog_2 = Dialog([
            Statement(
                r"Password:\s?$",
                action=send_password,
                args={"password": password},
                loop_continue=True,
            ),
            Statement(
                r"Re-enter password:\s?$",
                action=send_password,
                args={"password": password},
                loop_continue=True,
            ),
        ])

        device.configure([
            f"crypto pki server {server_name}",
            "no shut",
        ],
                         timeout=120,
                         reply=dialog_2)

        time.sleep(120)

    except SubCommandFailure:
        raise SubCommandFailure(
            "Could not configure crypto pki server on device")
    def call_service(self, to_state,
                     timeout=None,
                     *args, **kwargs):

        if not self.connection.connected:
            return

        con = self.connection
        sm = self.get_sm()

        dialog = Dialog([fxos_statements.command_not_completed_stmt])

        timeout = timeout if timeout is not None else self.timeout

        if isinstance(to_state, str):
            to_state_list = [to_state]
        elif isinstance(to_state, list):
            to_state_list = to_state
        else:
            raise Exception('Invalid switchto to_state type: %s' % repr(to_state))

        for to_state in to_state_list:
            m1 = re.match(r'module(\s+(\d+))?(\s+(console|telnet))?', to_state)
            m2 = re.match(r'cimc(\s+(\S+))?', to_state)
            m3 = re.match(r'fxos[ _]scope ?(.*)', to_state)
            m4 = re.match(r'adapter(\s+(\S+))?', to_state)
            if m1:
                mod = m1.group(2) or 1
                con_type = m1.group(4) or 'console'
                self.context._module = mod
                self.context._mod_con_type = con_type
                to_state = 'module'
            elif m2:
                mod = m2.group(2) or '1/1'
                self.context._cimc_module = mod
                to_state = 'cimc'
                con.state_machine.go_to('fxos', con.spawn,
                                        context=self.context,
                                        hop_wise=True,
                                        timeout=timeout)
            elif m3:
                scope = m3.group(1)
                if not scope:
                    con.log.warning('No scope specified, ignoring switchto')
                    continue
                else:
                    self.context._scope = scope
                    to_state = 'fxos_scope'
                    con.state_machine.go_to('fxos', con.spawn,
                                            context=self.context,
                                            hop_wise=True,
                                            timeout=timeout)
            elif m4:
                mod = m4.group(2) or '1/1'
                self.context._adapter_module = mod
                to_state = 'adapter'
            else:
                to_state = to_state.replace(' ', '_')

            valid_states = [x.name for x in sm.states]
            if to_state not in valid_states:
                con.log.warning(
                    '%s is not a valid state, ignoring switchto' % to_state)
                continue

            con.state_machine.go_to(to_state,
                                    con.spawn,
                                    context=self.context,
                                    hop_wise=True,
                                    timeout=timeout,
                                    dialog=dialog)

        self.end_state = sm.current_state
Beispiel #5
0
    def call_service(self,
                     reload_command='system reboot',
                     dialog=Dialog([]),
                     timeout=None,
                     *args,
                     **kwargs):
        con = self.connection
        timeout = timeout or self.timeout

        fmt_msg = "+++ reloading %s " \
                  " with reload_command '%s' " \
                  "and timeout %s +++"
        con.log.info(fmt_msg %
                     (self.connection.hostname, reload_command, timeout))

        if not isinstance(dialog, Dialog):
            raise SubCommandFailure(
                "dialog passed must be an instance of Dialog")

        if self.context.get('console'):
            dialog = self.service_dialog(service_dialog=dialog)
            dialog += Dialog(authentication_statement_list)
            dialog += Dialog(reload_continue_statement_list)
            con.spawn.sendline(reload_command)
            try:
                self.result = dialog.process(
                    con.spawn,
                    timeout=timeout,
                    prompt_recovery=self.prompt_recovery,
                    context=self.context)
            except Exception as err:
                raise SubCommandFailure("Reload failed %s" % err)

            if self.result:
                self.result = utils.remove_ansi_escape_codes(
                    self.result.match_output)
        else:
            con.log.warning(
                'Did not detect a console session, will try to reconnect...')
            dialog = Dialog(reload_statement_list)
            con.spawn.sendline(reload_command)
            dialog.process(con.spawn,
                           timeout=timeout,
                           prompt_recovery=self.prompt_recovery,
                           context=self.context)
            con.expect('.+')
            con.log.warning('Disconnecting...')
            con.disconnect()
            for x in range(3):
                con.log.warning('Waiting for {} seconds'.format(
                    con.settings.RELOAD_WAIT))
                sleep(con.settings.RELOAD_WAIT)
                con.log.warning('Trying to connect... attempt #{}'.format(x +
                                                                          1))
                try:
                    output = con.connect()
                    self.result = output
                except:
                    con.log.warning('Connection failed')
                if con.connected:
                    break

            if not con.connected:
                raise SubCommandFailure('Reload failed - could not reconnect')
 def call_service(self, reply=Dialog([]), vrf=None, *args, **kwargs):
     if vrf is not None:
         kwargs['extra_options'] = kwargs.setdefault('extra_options', '') \
                                   + ' vrf {}'.format(vrf)
     super().call_service(reply=reply, *args, **kwargs)
 def get_connection_dialog(self):
     dialog = super().get_connection_dialog()
     dialog += Dialog(additional_connection_dialog)
     return dialog
Beispiel #8
0
    def call_service(self,
                     reload_command=None,
                     reply=Dialog([]),
                     timeout=None,
                     image_to_boot=None,
                     return_output=False,
                     *args,
                     **kwargs):

        self.result = False
        reload_cmd = reload_command or self.reload_command
        timeout = timeout or self.timeout
        conn = self.connection.active

        # update all subconnection context with image_to_boot
        if image_to_boot:
            for subconn in self.connection:
                subconn.context.image_to_boot = image_to_boot

        reload_dialog = self.dialog
        if reply:
            reload_dialog = reply + reload_dialog

        custom_auth_stmt = custom_auth_statements(
            conn.settings.LOGIN_PROMPT, conn.settings.PASSWORD_PROMPT)
        if custom_auth_stmt:
            reload_dialog += Dialog(custom_auth_stmt)

        reload_dialog += Dialog([switch_prompt])

        conn.log.info('Processing on active rp %s-%s' %
                      (conn.hostname, conn.alias))
        conn.sendline(reload_cmd)
        try:
            reload_cmd_output = reload_dialog.process(
                conn.spawn,
                timeout=timeout,
                prompt_recovery=self.prompt_recovery,
                context=conn.context)
        except Exception as e:
            raise SubCommandFailure('Error during reload', e) from e

        if 'state' in conn.context and conn.context.state == 'rommon':
            # If manual boot enabled wait for all peers to come to boot state.
            sleep(self.connection.settings.STACK_ROMMON_SLEEP)

            conn.context.pop('state')
            try:
                # send boot command for each subconnection
                for subconn in self.connection.subconnections:
                    utils.send_boot_cmd(subconn, timeout, self.prompt_recovery,
                                        reply)

                # process boot up for each subconnection
                for subconn in self.connection.subconnections:
                    self.connection.log.info('Processing on rp '
                                             '%s-%s' %
                                             (conn.hostname, subconn.alias))
                    utils.boot_process(subconn, timeout, self.prompt_recovery,
                                       reload_dialog)

            except Exception as e:
                self.connection.log.error(e)
                raise SubCommandFailure('Reload failed.', e) from e
        else:
            try:
                # bring device to enable mode
                conn.state_machine.go_to('any',
                                         conn.spawn,
                                         timeout=timeout,
                                         prompt_recovery=self.prompt_recovery,
                                         context=conn.context)
                conn.state_machine.go_to('enable',
                                         conn.spawn,
                                         timeout=timeout,
                                         prompt_recovery=self.prompt_recovery,
                                         context=conn.context)
            except Exception as e:
                raise SubCommandFailure(
                    'Failed to bring device to disable mode.', e) from e

        # check active and standby rp is ready
        self.connection.log.info('Wait for Standby RP to be ready.')

        interval = self.connection.settings.RELOAD_POSTCHECK_INTERVAL
        if utils.is_active_standby_ready(conn,
                                         timeout=timeout,
                                         interval=interval):
            self.connection.log.info('Active and Standby RPs are ready.')
        else:
            self.connection.log.info(
                'Timeout in %s secs. '
                'Standby RP is not in Ready state. Reload failed' % timeout)
            self.result = False
            return

        self.connection.log.info('Sleeping for %s secs.' % \
                self.connection.settings.STACK_POST_RELOAD_SLEEP)
        sleep(self.connection.settings.STACK_POST_RELOAD_SLEEP)

        self.connection.log.info('Disconnecting and reconnecting')
        self.connection.disconnect()
        self.connection.connect()

        self.connection.log.info("+++ Reload Completed Successfully +++")
        self.result = True

        if return_output:
            Result = namedtuple('Result', ['result', 'output'])
            self.result = Result(
                self.result,
                reload_cmd_output.match_output.replace(reload_cmd, '', 1))
Beispiel #9
0
    def call_service(self,
                     command=None,
                     reply=Dialog([]),
                     timeout=None,
                     *args,
                     **kwargs):

        switchover_cmd = command or self.command
        timeout = timeout or self.timeout
        conn = self.connection.active

        expected_active_sw = self.connection.standby.member_id
        dialog = self.dialog

        if reply:
            dialog = reply + self.dialog

        # added connection dialog in case switchover ask for username/password
        connect_dialog = self.connection.connection_provider.get_connection_dialog(
        )
        dialog += connect_dialog

        conn.log.info('Processing on active rp %s-%s' %
                      (conn.hostname, conn.alias))
        conn.sendline(switchover_cmd)
        try:
            match_object = dialog.process(conn.spawn,
                                          timeout=timeout,
                                          prompt_recovery=self.prompt_recovery,
                                          context=conn.context)
        except Exception as e:
            raise SubCommandFailure('Error during switchover ', e) from e

        # try boot up original active rp with current active system
        # image, if it moved to rommon state.
        if 'state' in conn.context and conn.context.state == 'rommon':
            try:
                conn.state_machine.detect_state(conn.spawn,
                                                context=conn.context)
                conn.state_machine.go_to('enable',
                                         conn.spawn,
                                         timeout=timeout,
                                         prompt_recovery=self.prompt_recovery,
                                         context=conn.context,
                                         dialog=Dialog([switch_prompt]))
            except Exception as e:
                self.connection.log.warning(
                    'Fail to bring up original active rp from rommon state.',
                    e)
            finally:
                conn.context.pop('state')

        # To ensure the stack is ready to accept the login
        self.connection.log.info('Sleeping for %s secs.' % \
                                 self.connection.settings.POST_SWITCHOVER_SLEEP)
        sleep(self.connection.settings.POST_SWITCHOVER_SLEEP)

        # check all members are ready
        conn.state_machine.detect_state(conn.spawn, context=conn.context)

        interval = self.connection.settings.SWITCHOVER_POSTCHECK_INTERVAL
        if utils.is_all_member_ready(conn, timeout=timeout, interval=interval):
            self.connection.log.info('All members are ready.')
        else:
            self.connection.log.info('Timeout in %s secs. '
                                     'Not all members are in Ready state.' %
                                     timeout)
            self.result = False
            return

        self.connection.log.info('Disconnecting and reconnecting')
        self.connection.disconnect()
        self.connection.connect()

        self.connection.log.info('Verifying active and standby switch State.')
        if self.connection.active.member_id == expected_active_sw:
            self.connection.log.info('Switchover successful')
            self.result = True
        else:
            self.connection.log.info('Switchover failed')
            self.result = False
Beispiel #10
0
 def __init__(self, connection, context, **kwargs):
     super().__init__(connection, context, **kwargs)
     self.start_state = 'enable'
     self.end_state = 'enable'
     self.dialog += Dialog([slxos_statements.save_confirm])
Beispiel #11
0
def install_image_and_packages(section, steps, device, image, packages,
                           install_timeout=300, reload_timeout=900):
    """ This stage installs the provided image and optional packages onto
    your device using the install CLI. The stage will also handle the
    automatic reload.

    Stage Schema
    ------------
    install_image_and_packages:
        image:
            - <image to install> (Mandatory)
        packages:
            - <package to install> (Optional)
            - <package to install> (Optional)
        install_timeout: <timeout used for install operations, 'int', Default 300> (Optional)
        reload_timeout: <timeout used for device reloads, 'int', Default 900> (Optional)


    Example
    -------
    install_image_and_packages:
        image:
            - flash:image.iso
        packages:
            - flash:package.rpm

    """

    # Commonly used patterns
    error_patterns = [
        r".*Could not start this install operation.*",
        r".*Install operation \d+ aborted.*"]

    successful_operation_string = \
        r".*Install operation (?P<id>\d+) finished successfully.*"

    if ':' not in image[0]:
        section.failed("The image provided is not in the format '<dir>:<image>'.")

    with steps.start("Running install commit to clear any in progress "
                     "installs") as step:

        try:
            device.execute("install commit")
            device.expect(
                [successful_operation_string],
                timeout=install_timeout)
        except Exception as e:
            step.failed("The command 'install commit' failed. Reason: "
                        "{}".format(str(e)))

    with steps.start("Adding image and any provided packages to the "
                     "install repository") as step:

        # Separate directory and image
        directory, image = image[0].replace('/', '').split(':')

        # Get packages and remove directories
        # pkgs = ' pkg1 pkg2 pkg3 ...'
        pkgs = ''
        for pkg in packages:
            pkg = pkg.replace('/', '').split(':')
            if len(pkg) == 1:
                pkgs += ' '+pkg[0]
            else:
                pkgs += ' '+pkg[1]

        # install add source flash: <image> <pkg1> <pkg2>
        cmd = 'install add source {dir}: {image}{packages}'.format(
            dir=directory, image=image, packages=pkgs)

        try:
            device.execute(
                cmd,
                timeout=install_timeout,
                error_pattern=error_patterns)

            out = device.expect(
                [successful_operation_string],
                trim_buffer=False,
                timeout=install_timeout)
        except Exception as e:
            step.failed("The command '{cmd}' failed. Error: {e}"
                        .format(cmd=cmd, e=str(e)))

        out = out.match_output

        # If code execution reaches here the regex has already been matched
        # via the expect. So we know it will match again here. We just need
        # to retrieve the operation id for the next steps.
        p1 = re.compile(successful_operation_string)
        for line in out.splitlines():
            m = p1.match(line)
            if m:
                operation_id = m.groupdict()['id']
                break

        step.passed("The command '{cmd}' succeeded. The "
                    "operation ID is '{operation_id}'"
                    .format(cmd=cmd, operation_id=operation_id))

    with steps.start("Activating operation ID {}".format(operation_id)) as step:

        cmd = 'install activate id {id}'.format(id=operation_id)

        install_activate_dialog = Dialog([
            Statement(pattern='.*This install operation will reload the '
                              'system\, continue\?.*\[yes\:no\]\:\[yes\].*',
                      action='sendline(yes)',
                      loop_continue=False,
                      continue_timer=False)])

        try:
            # send the install cmd
            device.sendline(cmd)

            # Process the dialog that appears
            install_activate_dialog.process(
                device.spawn, timeout=install_timeout)

            # Wait for successful output
            device.expect(
                [successful_operation_string],
                timeout=install_timeout)
        except Exception as e:
            step.failed("Attempting to activate install id '{id}' "
                        "failed. Error: {e}"
                        .format(id=operation_id, e=str(e)))

    with steps.start("Reconnecting to '{dev}'".format(
            dev=device.name)) as step:

        timeout = Timeout(reload_timeout, 60)
        while timeout.iterate():
            timeout.sleep()
            device.destroy()

            try:
                device.connect(learn_hostname=True)
            except Exception as e:
                connection_error = e
                log.info("Could not connect to {dev}"
                         .format(dev=device.hostname))
            else:
                step.passed("Connected to {dev}"
                            .format(dev=device.hostname))

        step.failed("Could not connect to {dev}. Error: {e}"
                    .format(dev=device.hostname, e=str(connection_error)))

    with steps.start("Completing install") as step:

        try:
            device.execute("install commit")

            device.expect(
                [successful_operation_string],
                trim_buffer=False,
                timeout=install_timeout)
        except Exception as e:
            step.failed("The command 'install commit' failed. Reason: {}".format(str(e)))
Beispiel #12
0
 def __init__(self, connection, context, **kwargs):
     super().__init__(connection, context, **kwargs)
     self.dialog += Dialog(execution_statement_list)
Beispiel #13
0
 def call_service(self, command=[], reply=Dialog([]), target='active',
                   timeout=None, *args, **kwargs):
     self.commit_cmd = get_commit_cmd(**kwargs)
     super().call_service(command,
                          reply=reply + Dialog(config_commit_stmt_list),
                          target=target, timeout=timeout, *args, **kwargs)
Beispiel #14
0
 def __init__(self, connection, context, **kwargs):
     # Connection object will have all the received details
     super().__init__(connection, context, **kwargs)
     self.dialog += Dialog(execution_statement_list)
        else:
            platform = None

        try:
            c = Connection(hostname='Router', start=['bash'], os=_os, platform=platform, log_stdout=False)
            # c = Connection(hostname='Router', start=['bash'], os=_os, platform=platform)
            c.init_service()
            c.connection_provider = c.connection_provider_class(c)

        except Exception:
            print('---------------- ERROR ---------------', file=sys.stderr)
            traceback.print_exc()
            print('--------------------------------------', file=sys.stderr)

        else:
            print('\n\n')
            print(plugin_name)
            print('-' * len(plugin_name) + '\n')

            print_dialogs('default', c.state_machine.default_dialog)

            print_dialogs('connect', c.connection_provider.get_connection_dialog())

            try:
                print_dialogs('execute', c.execute.dialog if c.execute.dialog else Dialog([]))
                print_dialogs('configure', c.configure.dialog if c.configure.dialog else Dialog([]))
            except Exception:
                print('---------------- ERROR ---------------', file=sys.stderr)
                traceback.print_exc()
                print('--------------------------------------', file=sys.stderr)
Beispiel #16
0
    def call_service(self,
                     reload_command='reload',
                     dialog=Dialog([]),
                     timeout=None,
                     reload_creds=None,
                     *args,
                     **kwargs):
        con = self.connection
        timeout = timeout or self.timeout

        fmt_msg = "+++ reloading  %s  " \
                  " with reload_command %s " \
                  "and timeout is %s +++"
        con.log.debug(fmt_msg %
                      (self.connection.hostname, reload_command, timeout))

        con.state_machine.go_to(self.start_state,
                                con.spawn,
                                prompt_recovery=self.prompt_recovery,
                                context=self.context)

        if not isinstance(dialog, Dialog):
            raise SubCommandFailure(
                "dialog passed must be an instance of Dialog")

        show_terminal = con.execute('show terminal')
        line_type = re.search(r"Line .*, Type \"(\w+)\"", show_terminal)
        if line_type and line_type.groups():
            line_type = line_type.group(1)

        if reload_creds:
            context = self.context.copy()
            context.update(cred_list=reload_creds)
        else:
            context = self.context

        if line_type == 'Console':
            dialog += self.dialog
            con.spawn.sendline(reload_command)
            try:
                self.result = dialog.process(
                    con.spawn,
                    timeout=timeout,
                    prompt_recovery=self.prompt_recovery,
                    context=context)
                if self.result:
                    self.result = self.result.match_output
                con.state_machine.go_to('any',
                                        con.spawn,
                                        prompt_recovery=self.prompt_recovery,
                                        context=self.context)
            except Exception as err:
                raise SubCommandFailure("Reload failed %s" % err)

            output = self.result
            output = output.replace(reload_command, "", 1)
            # only strip first newline and leave formatting intact
            output = re.sub(r"^\r?\r\n", "", output, 1)
            output = output.rstrip()
        else:
            con.log.warning(
                'Did not detect a console session, will try to reconnect...')
            dialog = Dialog(reload_statement_list_vty)
            con.spawn.sendline(reload_command)
            output = ""
            self.result = dialog.process(con.spawn,
                                         timeout=timeout,
                                         prompt_recovery=self.prompt_recovery,
                                         context=self.context)
            if self.result:
                output += self.result.match_output
            try:
                m = con.spawn.expect('.+', timeout=10)
                if m:
                    output += m.match_output
            except TimeoutError:
                pass
            con.log.warning('Disconnecting...')
            con.disconnect()
            for x in range(3):
                con.log.warning('Waiting for {} seconds'.format(
                    con.settings.RELOAD_WAIT))
                sleep(con.settings.RELOAD_WAIT)
                con.log.warning('Trying to connect... attempt #{}'.format(x +
                                                                          1))
                try:
                    output += con.connect()
                except:
                    con.log.warning('Connection failed')
                if con.is_connected:
                    break

            if not con.is_connected:
                raise SubCommandFailure('Reload failed - could not reconnect')

        self.result = output
 def __init__(self, connection, context, **kwargs):
     super().__init__(connection, context, **kwargs)
     self.dialog += Dialog(
         [overwrite_previous, delete_filename, confirm, want_continue])
def cb5(spawn, context, session, name, city='bangalore', country='america'):
    print('spawn=%s; context=%s, name=%s; city=%s; contry=%s;' % (spawn, context, name, city, country))
    print(session.check)
    session.num *= session.num
    print('number is %s' % session.num)

s_list = [
    Statement(pattern=pattern, action=cb1),
    Statement(pattern=pattern, action=cb2),
    Statement(pattern=pattern, action=cb3, args={'name': 'person1'}),
    Statement(pattern=pattern, action=cb4),
    Statement(pattern=pattern, action=cb5, args={'name': 'person1', 'country': 'country1'}),
    Statement(pattern=pattern, action=None)
]

d = Dialog(s_list)

context = AttributeDict(dict(username='******', password='******'))

dp1 = DialogProcessor(d, s1, context)

dp1.process(context)



print('-- After dp1')
for st in d.statements:
    if st._action is not None:
        st._action()
for st in d.statements:
    if st._action is not None:
Beispiel #19
0
def execute_install_package(device, image_dir, image, save_system_config=True,
                            timeout=660, _install=True):
    """ Installs package
        Args:
            device ("obj"): Device object
            image_dir ("str"): Directory image is located in
            image ("str"): Image name
            save_system_config ("bool"): If config changed do we save it?
            timeout ("int"): maximum time for install

            _install ("bool"): True to install, False to uninstall.
                Not meant to be changed manually.

        Raises:
            Exception

        Returns:
            True if install succeeded else False
    """
    dialog = Dialog([
        Statement(pattern=r".*Press Quit\(q\) to exit, you may save "
                          r"configuration and re-enter the command\. "
                          r"\[y\/n\/q\]",
                  action='sendline(y)' if save_system_config else 'sendline(n)',
                  loop_continue=True,
                  continue_timer=False),
        Statement(pattern=r".*This operation may require a reload of the "
                          r"system\. Do you want to proceed\? \[y\/n\]",
                  action='sendline(y)',
                  loop_continue=True,
                  continue_timer=False),
        Statement(pattern=r"^.*RETURN to get started",
                  action='sendline()',
                  loop_continue=False,
                  continue_timer=False)
    ])

    if _install:
        cmd = """install add file {dir}{image}
        install activate file {dir}{image}""".format(
            dir=image_dir, image=image
        )
    else:
        cmd = "install deactivate file {dir}{image}".format(
            dir=image_dir, image=image
        )

    try:
        device.execute(cmd, reply=dialog, timeout=timeout)
    except StateMachineError:
        # this will be raised after 'Return to get started' is seen
        device.destroy()
        timeout = Timeout(90, 30)
        while timeout.iterate():
            try:
                connect_device(device)
            except Exception:
                timeout.sleep()
                continue
            break
        else:
            raise Exception("Couldnt reconnect to the device")

    if _install:
        cmd = "install commit"
    else:
        cmd = """install commit
        install remove file {dir}{image}""".format(
            dir=image_dir, image=image
        )

    device.execute(cmd)

    try:
        out = device.parse("show install summary")
    except SchemaEmptyParserError:
        out = {}

    for location in out.get("location"):
        for pkg in out['location'][location]['pkg_state']:
            pkg = out['location'][location]['pkg_state'][pkg]
            if (_install and
                    image in pkg['filename_version'] and
                    'C' == pkg['state']):
                # the image should exist; it was just installed
                return True
            elif (not _install and
                    image in pkg['filename_version']):
                # the image should not exist; it was just uninstalled.
                return False

    return False if _install else True
Beispiel #20
0
    def restore_configuration(self,
                              device,
                              method,
                              abstract,
                              iteration=10,
                              interval=60,
                              compare=False,
                              compare_exclude=[],
                              reload_timeout=None,
                              delete_after_restore=True):
        if method == 'checkpoint':
            # Enable the feature
            for i in range(1, iteration):
                try:
                    self.rollback_checkpoint(device=device, name=self.ckname)
                    break
                except Exception as e:
                    if i == iteration - 1:
                        raise Exception('Unable to rollback config')
                    else:
                        log.info('Rollback configuration failed: sleeping {} '
                                 'seconds and retrying...'.format(interval))
                        time.sleep(interval)

            if delete_after_restore:
                # Delete the checkpoint
                self.create_delete_checkpoint(device=device,
                                              name=self.ckname,
                                              abstract=abstract,
                                              action='delete')

                # Check if checkpoint is successfully deleted
                self.check_checkpoint_status(device=device,
                                             name=self.ckname,
                                             expect='delete',
                                             abstract=abstract)
        elif method == 'local':
            # reover the deivce with whole running-config
            device.configure(self.run_config)
        elif method == 'config_replace':
            # delete the archive file
            dialog = Dialog([
                Statement(pattern=r'This will apply all necessary.*',
                          action='sendline(Y)',
                          loop_continue=True,
                          continue_timer=False),
                Statement(pattern=r'less than running config.*',
                          action='sendline(Y)',
                          loop_continue=True,
                          continue_timer=False),
            ])

            for i in range(1, iteration):
                # configure replace location:<filename>
                output = device.execute('configure replace {}'.format(
                    self.to_url),
                                        reply=dialog)
                if 'Rollback Done' in output:
                    break
                elif i == iteration - 1:
                    raise Exception('Unable to execute config replace')
                else:
                    log.info(
                        'Config replace failed: sleeping {} seconds before'
                        ' retrying.'.format(interval))
                    time.sleep(interval)

            # Compare restored configuration to details in file
            if compare:
                log.info(
                    "Comparing current running-config with config-replace file"
                )

                # Default
                exclude = [
                    'device', 'maker', 'diff_ignore', 'callables',
                    '(Current configuration.*)',
                    '(.*Building configuration.*)', '(.*Load for.*)',
                    '(.*Time source.*)'
                ]
                if compare_exclude:
                    if isinstance(compare_exclude, str):
                        exclude.extend([compare_exclude])
                    else:
                        exclude.extend(compare_exclude)

                # show run
                show_run_output = device.execute('show running-config')
                show_run_config = Config(show_run_output)
                show_run_config.tree()

                # location:<filename> contents
                more_file = device.execute('more {}'.format(self.to_url))
                more_file_config = Config(more_file)
                more_file_config.tree()

                # Diff 'show run' and config replace file contents
                diff = Diff(show_run_config.config,
                            more_file_config.config,
                            exclude=exclude)
                diff.findDiff()

                # Check for differences
                if len(diff.diffs):
                    log.error(
                        "Differences observed betweenrunning-config and "
                        "config-replce file:'{f}' for device {d}:".format(
                            f=self.to_url, d=device.name))
                    log.error(str(diff.diffs))
                    raise Exception(
                        "Comparison between running-config and "
                        "config-replace file '{f}' failed for device"
                        " {d}".format(f=self.to_url, d=device.name))
                else:
                    log.info(
                        "Comparison between running-config and config-replace"
                        "file '{f}' passed for device {d}".format(
                            f=self.to_url, d=device.name))

            if delete_after_restore:
                # Delete location:<filename>
                self.filetransfer = FileUtils.from_device(device)
                self.filename = self.to_url
                self.filetransfer.deletefile(target=self.to_url, device=device)

                # Verify location:<filename> deleted
                dir_output = self.filetransfer.dir(target=self.to_url,
                                                   device=device)
                for file in dir_output:
                    if self.filename in file:
                        break
                else:
                    log.info("Successfully deleted '{}'".format(self.to_url))
                    return
                raise Exception("Unable to delete '{}'".format(self.to_url))
        else:
            # modify the device via callable function
            # using Conf object
            self.modify_func(device=device,
                             conf=self.conf,
                             values_dict=self.conf_argument,
                             recover=True,
                             **self.specific_args)
    def call_service(self, reload_command='reboot', reply=Dialog([]), timeout=None, *args, **kwargs):  # noqa C901
        # Clear log buffer
        self.log_buffer.seek(0)
        self.log_buffer.truncate()

        con = self.connection
        timeout = timeout or self.timeout
        con.log.debug("+++ reloading  %s  with reload_command %s "
                      "and timeout is %s +++" % (self.connection.hostname, reload_command, timeout))

        console = con.context.get('console', False)

        if console:
            dialog = reply + self.dialog
            con.spawn.sendline(reload_command)
            try:
                con.log.info('Rebooting system..')
                # reload and wait until 'Restarting system' is seen
                self.result = dialog.process(con.spawn,
                                             timeout=timeout,
                                             prompt_recovery=self.prompt_recovery,
                                             context=self.context)

                con.log.info('Waiting for boot to finish..')
                # Wait until boot is done
                boot_wait(con.spawn, timeout=timeout or self.timeout)

                con.log.info('Reload done, waiting %s seconds' % con.settings.POST_RELOAD_WAIT)
                time.sleep(con.settings.POST_RELOAD_WAIT)

                dialog = Dialog(login_statements + [Statement(fxos_patterns.fxos_prompt)])

                con.log.info('Trying to login..')
                # try to login
                con.spawn.sendline()
                self.result = dialog.process(con.spawn,
                                             timeout=timeout or self.timeout,
                                             prompt_recovery=self.prompt_recovery,
                                             context=self.context)

                con.state_machine.detect_state(con.spawn)
            except Exception as err:
                raise SubCommandFailure("Reload failed %s" % err)
        else:
            con.log.debug('Did not detect a console session, will try to reconnect...')
            dialog = reply + self.dialog
            con.spawn.sendline(reload_command)
            self.result = dialog.process(con.spawn,
                                         timeout=timeout or self.timeout,
                                         prompt_recovery=self.prompt_recovery,
                                         context=self.context)
            try:
                con.spawn.expect('.+', timeout=10, log_timeout=False)
            except TimeoutError:
                pass
            con.log.info('Disconnecting...')
            con.disconnect()
            for x in range(con.settings.RELOAD_RECONNECT_ATTEMPTS):
                con.log.info('Waiting for {} seconds'.format(con.settings.RELOAD_WAIT))
                time.sleep(con.settings.RELOAD_WAIT)
                con.log.info('Trying to connect... attempt #{}'.format(x + 1))
                try:
                    con.connect()
                except Exception:
                    con.log.warning('Connection failed')
                if con.is_connected:
                    break

            if not con.is_connected:
                raise SubCommandFailure('Reload failed - could not reconnect')

        self.log_buffer.seek(0)
        self.result = self.log_buffer.read()
Beispiel #22
0
    def create_delete_checkpoint(self, device, name, abstract, action):
        '''
            Create or Delete checkpoint

            Args:

                device (`obj`): Device Object.
                name (`str`): Checkpoint name.
                action (`str`): Create or Delete the checkpoint
                                Only accept 'create' and 'delete'
            Returns:

                None

            Raises:

                SyntaxError, AssertionError

            example:

                >>> create_delete_checkpoint(device=device,
                        name='bgp-001', action='create')
        '''

        assert action in ['create', 'delete']

        log.info('{a} checkpoint {n}'.format(a=action, n=name))
        if action == 'create':
            # create checkpoint
            try:
                # get dir location
                dir_loc = abstract.parser.show_platform.Dir(
                    device=device).parse()
                dir_loc = dir_loc['dir']['dir'].replace(':/', '')
                # activate archive mode
                cfg_strs = [
                    "archive", "path {dir}:{name}".format(dir=dir_loc,
                                                          name=name),
                    "do-exec archive config"
                ]
                ret = device.configure(cfg_strs)
            except Exception as e:
                raise SyntaxError(
                    "Issue sending {c}".format(c=cfg_strs)) from e
            else:
                if 'ERROR' in ret:
                    raise SyntaxError("Issue sending {c}".format(c=cfg_strs))
        else:
            try:
                # get location
                location = re.search(r'(([\w\-]+)\:+).*',
                                     self.ckname).groups()[0]

                # delete the archive file
                dialog = Dialog([
                    Statement(pattern=r'Delete filename.*',
                              action='sendline()',
                              loop_continue=True,
                              continue_timer=False),
                    Statement(pattern=r'Do you want to delete.*',
                              action='sendline(y)',
                              loop_continue=True,
                              continue_timer=False),
                    Statement(pattern=r'Delete {}.*'.format(location),
                              action='sendline()',
                              loop_continue=True,
                              continue_timer=False),
                    Statement(pattern=r'\[confirm\]',
                              action='sendline()',
                              loop_continue=True,
                              continue_timer=False),
                ])

                device.execute('delete {}'.format(self.ckname), reply=dialog)

                # deactivate archive mode
                cfg_strs = ['archive', 'no path', 'exit']
                ret = device.configure(cfg_strs)
            except Exception as e:
                raise SyntaxError(
                    "Issue sending {c}".format(c=cfg_strs)) from e
            else:
                if 'ERROR' in ret:
                    raise SyntaxError("Issue sending {c}".format(c=cfg_strs))
rtr_list = []
while True:
    hostname = input()
    if hostname:
        rtr_list.append(hostname)
    else:
        break

for rtr in rtr_list:
    nodes = rtr
    tb = load('Operation_List_Master.yaml')
    dev = tb.devices[nodes]
    d = Dialog([
        Statement(pattern=r'Permission denied',
                  action=None,
                  args=None,
                  loop_continue=True,
                  continue_timer=False)
    ])
    dev.connect(connect_reply=d)
    p0 = dev.admin_execute('show inventory')
    P0 = re.split('\r\n|NAME:|, DESCR:|PID:|, VID:|, SN:', p0)
    del P0[0]
    P1 = (list(filter(None, P0)))

    NAME = []
    DESCR = []
    SN = []
    PID = []
    VID = []
    def firepower_install(self):
        """Perform ping test and verify the network connectivity to TFTP server.
        Install FTD pkg image Enter device network info, hostname, and firewall
        mode.

        :return: None

        """

        for i in range(40):
            self.spawn_id.sendline('ping -c 1 {}'.format(self.rommon_tftp_server))
            try:
                self.spawn_id.expect('64 bytes from', timeout=5)
            except TimeoutError:
                time.sleep(60)
                continue
            else:
                break
        else:
            raise RuntimeError(">>>>>> Ping not working")

        d0 = Dialog([
            ['-boot>', 'sendline(system install {})'.format(self.pkg_image),
                None, False, False]
        ])

        d1 = Dialog([
            ['Do you want to continue?', 'sendline(y)', None, True, False],
            ['Upgrade aborted', 'sendline()', None, False, False],
            ['Installation aborted', 'sendline()', None, False, False]
        ])
        count = 0
        while count < self.retry_count:
            try:
                d0.process(self.spawn_id, timeout=20)
                d1.process(self.spawn_id, timeout=60)
                count += 1
                time.sleep(5)
            except:
                break
        assert count < self.retry_count, 'ftd installation failed' \
            ', please check ftd package url: "{}"'.format(self.pkg_image)

        d2 = Dialog([
            ['Do you want to continue with upgrade?', 'sendline(y)', None,
             True, True],
            ["Press 'Enter' to reboot the system.", 'sendline()', None, True,
             True],
            ['Use SPACE to begin boot immediately.', 'send(" ")', None, True,
             True],
            ['Use SPACE to launch Cisco FTD immediately.', 'send(" ")', None,
             True, True],
            ['firepower login: '******'sendline()', None, False, False],
        ])
        d2.process(self.spawn_id, timeout=3900)

        # Allow install processes to finish
        # Sleep was extended to 5 minutes as part of CSCvi89671
        # TODO: This sleep should be removed once CSCvi89616 is resolved
        time.sleep(300)

        d3 = Dialog([
            ['firepower login: '******'sendline(admin)', None, True, False],
            ['Password: '******'sendline({})'.format(self.sm.patterns.default_password),
             None, True, False],
            ['Press <ENTER> to display the EULA: ', 'sendline()', None, True, False],
            ['--More--', 'send(q)', None, True, False],
            ["Please enter 'YES' or press <ENTER> to AGREE to the EULA: ",
             'sendline(YES)', None, False, False],
        ])
        d3.process(self.spawn_id, timeout=600)

        d4 = Dialog([
            ['firepower login: '******'sendline(admin)', None, True, False],
            ['Password: '******'sendline({})'.format(self.sm.patterns.login_password),
             None, True, False],
            ['Enter new password:'******'sendline({})'.format(self.sm.patterns.login_password),
             None, True, True],
            ['Confirm new password:'******'sendline({})'.format(self.sm.patterns.login_password),
             None, True, False],
            ['Do you want to configure IPv4', 'sendline(y)', None, True, False],
        ])

        if self.uut_ip6 is None:
            d4.append(['Do you want to configure IPv6', 'sendline(n)', None, True, False])
        else:
            d4.append(['Do you want to configure IPv6', 'sendline(y)', None, True, False])
        d4.append(['Configure IPv4 via DHCP or manually', 'sendline(manual)', None,
                   True, False])
        d4.append(['Enter an IPv4 address for the management interface',
                   'sendline({})'.format(self.uut_ip), None, True, False])
        d4.append(['Enter an IPv4 netmask for the management interface',
                   'sendline({})'.format(self.uut_netmask), None, True, False])
        d4.append(['Enter the IPv4 default gateway for the management interface',
                   'sendline({})'.format(self.uut_gateway), None, True, False])
        if self.uut_ip6 is not None:
            d4.append(['Configure IPv6 via DHCP, router, or manually',
                       'sendline(manual)', None, True, False])
            d4.append(['Enter the IPv6 address for the management interface',
                       'sendline({})'.format(self.uut_ip6), None, True, False])
            d4.append(['Enter the IPv6 address prefix for the management interface',
                       'sendline({})'.format(self.uut_prefix), None, True, False])
            d4.append(['Enter the IPv6 gateway for the management interface',
                       'sendline({})'.format(self.uut_gateway6), None, True, False])
        d4.append(['Enter a fully qualified hostname for this system',
                   'sendline({})'.format(self.hostname), None, True, False])
        d4.append(['Enter a comma-separated list of DNS servers or',
                   'sendline({})'.format(self.dns_server), None, True, False])
        d4.append(['Enter a comma-separated list of search domains or',
                   'sendline({})'.format(self.search_domains), None, False, False])
        d4.process(self.spawn_id, timeout=900)

        d5 = Dialog([
            ['Configure (firewall|deployment) mode', 'sendline({})'.format(self.firewall_mode),
             None, True, False]
        ])

        if self.mode == 'local':
            d5.append(['Manage the device locally?', 'sendline(yes)', None, True, False])
        else:
            d5.append(['Manage the device locally?', 'sendline(no)', None, True, False])
        d5.append(['Successfully performed firstboot initial configuration steps',
                   'sendline()', None, True, False])
        d5.append(['> ', 'sendline()', None, False, False])
        d5.process(self.spawn_id, timeout=600)

        logger.info('fully installed.')
 def __init__(self, connection, context, **kwargs):
     super().__init__(connection, context, **kwargs)
     self.dialog = Dialog(reload_statement_list + [boot_from_rommon_stmt])
    def rommon_to_new_image(self, rommon_tftp_server, pkg_image,
                            uut_ip, uut_netmask, uut_gateway, rommon_image, dns_server,
                            hostname='firepower', search_domains='cisco.com',
                            is_device_kenton=True, retry_count=MAX_RETRY_COUNT,
                            power_cycle_flag=False, pdu_ip='', pdu_port='',
                            pdu_user='******', pdu_pwd='admn', ntp_server=None,
                            mode='local',
                            uut_ip6=None, uut_prefix=None, uut_gateway6=None,
                            manager=None, manager_key=None, manager_nat_id=None,
                            firewall_mode='routed', timeout=600, **kwargs):
        """Install rommon image and FTD pkg image on ASA.

        :param rommon_tftp_server: TFTP Server IP Address
        :param pkg_image: FTD image to be transferred via HTTP,
            e.g. 'http://192.168.0.50/Release/6.0.0-1005/installers/ftd-6.0.0-1005.pkg'
        :param uut_ip: Device IP Address to access TFTP Server
        :param uut_netmask: Device Netmask
        :param uut_gateway: Device Gateway
        :param rommon_image: boot image under /tftpboot to be transferred via TFTP,
            e.g. 'asa/Release/6.0.0-1005/installers/ftd-boot-99.1.3.194.lfbff'
        :param dns_server: DNS server
        :param hostname: hostname to be set
        :param search_domains: search domains delimited by comma,
            defaulted to 'cisco.com'
        :param is_device_kenton: True if device is Kenton, False if device is Saleen
        :param retry_count: download retry count, defaulted to MAX_RETRY_COUNT
        :param power_cycle_flag: True power cylce before baseline, False otherwise
        :param pdu_ip: PDU IP
        :param pdu_port: PDU Port
        :param pdu_user: PDU admn
        :param pdu_pwd: PDU pwd
        :param ntp_server: NTP server delimited by comma, defaulted to None,
            otherwise the value of ntp_server is - e.g. "ntp.esl.cisco.com"
        :param mode: the manager mode (local, remote)
        :param uut_ip6: Device IPv6 Address
        :param uut_prefix: Device IPv6 Prefix
        :param uut_gateway6: Device IPv6 Gateway
        :param manager: FMC to be configured for registration
        :param manager_key: Registration key
        :param manager_nat_id: Registration NAT Id
        :param firewall_mode: the firewall mode (routed, transparent, ngips)
        :param timeout: in seconds; time to wait for fetching the boot image from TFTP server;
                        defaulted to 600s
        :return: None

        """

        logger.info('Starting baseline')
        graphite.publish_kick_metric('device.ftd5500x.baseline', 1)
        self.rommon_tftp_server = rommon_tftp_server
        self.pkg_image = pkg_image
        self.uut_ip = uut_ip
        self.uut_netmask = uut_netmask
        self.uut_gateway = uut_gateway
        self.uut_ip6 = uut_ip6
        self.uut_prefix = uut_prefix
        self.uut_gateway6 = uut_gateway6
        self.rommon_image = rommon_image
        self.dns_server = dns_server
        self.hostname = hostname
        self.search_domains = search_domains
        self.retry_count = retry_count
        self.ntp_server = ntp_server
        self.mode = mode
        self.firewall_mode=firewall_mode
        self.manager = manager
        self.manager_key = manager_key
        self.manager_nat_id = manager_nat_id
        if not (self.sm.current_state in ['rommon_state', 'boot_state']):
            if not power_cycle_flag:
                if self.sm.current_state is 'disable_state':
                    logger.info('Device is in disable state. Go to enable and reload ...')
                    self.go_to('enable_state')
                    self.spawn_id.sendline('reload noconfirm')
                elif self.sm.current_state in ['enable_state', 'config_state']:
                    logger.info('Device is in enable or config state. Reloading ...')
                    self.spawn_id.sendline('reload noconfirm')
                else:
                    logger.info('Reboot the device ...')
                    self.go_to('sudo_state')
                    self.spawn_id.sendline('reboot')
            else:
                logger.info('Power cycle the device ...')
                self.power_cycle(pdu_ip, pdu_port, wait_until_device_is_on=False, power_bar_user=pdu_user,
                                 power_bar_pwd=pdu_pwd)
            try:
                self.spawn_id.expect('Use (.*?BREAK.*?|.*?ESC.*?) to interrupt boot', timeout=120)
            except TimeoutError:
                RuntimeError(">>>>>> Failed to stop rebooting")
            logger.info('Drop the device to rommon.')
            self.rommon_go_to()

        if self.sm.current_state is 'boot_state':
            logger.info('Device is in boot_state, drop the device to rommon.')
            self.spawn_id.sendline('system reload')
            d1 = Dialog([
                ['Are you sure you want to reload the system',
                 'sendline(y)', None, False, False],
            ])
            d1.process(self.spawn_id, timeout=30)
            self.rommon_go_to()

        if is_device_kenton:
            logger.info('Device is Kenton. Rommon configure.')
            self.rommon_configure()
        else:
            logger.info('Device is Saleen. Rommon configure.')
            self.rommon_configure_saleen()

        logger.info('tftpdnld - tftp server: {}, '
                    'rommon image: {} ...'.format(rommon_tftp_server, rommon_image))
        self.rommon_boot(timeout=timeout)
        self.go_to('any')
        logger.info('firepower boot configure ...')
        self.firepower_boot_configure()
        logger.info('FTD image install - image: {} ...'.format(pkg_image))
        self.firepower_install()
        self.go_to('any')
        if self.manager is not None and self.mode != 'local':
            logger.info('Configure manager')
            self.configure_manager()
        logger.info('Validate version installed')
        self.validate_version()
        logger.info('Installation completed successfully.')
Beispiel #27
0
def load_config_precessor(section, configs, unconfig=False):
    '''load configuration prepostprocessor

    Can be controlled via sections parameters which is provided by the
    triggers/verification datafile

    Args:
      Mandatory:
        section (`obj`): Aetest Subsection object.
        configs (`dict`) : Contains the configuration file location
        unconfig (`bool`) : True when apply the unconfigurations
                            Default as False

    Returns:
        AETEST results


    Raises:
        None

    '''
    log.info(
        banner('Load {} on devices'.format(
            'configurations' if not unconfig else 'unconfigurations')))

    if section and getattr(section, 'parameters', {}):

        testbed = section.parameters.get('testbed', {})
        # get uut in case there is need to store hardcode values
        uut = testbed.devices['uut']

        if os.path.isfile(configs):
            configs = yaml.load(open(configs))
        elif isinstance(configs, str):
            module = Lookup.from_device(uut)
            path = configs.split('.')
            for item in path:
                module = getattr(module, item)
            configs = module
        else:
            section.skipped('The configs type {} is not supported'.format(
                type(configs)))

        # copy dictionary without changing original configs
        # due to reuse it with conf/unconfig
        tmp_config = copy.deepcopy(configs)

        # Get hardcode values from uut
        for key, val in sorted(configs['devices']['uut'].items()):
            if not key.isdigit():
                if hasattr(section, 'mapping'):
                    # check if device
                    if key == 'peer':
                        uut.peer = testbed.devices[val]
                        tmp_config['devices']['uut'].pop(key)
                        continue
                    section.mapping.requirements.setdefault(
                        'provided_values', {}).setdefault(key, val)
                tmp_config['devices']['uut'].pop(key)

        for dev in sorted(configs.get('devices', {})):

            device = testbed.devices[dev]

            # Sort the item; it is expected to be
            # Sort them by the key, which needs to be an inter
            # 1, 2, 3, and so on
            for num, conf in sorted(tmp_config['devices'][dev].items()):
                if unconfig and 'unconfig' in conf:
                    conf['config'] = conf['unconfig']

                # replace the format syntax if has any
                conf['config'] = conf['config'].format(
                    **section.mapping.requirements.get('provided_values', {})
                    if hasattr(section, 'mapping') else {})

                log.info(
                    banner("Applying configuration on '{d}'".format(
                        d=device.name)))
                if os.path.isfile(conf['config']):
                    if 'invalid' not in conf:
                        # Set default
                        conf['invalid'] = []
                    try:
                        device.tftp.copy_file_to_device(
                            device=device,
                            filename=conf['config'],
                            location='running-config',
                            vrf='management',
                            invalid=conf['invalid'])
                    except Exception as e:
                        log.error(str(e))
                        section.failed(
                            "Issue while applying the configuration "
                            "on {d}".format(d=dev))
                elif isinstance(conf['config'], str):
                    try:
                        # Do you wish to continue? [yes]:
                        dialog = Dialog([
                            Statement(pattern=r'\[startup\-config\]\?.*',
                                      action='sendline()',
                                      loop_continue=True,
                                      continue_timer=False),
                            Statement(pattern=r'\[yes]\:.*',
                                      action='sendline()',
                                      loop_continue=True,
                                      continue_timer=False)
                        ])
                        device.configure(conf['config'], reply=dialog)
                    except Exception as e:
                        log.error(str(e))
                        section.failed(
                            "Issue while applying the configuration "
                            "on {d}".format(d=dev))
                else:
                    section.failed(
                        'The configs type {} is not supported'.format(
                            type(conf['config'])))

                # sleep for x amount of time after
                if 'sleep' in conf and not unconfig:
                    log.info("Sleeping for '{s}' "
                             "seconds for waiting system is stable "
                             "after loading the configuration".format(
                                 s=conf['sleep']))
                    time.sleep(conf['sleep'])
    def convert_to_elektra(self, rommon_tftp_server,
        uut_ip, uut_netmask, uut_gateway, asa_image, dns_server,
        hostname='firepower', search_domains='cisco.com',
        is_device_kenton=True, retry_count=MAX_RETRY_COUNT,
        power_cycle_flag=False, pdu_ip='', pdu_port='', mgmt_port='Management1/1', timeout=600):
        """Install rommon image and FTD pkg image on ASA.

        :param rommon_tftp_server: TFTP Server IP Address
        :param uut_ip: Device IP Address to access TFTP Server
        :param uut_netmask: Device Netmask
        :param uut_gateway: Device Gateway
        :param asa_image: asa boot image to be transferred via TFTP,
            e.g. 'asa/asa952-2-smp-k8.bin' for saleen or 'asa/asa952-2-lfbff-k8.SPA' for Kenton
        :param dns_server: DNS server
        :param hostname: hostname to be set
        :param search_domains: search domains delimited by comma,
            defaulted to 'cisco.com'
        :param is_device_kenton: True if device is Kenton, False if device is Saleen
        :param retry_count: download retry count, defaulted to MAX_RETRY_COUNT
        :param power_cycle_flag: True power cylce before baseline, False otherwise
        :param pdu_ip: PDU IP
        :param pdu_port: PDU Port
        :param mgmt_port: name of the management port; if not provided, defaulted to 'Management1/1'
        :param timeout: in seconds; time to wait for fetching the boot image from TFTP server;
                       defaulted to 600s
        :return: None

        """
        self.rommon_tftp_server = rommon_tftp_server
        self.uut_ip = uut_ip
        self.uut_netmask = uut_netmask
        self.uut_gateway = uut_gateway
        self.rommon_image = asa_image
        self.dns_server = dns_server
        self.hostname = hostname
        self.search_domains = search_domains

        if self.sm.current_state is 'rommon_state':
            logger.info('Reboot the device ...')
            self.spawn_id.sendline('reboot')

        if self.sm.current_state is 'boot_state':
            logger.info('Device is in boot_state, reload the device')
            self.spawn_id.sendline('system reload')
            d1 = Dialog([
                ['Are you sure you want to reload the system',
                 'sendline(y)', None, False, False],
            ])
            d1.process(self.spawn_id, timeout=30)

        logger.info('=== Enable configure')
        self.enable_configure()

        logger.info("=== Configure manamgement interface")
        self.configure_mgmt_interface(uut_ip, uut_netmask, uut_gateway, rommon_tftp_server, mgmt_port)

        logger.info("=== Set the new boot image")
        self.set_boot_image(self.rommon_tftp_server, asa_image)

        logger.info('=== Reboot the device ...')
        self.go_to('config_state')
        self.spawn_id.sendline('reload')
        d = Dialog([
            ['Proceed with reload?', 'sendline()', None, True, False],
            ['Rebooting', None, None, False, False],
        ])
        d.process(self.spawn_id, timeout=180)

        logger.info('==== Drop the device to rommon.')
        self.rommon_go_to()

        if is_device_kenton:
            logger.info('Device is Kenton. Rommon configure.')
            self.rommon_configure()
        else:
            logger.info('Device is Saleen. Rommon configure.')
            self.rommon_configure_saleen()

        logger.info('tftpdnld - tftp server: {}, '
                    'rommon image: {} ...'.format(rommon_tftp_server, asa_image))
        self.rommon_boot(timeout=timeout)

        logger.info("=== Configure management interface")
        self.go_to('any')
        self.configure_mgmt_interface(uut_ip, uut_netmask, uut_gateway, rommon_tftp_server, mgmt_port)
        logger.info("=== You have converted successfully the device to Elektra")
    def call_service(self,
                     reload_command='reload',
                     dialog=Dialog([]),
                     target='active',
                     timeout=None,
                     reload_creds=None,
                     *args,
                     **kwargs):
        con = self.connection
        self.context = con.active.context
        timeout = timeout or self.timeout

        fmt_msg = "+++ reloading  %s  " \
                  " with reload_command %s " \
                  "and timeout is %s +++"
        con.log.debug(fmt_msg %
                      (self.connection.hostname, reload_command, timeout))

        con.active.state_machine.go_to(self.start_state,
                                       con.active.spawn,
                                       prompt_recovery=self.prompt_recovery,
                                       context=self.context)

        if not isinstance(dialog, Dialog):
            raise SubCommandFailure(
                "dialog passed must be an instance of Dialog")

        show_terminal = con.execute('show terminal')
        line_type = re.search(r"Line .*, Type \"(\w+)\"", show_terminal)
        if line_type and line_type.groups():
            line_type = line_type.group(1)

        if reload_creds:
            context = self.context.copy()
            context.update(cred_list=reload_creds)
        else:
            context = self.context

        if line_type == 'Console':
            dialog += self.dialog
            con.active.spawn.sendline(reload_command)
            try:
                try:
                    self.result = dialog.process(
                        con.active.spawn,
                        timeout=timeout,
                        prompt_recovery=self.prompt_recovery,
                        context=context)
                    if self.result:
                        self.result = self.result.match_output
                except Exception:
                    self.result = con.active.spawn.buffer
                    if 'is in standby' in self.result:
                        con.log.info(
                            'Timed out due to active/standby interchanged. Reconnecting...'
                        )
                    else:
                        con.log.info(
                            'Timed out. timeout might need to be increased. Reconnecting...'
                        )
                    con.disconnect()
                    original_connection_timeout = con.settings.CONNECTION_TIMEOUT
                    con.settings.CONNECTION_TIMEOUT = timeout
                    con.connect()
                    con.settings.CONNECTION_TIMEOUT = original_connection_timeout

                con.active.state_machine.go_to(
                    'any',
                    con.active.spawn,
                    prompt_recovery=self.prompt_recovery,
                    context=self.context)
                # Bring standby to good state.
                con.log.info('Waiting for config sync to finish')
                standby_wait_time = con.settings.POST_HA_RELOAD_CONFIG_SYNC_WAIT
                standby_wait_interval = 50
                standby_sync_try = standby_wait_time // standby_wait_interval + 1
                for round in range(standby_sync_try):
                    con.standby.spawn.sendline()
                    try:
                        con.standby.state_machine.go_to(
                            'any',
                            con.standby.spawn,
                            context=context,
                            timeout=standby_wait_interval,
                            prompt_recovery=self.prompt_recovery,
                            dialog=con.connection_provider.
                            get_connection_dialog())
                        break
                    except Exception as err:
                        if round == standby_sync_try - 1:
                            raise Exception(
                                'Bringing standby to any state failed within {} sec'
                                .format(standby_wait_time)) from err
            except Exception as err:
                raise SubCommandFailure("Reload failed %s" % err)

            output = self.result
            output = output.replace(reload_command, "", 1)
            # only strip first newline and leave formatting intact
            output = re.sub(r"^\r?\r\n", "", output, 1)
            output = output.rstrip()
        else:
            raise Exception("Console is not used.")

        self.result = output
    def call_service(self,
                     command=[],
                     reply=Dialog([]),
                     timeout=None,
                     error_pattern=None,
                     *args,
                     **kwargs):

        # Get current state of the state machine and determine end state
        sm = self.get_sm()
        con = self.connection

        con.log.debug('+++ configure state %s +++' % sm.current_state)

        if sm.current_cli_style == 'cisco':
            self.start_state = 'cisco_config'
            self.end_state = 'cisco_exec'
            PROMPT_PREFIX = None
        elif sm.current_cli_style == 'juniper':
            self.start_state = 'juniper_config'
            self.end_state = 'juniper_exec'
            PROMPT_PREFIX = con.settings.JUNIPER_PROMPT_PREFIX
        else:
            raise StateMachineError(
                'Invalid state (%s) when calling configure' %
                sm.current_cli_style())

        spawn = self.get_spawn()
        sm.go_to(self.start_state, spawn, context=self.context)

        timeout = timeout or self.timeout
        if isinstance(command, str):
            command = command.splitlines()
        self.command_list_is_empty = False
        if not isinstance(reply, Dialog):
            raise SubCommandFailure(
                "dialog passed via 'reply' must be an instance of Dialog")

        # No command passed, just move to config mode
        if len(command) == 0:
            self.result = None
            self.command_list_is_empty = True
            return

        if con.settings.IGNORE_CHATTY_TERM_OUTPUT:
            # clear buffer of 'System message at ...' messages
            chatty_term_wait(con.spawn, trim_buffer=True)

        command_output = {}
        # if commands is a list
        if not isinstance(command, collections.abc.Sequence):
            raise SubCommandFailure('Invalid command passed %s' %
                                    repr(command))

        if 'commit' not in command:
            command.append('commit')

        try:
            for cmd in command:
                self.result = con.command(cmd,
                                          reply=reply,
                                          error_pattern=error_pattern,
                                          timeout=timeout)
                if self.result:
                    output = utils.truncate_trailing_prompt(
                        sm.get_state(sm.current_state), self.result,
                        self.connection.hostname)
                    output = output.replace(cmd, "", 1)
                    output = re.sub(r"^\r\n", "", output, 1)
                    if PROMPT_PREFIX:
                        output = re.sub(PROMPT_PREFIX, "", output)
                    command_output[cmd] = output.rstrip()
        except SubCommandFailure as e:
            # Go to exec state after command failure,
            # do not commit changes (handled by state transition)
            sm.go_to(self.end_state, spawn, context=self.context)
            raise

        if len(command_output) == 1:
            self.result = list(command_output.values())[0]
        else:
            self.result = command_output