cisco_wlc_ssh.py 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. """Netmiko Cisco WLC support."""
  2. from __future__ import print_function
  3. from __future__ import unicode_literals
  4. import time
  5. import re
  6. from netmiko.base_connection import BaseConnection
  7. from netmiko.py23_compat import string_types
  8. from netmiko import log
  9. class CiscoWlcSSH(BaseConnection):
  10. """Netmiko Cisco WLC support."""
  11. def special_login_handler(self, delay_factor=1):
  12. """WLC presents with the following on login (in certain OS versions)
  13. login as: user
  14. (Cisco Controller)
  15. User: user
  16. Password:****
  17. """
  18. delay_factor = self.select_delay_factor(delay_factor)
  19. i = 0
  20. time.sleep(delay_factor * .5)
  21. output = ""
  22. while i <= 12:
  23. output = self.read_channel()
  24. if output:
  25. if 'login as' in output or 'User' in output:
  26. self.write_channel(self.username + self.RETURN)
  27. elif 'Password' in output:
  28. self.write_channel(self.password + self.RETURN)
  29. break
  30. time.sleep(delay_factor * 1)
  31. else:
  32. self.write_channel(self.RETURN)
  33. time.sleep(delay_factor * 1.5)
  34. i += 1
  35. def send_command_w_enter(self, *args, **kwargs):
  36. '''
  37. For 'show run-config' Cisco WLC adds a 'Press Enter to continue...' message
  38. Even though pagination is disabled
  39. show run-config also has excessive delays in the output which requires special
  40. handling.
  41. Arguments are the same as send_command_timing() method
  42. '''
  43. if len(args) > 1:
  44. raise ValueError("Must pass in delay_factor as keyword argument")
  45. # If no delay_factor use 1 for default value
  46. delay_factor = kwargs.get('delay_factor', 1)
  47. kwargs['delay_factor'] = self.select_delay_factor(delay_factor)
  48. output = self.send_command_timing(*args, **kwargs)
  49. if 'Press Enter to' in output:
  50. new_args = list(args)
  51. if len(args) == 1:
  52. new_args[0] = self.RETURN
  53. else:
  54. kwargs['command_string'] = self.RETURN
  55. if not kwargs.get('max_loops'):
  56. kwargs['max_loops'] = 150
  57. # Send an 'enter'
  58. output = self.send_command_timing(*new_args, **kwargs)
  59. # WLC has excessive delay after this appears on screen
  60. if '802.11b Advanced Configuration' in output:
  61. # Defaults to 30 seconds
  62. time.sleep(kwargs['delay_factor'] * 30)
  63. not_done = True
  64. i = 1
  65. while not_done and i <= 150:
  66. time.sleep(kwargs['delay_factor'] * 3)
  67. i += 1
  68. new_data = ""
  69. new_data = self.read_channel()
  70. if new_data:
  71. output += new_data
  72. else:
  73. not_done = False
  74. strip_prompt = kwargs.get('strip_prompt', True)
  75. if strip_prompt:
  76. # Had to strip trailing prompt twice.
  77. output = self.strip_prompt(output)
  78. output = self.strip_prompt(output)
  79. return output
  80. def session_preparation(self):
  81. '''
  82. Prepare the session after the connection has been established
  83. Cisco WLC uses "config paging disable" to disable paging
  84. '''
  85. self._test_channel_read()
  86. self.set_base_prompt()
  87. self.disable_paging(command="config paging disable")
  88. # Clear the read buffer
  89. time.sleep(.3 * self.global_delay_factor)
  90. self.clear_buffer()
  91. def cleanup(self):
  92. """Reset WLC back to normal paging."""
  93. self.send_command_timing("config paging enable")
  94. def check_config_mode(self, check_string='config', pattern=''):
  95. """Checks if the device is in configuration mode or not."""
  96. if not pattern:
  97. pattern = re.escape(self.base_prompt)
  98. return super(CiscoWlcSSH, self).check_config_mode(check_string, pattern)
  99. def config_mode(self, config_command='config', pattern=''):
  100. """Enter into config_mode."""
  101. if not pattern:
  102. pattern = re.escape(self.base_prompt)
  103. return super(CiscoWlcSSH, self).config_mode(config_command, pattern)
  104. def exit_config_mode(self, exit_config='exit', pattern=''):
  105. """Exit config_mode."""
  106. if not pattern:
  107. pattern = re.escape(self.base_prompt)
  108. return super(CiscoWlcSSH, self).exit_config_mode(exit_config, pattern)
  109. def send_config_set(self, config_commands=None, exit_config_mode=True, delay_factor=1,
  110. max_loops=150, strip_prompt=False, strip_command=False,
  111. config_mode_command=None):
  112. """
  113. Send configuration commands down the SSH channel.
  114. config_commands is an iterable containing all of the configuration commands.
  115. The commands will be executed one after the other.
  116. Does not automatically exit/enter configuration mode.
  117. """
  118. delay_factor = self.select_delay_factor(delay_factor)
  119. if config_commands is None:
  120. return ''
  121. elif isinstance(config_commands, string_types):
  122. config_commands = (config_commands,)
  123. if not hasattr(config_commands, '__iter__'):
  124. raise ValueError("Invalid argument passed into send_config_set")
  125. # Send config commands
  126. for cmd in config_commands:
  127. self.write_channel(self.normalize_cmd(cmd))
  128. time.sleep(delay_factor * .5)
  129. # Gather output
  130. output = self._read_channel_timing(delay_factor=delay_factor, max_loops=max_loops)
  131. output = self._sanitize_output(output)
  132. log.debug("{}".format(output))
  133. return output
  134. def save_config(self, cmd='save config', confirm=True, confirm_response='y'):
  135. return super(CiscoWlcSSH, self).save_config(cmd=cmd, confirm=confirm,
  136. confirm_response=confirm_response)