Fix `authorize: yes` and `become_method: enable` (#32864)

* Update connection play_context when socket exists

* Don't fail on connections other than network_cli

* Fix enable prompt detection on ios & eos

* Check against "Module not found" error code, defined in modules/jsonrpc.py
pull/32918/head
Nathaniel Case 7 years ago committed by GitHub
parent 3fedd88a9f
commit a1517234f6
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -26,12 +26,11 @@ from ansible import constants as C
from ansible.module_utils._text import to_bytes, to_native, to_text from ansible.module_utils._text import to_bytes, to_native, to_text
from ansible.module_utils.six import PY3 from ansible.module_utils.six import PY3
from ansible.module_utils.six.moves import cPickle from ansible.module_utils.six.moves import cPickle
from ansible.module_utils.connection import send_data, recv_data from ansible.module_utils.connection import Connection, ConnectionError, send_data, recv_data
from ansible.module_utils.service import fork_process from ansible.module_utils.service import fork_process
from ansible.playbook.play_context import PlayContext from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import connection_loader from ansible.plugins.loader import connection_loader
from ansible.utils.path import unfrackpath, makedirs_safe from ansible.utils.path import unfrackpath, makedirs_safe
from ansible.errors import AnsibleError
from ansible.utils.display import Display from ansible.utils.display import Display
from ansible.utils.jsonrpc import JsonRpcServer from ansible.utils.jsonrpc import JsonRpcServer
@ -293,6 +292,20 @@ def main():
else: else:
messages.append('found existing local domain socket, using it!') messages.append('found existing local domain socket, using it!')
conn = Connection(socket_path)
pc_data = to_text(init_data)
try:
messages.extend(conn.update_play_context(pc_data))
except Exception as exc:
# Only network_cli has update_play context, so missing this is
# not fatal e.g. netconf
if isinstance(exc, ConnectionError) and getattr(exc, 'code') == -32601:
pass
else:
result.update({
'error': to_text(exc),
'exception': traceback.format_exc()
})
result.update({ result.update({
'messages': messages, 'messages': messages,

@ -56,8 +56,10 @@ from collections import Sequence
from ansible import constants as C from ansible import constants as C
from ansible.errors import AnsibleConnectionFailure from ansible.errors import AnsibleConnectionFailure
from ansible.module_utils.six import BytesIO, binary_type from ansible.module_utils.six import PY3, BytesIO, binary_type
from ansible.module_utils.six.moves import cPickle
from ansible.module_utils._text import to_bytes, to_text from ansible.module_utils._text import to_bytes, to_text
from ansible.playbook.play_context import PlayContext
from ansible.plugins.loader import cliconf_loader, terminal_loader, connection_loader from ansible.plugins.loader import cliconf_loader, terminal_loader, connection_loader
from ansible.plugins.connection import ConnectionBase from ansible.plugins.connection import ConnectionBase
from ansible.plugins.connection.local import Connection as LocalConnection from ansible.plugins.connection.local import Connection as LocalConnection
@ -134,19 +136,28 @@ class Connection(ConnectionBase):
def fetch_file(self, in_path, out_path): def fetch_file(self, in_path, out_path):
return self._local.fetch_file(in_path, out_path) return self._local.fetch_file(in_path, out_path)
def update_play_context(self, play_context): def update_play_context(self, pc_data):
"""Updates the play context information for the connection""" """Updates the play context information for the connection"""
pc_data = to_bytes(pc_data)
if PY3:
pc_data = cPickle.loads(pc_data, encoding='bytes')
else:
pc_data = cPickle.loads(pc_data)
play_context = PlayContext()
play_context.deserialize(pc_data)
display.vvvv('updating play_context for connection', host=self._play_context.remote_addr) messages = ['updating play_context for connection']
if self._play_context.become is False and play_context.become is True: if self._play_context.become is False and play_context.become is True:
auth_pass = play_context.become_pass auth_pass = play_context.become_pass
self._terminal.on_authorize(passwd=auth_pass) self._terminal.on_authorize(passwd=auth_pass)
messages.append('authorizing connection')
elif self._play_context.become is True and not play_context.become: elif self._play_context.become is True and not play_context.become:
self._terminal.on_deauthorize() self._terminal.on_deauthorize()
messages.append('deauthorizing connection')
self._play_context = play_context self._play_context = play_context
return messages
def _connect(self): def _connect(self):
''' '''

@ -61,7 +61,7 @@ class TerminalModule(TerminalBase):
cmd = {u'command': u'enable'} cmd = {u'command': u'enable'}
if passwd: if passwd:
cmd[u'prompt'] = to_text(r"[\r\n]?password: $", errors='surrogate_or_strict') cmd[u'prompts'] = to_text(r"[\r\n]?password: $", errors='surrogate_or_strict')
cmd[u'answer'] = passwd cmd[u'answer'] = passwd
try: try:

@ -60,7 +60,7 @@ class TerminalModule(TerminalBase):
if passwd: if passwd:
# Note: python-3.5 cannot combine u"" and r"" together. Thus make # Note: python-3.5 cannot combine u"" and r"" together. Thus make
# an r string and use to_text to ensure it's text on both py2 and py3. # an r string and use to_text to ensure it's text on both py2 and py3.
cmd[u'prompt'] = to_text(r"[\r\n]?password: $", errors='surrogate_or_strict') cmd[u'prompts'] = to_text(r"[\r\n]?password: $", errors='surrogate_or_strict')
cmd[u'answer'] = passwd cmd[u'answer'] = passwd
try: try:

Loading…
Cancel
Save