Я пишу многопоточное приложение, которое вызывает Ansible через Python API.
Безопасен ли поток API Asible Python? Как сделать независимые CLIARGS в каждом потоке?
Теперь в каждом потоке я инициализирую context.CLIARGS, если соединение будет s sh или winrm.
Кажется, что в некоторых случаи, когда потоки работают параллельно, ansbile запускает playbook с подключением s sh, а затем переключается на winrm -с портом по умолчанию.
Я получаю сообщение об ошибке:
{'results': [{'unreachable': True
'msg': "ssl: HTTPSConnectionPool(host='server.test.com'
port=5986): Max retries exceeded with url: /wsman (Caused by NewConnectionError('<urllib3.connection.HTTPSConnection object at 0x7f02d0d3c198>: Failed to establish a new connection: [Errno 111] Connection refused',))"
, что странно потому что должно go через s sh. И даже если это когда-либо будет go через winrm, я никогда не буду устанавливать порт на 5986, а на 5985.
Мой фрагмент кода:
# initialize needed objects
loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
if os_type == 'linux':
inventory = InventoryManager(loader=loader, sources=(hostname+',') ) #sources=('/xxx/inventory_file',)) #< put HOSTNAME
conn_type='ssh'
variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))
# since the API is constructed for CLI it expects certain options to always be set in the context object
context.CLIARGS = ImmutableDict(tags={}, listtags=False, listtasks=False, listhosts=False, syntax=False, connection=conn_type,
module_path=None, forks=10, remote_user=ansible_user, private_key_file=None, ansible_ssh_pass=ansible_ssh_pass,
ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None,
become_method=None, become_user=None, verbosity=True, check=False, start_at_task=None, diff=False)
elif os_type == 'windows': # this is a special case, when we detected windows, we set inventory(for auth) and conn_type
inventory = InventoryManager(loader=loader, sources=(inventory_file) ) #sources=('/xxx/inventory_file',)) #< put HOSTNAME
conn_type ='winrm'
ansible_connection='winrm'
ansible_port = 5985
ansible_winrm_transport='ntlm'
variable_manager = VariableManager(loader=loader, inventory=inventory, version_info=CLI.version_info(gitinfo=False))
# since the API is constructed for CLI it expects certain options to always be set in the context object
context.CLIARGS = ImmutableDict(tags={}, listtags=False, listtasks=False, listhosts=False, syntax=False,
connection=conn_type, ansible_connection=ansible_connection, ansible_winrm_server_cert_validation='ignore', ansible_user=ansible_user,
module_path=None, forks=10, remote_user=ansible_user, private_key_file=None,
ssh_common_args=None, ssh_extra_args=None, sftp_extra_args=None, scp_extra_args=None, become=None,
become_method=None, become_user=None, verbosity=True, check=False, start_at_task=None, diff=False,
ansible_port=ansible_port, ansible_winrm_transport=ansible_winrm_transport
)
try:
pbex = PlaybookExecutor(playbooks=[playbook_path], inventory=inventory, variable_manager=variable_manager, loader=loader, passwords=passwords)
results = pbex.run()
Среда:
RHEL 7.8
Python 3.6.9
ansible==2.9.6
certifi==2020.4.5.1
cffi==1.14.0
chardet==3.0.4
click==7.1.1
cryptography==2.9
Flask==1.1.2
Flask-Threads==0.0.1a0
idna==2.9
itsdangerous==1.1.0
Jinja2==2.11.1
MarkupSafe==1.1.1
ntlm-auth==1.4.0
pycparser==2.20
pywinrm==0.4.1
PyYAML==5.3.1
requests==2.23.0
requests-ntlm==1.1.0
six==1.14.0
urllib3==1.25.9
waitress==1.4.3
Werkzeug==1.0.1
xmltodict==0.12.0