Ansible Api 2.x 密鑰登錄方式實現

前提

(1)密碼方式可先參閱我另外一篇博文:  https://blog.csdn.net/knight_zhou/article/details/103683305

(2)也可以參閱我的 51cto訂閱專欄:  https://blog.51cto.com/cloumn/detail/99

 

官方文檔

https://docs.ansible.com/ansible/2.7/dev_guide/index.html

實驗環境

主機名 OS IP 備註
vm201 Centos7.7 172.20.128.31 ansible2.7.8服務器
vm203 Centos7.7 172.20.128.33 客戶端


背景

有時候我們通過ansible執行shell或者playbook的時候,有時候是免密碼登錄客戶端機器的。也就是說是通過密鑰方式登錄客戶端機器,那麼如何實現Python的 Ansible Api 2.x 的密鑰方式了?

代碼實現

在網上找了半天關於密鑰方式的代碼實現,很多人寫代碼寫到一半,或者直接不全。或者直接貼核心代碼,也沒看見完整代碼在哪裏,亂七八糟的。所以本人摸索別人的代碼以及結合官方文檔。進行代碼實現如下:

我們暫且命名爲 ansible_api_key_shell.py 文件,用來實現密鑰方式去執行shell命令

#!/usr/bin/python
#coding:utf-8
from ansible.inventory.manager import InventoryManager
from ansible.parsing.dataloader import DataLoader
from ansible.vars.manager import VariableManager
from ansible.playbook.play import Play
from ansible.executor.task_queue_manager import TaskQueueManager
from ansible.plugins.callback import CallbackBase
from collections import namedtuple

loader = DataLoader()
inventory = InventoryManager(loader=loader, sources=['/etc/ansible/hosts']) 

variable_manager = VariableManager(loader=loader, inventory=inventory)

Options = namedtuple ('Options',
                     ['connection',
                      'remote_user',
                      'ask_sudo_pass',
                      'ack_pass',
                      'module_path',
                      'forks',
                      'become',
                      'become_method',
                      'become_user',
                      'check',
                      'listhosts',
                      'sudo_user',
                      'sudo',
                      'diff']
                     )

options = Options(connection='smart',
                  remote_user='www',
                  ack_pass=None,
                  sudo_user=None,
                  forks=5,
                  ask_sudo_pass=None,
                  module_path=None,
                  become=None,
                  become_method=None,
                  become_user=None,
                  listhosts=None,
                  check=False,
                  diff=False,
                  sudo=False)   

play_source = dict(
    name = 'exec shell', 
    #hosts = '10.20.128.21', 
    hosts = 'all', 
    gather_facts = 'yes', 
    tasks = [
        dict(action=dict(module='shell', args='touch /tmp/xxzz')),
    ]
)

play = Play().load(play_source, variable_manager=variable_manager, loader=loader)


## 定義任務隊列
tqm = TaskQueueManager(
    inventory=inventory,
    variable_manager=variable_manager,
    loader=loader,
    options=options,
    #passwords=dict(conn_pass="zhoulong")
    passwords=None,
    #private_key_file=key_file
)
##
result = tqm.run(play)
print(result)

我們執行一下腳本看看返回結果:

[www@vm201 ~]$ python ansible_api_key_shell.py 

PLAY [exec shell] *********************************************************************************************************************************************

TASK [Gathering Facts] ****************************************************************************************************************************************
ok: [172.20.128.33]

TASK [shell] **************************************************************************************************************************************************
 [WARNING]: Consider using the file module with state=touch rather than running 'touch'.  If you need to use command because file is insufficient you can add
'warn: false' to this command task or set 'command_warnings=False' in ansible.cfg to get rid of this message.

changed: [172.20.128.33]
0

然後我們在客戶端看看是不是生成了文件:

[www@vm203 ~]$ ll /tmp/xxzz 
-rw-rw-r-- 1 www www 0 Jul  1 23:57 /tmp/xxzz

到此執行成功。

至於如何執行playbook,這裏就不再講了,如果你讀了我的另外一篇博文 "Ansible Api 2.x 詳解" 或者我的51cto 博客專欄,你一定知道怎麼寫了。

需要注意的地方

之前我一直以爲 定義任務隊列的時候(TaskQueueManager) 需要把密鑰文件指定位置,然後我通過查官方文檔發現並沒有這個參數。

所以如果我們在設置密碼爲空的前提下默認就會走密鑰方式登錄機器。這個是要注意的地方。

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章