一起學Python吧~Python3調用Ansible項目實戰

別問我爲什麼Terminal的命令也要用PyCharm來寫,一切都是爲了方便麪~

#!/bin/env python3
#-*- coding:utf8 -*-
#學python3的第十四天(運維開發者工具)
#Ansible批量管理
# """配置簡單ansible環境
# [root@room9pc01 ~]# cat  /etc/hosts
# 127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4
# ::1         localhost localhost.localdomain localhost6 localhost6.localdomain6
# 192.168.1.50  node4
# 192.168.1.5   node5
# 192.168.1.6   node6
# [root@room9pc01 ~]#mkdir ansiblereadme
# [root@room9pc01 ~]#cd ansiblereadme
# [root@room9pc01 ansiblereadme]#vim ansible.cfg
# [defaults]
# inventory = hosts
# remote_user = root
# host_key_checking = False
#
# #vim hosts
# [dbservers]
# node4
#
# [webservers]
# node5
# node6
# """
# #兩種命令管理方式:adhoc,playbook
# #1)adhoc臨時命令
# #adhoc方式配置yum
# """
# [root@room9pc01 ansiblereadme]#  ansible all -m yum_repository -a "name=Server baseurl=ftp://192.168.1.254/centos-1804 enabled=yes gpgcheck=no description='Centos 7.4'"
# node5 | CHANGED => {
#     "changed": true,
#     "repo": "Server",
#     "state": "present"
# }
# node6 | CHANGED => {
#     "changed": true,
#     "repo": "Server",
#     "state": "present"
# }
# node4 | CHANGED => {
#     "changed": true,
#     "repo": "Server",
#     "state": "present"
# }
# """
# """檢查yum是否配好
# [root@room9pc01 ansiblereadme]# for i in node{4,5,6}
# > do
# > ssh $i 'yum repolist'
# > done
# 已加載插件:fastestmirror
# Loading mirror speeds from cached hostfile
# 源標識                             源名稱                                  狀態
# Server                             Centos 7.4                              9,911
# local_repo                         CentOS-7 - Base                         9,911
# repolist: 19,822
# 已加載插件:fastestmirror
# Determining fastest mirrors
# 源標識                             源名稱                                  狀態
# Server                             Centos 7.4                              9,911
# local_repo                         CentOS-7 - Base                         9,911
# repolist: 19,822
# 已加載插件:fastestmirror
# Determining fastest mirrors
# 源標識                             源名稱                                  狀態
# Server                             Centos 7.4                              9,911
# local_repo                         CentOS-7 - Base                         9,911
# repolist: 19,822
# """
# #2)playbook創建lamp環境
# """修改vim配置,適應yaml語法(非必須)
# [root@room9pc01 ansiblereadme]# vim ~/.vimrc
# [root@room9pc01 ansiblereadme]# cat ~/.vimrc
# autocmd FileType yaml setlocal sw=2 ts=2 et ai
# """
# """編寫playbook配置lamp
# [root@room9pc01 ansiblereadme]# vim lamp.yml
# [root@room9pc01 ansiblereadme]# cat lamp.yml
# ---
# - name: configure webservers
#   hosts: webservers
#   tasks:
#     - name: install web pkgs
#       yum:
#         name: httpd, php, php-mysql
#         state: installed
#
#     - name: configure web service
#       service:
#         name: httpd
#         state: started
#         enabled: yes
#
# - name: configure dbservers
#   hosts: dbservers
#   tasks:
#     - name: install db pkgs
#       yum:
#         name: mariadb-server
#         state: present
#     - name: configure db service
#       service:
#         name: mariadb
#         state: started
#         enabled: yes
# """
# """檢查配置文件語法
# [root@room9pc01 ansiblereadme]# ansible-playbook --syntax-check lamp.yml
#
# playbook: lamp.yml
# """
# """執行playbook
# [root@room9pc01 ansiblereadme]# ansible-playbook lamp.yml
#
# PLAY [configure webservers] *****************************************************************
#
# TASK [Gathering Facts] **********************************************************************
# ok: [node6]
# ok: [node5]
#
# TASK [install web pkgs] *********************************************************************
# ok: [node6]
# ok: [node5]
#
# TASK [configure web service] ****************************************************************
# changed: [node6]
# changed: [node5]
#
# PLAY [configure dbservers] ******************************************************************
#
# TASK [Gathering Facts] **********************************************************************
# ok: [node4]
#
# TASK [install db pkgs] **********************************************************************
# ok: [node4]
#
# TASK [configure db service] *****************************************************************
# ok: [node4]
#
# PLAY RECAP **********************************************************************************
# node4                      : ok=3    changed=1    unreachable=0    failed=0
# node5                      : ok=3    changed=1    unreachable=0    failed=0
# node6                      : ok=3    changed=1    unreachable=0    failed=0
# """
# """檢查是否成功
# [root@room9pc01 ansiblereadme]# check () {
# > ssh node4 'netstat -ntlupa|grep 3306'
# > ssh node5 'netstat -ntlupa|grep 80'
# > ssh node6 'netstat -ntlupa|grep 80'
# > }
# [root@room9pc01 ansiblereadme]# check
# tcp        0      0 0.0.0.0:3306            0.0.0.0:*               LISTEN      835/mysqld
# tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      23818/httpd
# tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN      23801/httpd
# """
"""ansible編程(主要用途:以Python調用Ansible)
ansile官方站點:https://docs.ansible.com/ansible/2.7/index.html
 -> 搜索 python api -> 將示例代碼拷貝出來,執行。
 確認可執行後 修改如下內容再次執行!
"""
#***************python API****************
# #!/usr/bin/env python
#
# import shutil
# from collections import namedtuple
# from ansible.parsing.dataloader import DataLoader
# from ansible.vars.manager import VariableManager
# from ansible.inventory.manager import InventoryManager
# from ansible.playbook.play import Play
# from ansible.executor.task_queue_manager import TaskQueueManager
# import ansible.constants as C
#
# # since API is constructed for CLI it expects certain options to always be set, named tuple 'fakes' the args parsing options object
# # option用於定義選項,絕大部分使用默認值即可
# # connection是連接方式,有三種:
# # local: 本地執行指令;ssh: 通過ssh連接執行;smart:自動判斷
# # fork指定可以創建的進程數,每個進程連接一臺服務器
# Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff'])
# # options = Options(connection='local', module_path=['/to/mymodules'], forks=10, become=None, become_method=None, become_user=None, check=False, diff=False)
# options = Options(connection='smart', module_path=['/to/mymodules'], forks=10, become=None, become_method=None, become_user=None, check=False, diff=False)
#
# # initialize needed objects
# # DataLoader負責將yaml、json、ini等文件轉換成python的數據類型
# loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
# #存儲加密密碼
# passwords = dict(vault_pass='secret')
#
# # create inventory, use path to host config file as source or hosts in a comma separated string
# #主機清單 有兩種形式,一種是用逗號將所有的主機分割的字符串
# #另一種形式,是使用列表將主機清單文件位置包含
# inventory = InventoryManager(loader=loader, sources='ansiblereadme/hosts')
#
# # variable manager takes care of merging all the different sources to give you a unifed view of variables available in each context
# #用於保管變量的管理器
# variable_manager = VariableManager(loader=loader, inventory=inventory)
#
# # create datastructure that represents our play, including tasks, this is basically what our YAML loader does internally.
# #創建代表play的數據結構
# play_source =  dict(
#         name = "Ansible Play",
#         hosts = 'webservers', #在那些主機上執行任務
#         gather_facts = 'no',
#         tasks = [
#             dict(action=dict(module='shell', args='ls'), register='shell_out'),
#             dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
#          ]
#     )
#
# # Create play object, playbook objects use .load instead of init or new methods,
# # this will also automatically create the task objects from the info provided in play_source
# #創建一個play對象
# play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
#
# # Run it - instantiate task queue manager, which takes care of forking and setting up all objects to iterate over host list and tasks
# #創建任務隊列管理器,用於調度執行play
# tqm = None
# try:
#     tqm = TaskQueueManager(
#               inventory=inventory,
#               variable_manager=variable_manager,
#               loader=loader,
#               options=options,
#               passwords=passwords,
#           )
#     result = tqm.run(play) # most interesting data for a play is actually sent to the callback's methods
# finally:
#     # we always need to cleanup child procs and the structres we use to communicate with them
#     #請理執行後的環境,如刪除臨時文件
#     if tqm is not None:
#         tqm.cleanup()
#
#     # Remove ansible tmpdir
#     shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
"""執行
(csdnak) [root@room9pc01 untitled]# ./14.day.py 

PLAY [Ansible Play] *****************************************************************

TASK [shell] ************************************************************************
changed: [node6]
changed: [node5]

TASK [debug] ************************************************************************
ok: [node5] => {
    "msg": ""
}
ok: [node6] => {
    "msg": ""
}

"""
#Ansible加密/解密文件測試
"""對應上方passwords選項(選用)
# 加密文件
[root@room8pc16 ansiblereadme]# echo 'hello world' > hi.txt
[root@room8pc16 ansiblereadme]# cat hi.txt 
hello world
[root@room8pc16 ansiblereadme]# ansible-vault encrypt hi.txt 

# 解密
[root@room8pc16 ansiblereadme]# ansible-vault decrypt hi.txt 
"""
#****************Funcation Python API*****************************
"""
還可添加sys模塊用sys.argv模塊來進行傳參操作!
可直接當成模塊import啦!
"""
# #!/bin/env python3
# import shutil
# from collections import namedtuple
# from ansible.parsing.dataloader import DataLoader
# from ansible.vars.manager import VariableManager
# from ansible.inventory.manager import InventoryManager
# from ansible.playbook.play import Play
# from ansible.executor.task_queue_manager import TaskQueueManager
# import ansible.constants as C
#
# def adhoc(sources, hosts, module, args):
#     Options = namedtuple('Options', ['connection', 'module_path', 'forks', 'become', 'become_method', 'become_user', 'check', 'diff'])
#     options = Options(connection='smart', module_path=['/to/mymodules'], forks=10, become=None, become_method=None, become_user=None, check=False, diff=False)
#     loader = DataLoader() # Takes care of finding and reading yaml, json and ini files
#     passwords = dict(vault_pass='secret')
#     inventory = InventoryManager(loader=loader, sources=sources)
#     variable_manager = VariableManager(loader=loader, inventory=inventory)
#     play_source=dict(
#             name="Ansible Play",
#             hosts=hosts,  # 在哪些主機上執行任務
#             gather_facts='no',
#             tasks=[
#                 dict(action=dict(module=module, args=args), register='shell_out'),
#                 dict(action=dict(module='debug', args=dict(msg='{{shell_out.stdout}}')))
#              ]
#         )
#     play = Play().load(play_source, variable_manager=variable_manager, loader=loader)
#     tqm = None
#     try:
#         tqm = TaskQueueManager(
#                   inventory=inventory,
#                   variable_manager=variable_manager,
#                   loader=loader,
#                   options=options,
#                   passwords=passwords,
#               )
#         result = tqm.run(play) # most interesting data for a play is actually sent to the callback's methods
#     finally:
#         if tqm is not None:
#             tqm.cleanup()
#
#         shutil.rmtree(C.DEFAULT_LOCAL_TMP, True)
# if __name__ == '__main__':
#     adhoc(sources=['ansiblereadme/hosts'], hosts='dbservers', module='shell', args='id root')
"""執行
(csdnak) [root@room9pc01 untitled]# ./14.day.py 

PLAY [Ansible Play] *****************************************************************

TASK [shell] ************************************************************************
changed: [node4]

TASK [debug] ************************************************************************
ok: [node4] => {
    "msg": "uid=0(root) gid=0(root) 組=0(root)"
}
"""
#***********************Python3 Funcation Playbook************************
"""
實現python調用playbook
"""
# #!/bin/env python3
# from collections import namedtuple
# from ansible.parsing.dataloader import DataLoader
# from ansible.vars.manager import VariableManager
# from ansible.inventory.manager import InventoryManager
# from ansible.executor.playbook_executor import PlaybookExecutor
#
# def runpb(hosts_list, playbooks):
#     Options = namedtuple('Options',
#                          ['connection',
#                           'remote_user',
#                           'ask_sudo_pass',
#                           'verbosity',
#                           'ask_pass',
#                           'module_path',
#                           'forks',
#                           'become',
#                           'become_method',
#                           'become_user',
#                           'check',
#                           'listhosts',
#                           'listtasks',
#                           'listtags',
#                           'syntax',
#                           'sudo_user',
#                           'sudo',
#                           'diff'])
#     options = Options(connection='smart',
#                       remote_user='root',
#                       ask_pass=None,
#                       sudo_user=None,
#                       forks=5,
#                       sudo=None,
#                       ask_sudo_pass=False,
#                       verbosity=5,
#                       module_path=None,
#                       become=None,
#                       become_method=None,
#                       become_user=None,
#                       check=False,
#                       diff=False,
#                       listhosts=None,
#                       listtasks=None,
#                       listtags=None,
#                       syntax=None)
#     loader = DataLoader()
#     passwords = dict()
#     inventory = InventoryManager(loader=loader, sources=hosts_list)
#     variable_manager = VariableManager(loader=loader, inventory=inventory)
#     playbook = PlaybookExecutor(
#         playbooks=playbooks,
#         inventory=inventory,
#         variable_manager=variable_manager,
#         loader=loader,
#         options=options,
#         passwords=passwords
#     )
#     result = playbook.run()
#     return result
#
# if __name__ == '__main__':
#     print(runpb(['ansiblereadme/hosts'], playbooks=['ansiblereadme/lamp.yml']))
#
"""執行(因爲前面執行過安裝mariadb httpd所以改變結果爲0 )
(csdnak) [root@room9pc01 untitled]# ./14.day.py 

PLAY [configure webservers] *********************************************************

TASK [Gathering Facts] **************************************************************
ok: [node5]
ok: [node6]

TASK [install web pkgs] *************************************************************
ok: [node5]
ok: [node6]

TASK [configure web service] ********************************************************
ok: [node5]
ok: [node6]

PLAY [configure dbservers] **********************************************************

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

TASK [install db pkgs] **************************************************************
ok: [node4]

TASK [configure db service] *********************************************************
ok: [node4]

PLAY RECAP **************************************************************************
node4                      : ok=3    changed=0    unreachable=0    failed=0   
node5                      : ok=3    changed=0    unreachable=0    failed=0   
node6                      : ok=3    changed=0    unreachable=0    failed=0   

0

"""
#*****************************************************************
# """命名的元組
# - 本質上還是元組
# - 元組通過下標取值
# - 命名的元組只是給下標起名。可以通過名字進行取值
# """
# from collections import namedtuple
# Poin = namedtuple('Point',['x','y','z'])
# p1 = Poin(10, 20, 15)
# print(p1[1:])  #(20, 15)
# print(p1[-1])  #15
# print(p1.x)  #10
# print(p1.y)  #20
# print(p1.z)  #15
#*****************************************************************
#將yaml文件轉成python數據庫類型(手動版本)
"""
-開頭的轉成列表
:開頭的轉成字典
"""
#一個playbook由兩個play構成,每個play都是一個列表項
#每個play又是一個字典結構
# [
#     {
#         name: configure webservers,
#         hosts: webservers,
#         tasks: [
#             {
#                 name: install web pkgs,
#                 yum: {
#                     name: httpd, php, php-mysql,
#                     state: present
#                 }
#             },
#             {
#                 name: configure web service,
#                 service: {
#                     name: httpd,
#                     state: started,
#                     enabled: yes
#                 }
#             },
#         ],
#     },
#     {
#         name: configure dbservers,
#         hosts: dbservers,
#         tasks: [
#             {
#                 name: install db pkgs,
#                 yum: {
#                     name: mariadb-server,
#                     state: present
#                 }
#             },
#             {
#                 name: configure db service,
#                 service: {
#                     name: mariadb,
#                     state: started,
#                     enabled: yes
#                 }
#             }
#         ]
#     },
# ]

#*********創建ansible模塊目錄**********
"""必須做此步驟(否則模塊不能用)
(csdnak) [root@room9pc01 untitled]# mkdir /tmp/mylib
(csdnak) [root@room9pc01 untitled]# export ANSIBLE_LIBRARY=/tmp/mylib
(csdnak) [root@room8pc16 day03]# vim /tmp/mylib/rcopy.py
"""
# #!/bin/env python3
# #實現copy功能
# from ansible.module_utils.basic import AnsibleModule
# import shutil
#
# def main():
#     module = AnsibleModule(
#         argument_spec=dict(
#             source=dict(required=True, type='str'),
#             destination=dict(required=True, type='str')
#         )
#     )
#     shutil.copy(module.params['source'], module.params['destination'])
#     module.exit_json(changed=True)
#
# if __name__ == '__main__':
#     main()
"""執行
(csdnak) [root@room9pc01 ansiblereadme]# ansible dbservers -m 14.day -a "source=/etc/hosts destination=/tmp/csdnak"
node4 | CHANGED => {
    "changed": true
}
#查看node4上是否有阿坤文件
(csdnak) [root@room9pc01 ansiblereadme]# ssh node4 'ls /tmp/csdnak'
/tmp/csdnak
"""
#************************
"""實現以下程序必須保證src和dst兩機python都有wget模塊
- 在http://pypi.org查找並下載wget
- 拷貝wget到目標主機
[root@node4 ~]# unzip wget-3.2.zip 
[root@node4 ~]# cd wget-3.2/
[root@node4 wget-3.2]# python setup.py install
"""
# #!/bin/env python3
# #實現資源下載
# from ansible.module_utils.basic import  AnsibleModule
# import wget
#
# def main():
#     module = AnsibleModule(
#         argument_spec=dict(
#             url=dict(required=True, type='str'),
#             dest=dict(required=True, type='str')
#         )
#     )
#     wget.download(module.params['url'], module.params['dest'])
#     module.exit_json(changed=True)
#
# if __name__ == '__main__':
#     main()
"""執行
(nsd1906) [root@room9pc01 ansiblereadme]# ansible dbservers -m 14.day -a "url=https://gss2.bdstatic.com/9fo3dSag_xI4khGkpoWK1HF6hhy/baike/c0%3Dbaike150%2C5%2C5%2C150%2C50/sign=e95e57acd20735fa85fd46ebff3864d6/f703738da9773912f15d70d6fe198618367ae20a.jpg  dest=/tmp/csdnak.jpg"
node4 | CHANGED => {
    "changed": true
}
#查看阿坤照片
[root@node4 ~]# eog /tmp/csdnak.jpg 

(eog:1779): Gtk-WARNING **: cannot open display: 
"""

#*************************晚間複習**************************
#***************time模塊**************
"""
時間戳:1970-1-1 0:0:0 到某一時間點之間的秒數
UTC時間:世界協調時,以英國格林威治所在的縱切面作爲標準時區,每隔15度是一個時區,共24個時區.
9元組:(年,月,日,時,分,秒,一週中的第幾天,一年中的第幾天,是否爲夏時制)
"""
# #當前時間的時間戳
# import time
# time.time()  #1573176067.5228834
# #字符串表示UTC時間
# time.ctime()  #'Fri Nov 8 09:32:08 2019'
# time.ctime(0) #0是時間戳
# #時間格式化
# time.strftime('%Y-%m%-%d %H:%M:%S')
# time.strftime('%Y-%m-%d %a %H:%M:%S')  #'2019-11-08 Fri 09:35:37'
# #9元組時間
# t1 = time.localtime()
# print(t1.tm_year)  #2019
# print(t1.tm_yday)  #312
# print(time.strptime('2019-11-11 00:00:00', '%Y-%m-%d %H:%M:%S'))
# #time.struct_time(tm_year=2019, tm_mon=11, tm_mday=11, tm_hour=0,
# #  tm_min=0, tm_sec=0,tm_wday=0, tm_yday=315, tm_isdst=-1)
# #睡眠3秒
# time.sleep(3)
# #***********datetime模塊***************
# #取出當前時間,分別爲年 月 日 時 分 秒 毫秒
# from datetime import datetime
#
# t1 = datetime.now()
# print(t1.year, t1.month, t1.day)  #2019 11 15(int類型)
# print(t1.hour, t1.minute, t1.second, t1.microsecond)
# #創建指定時間,沒有制定的,默認爲0
# t2 = datetime(2019, 11, 11)  #2019-11-11 00:00:00
# print(t2)
# #返回制定格式字符串
# t1.strftime('%Y-%m-%d %H:%M:%S')  #'2019-11-08 10:41:34'
# #將制定字符串轉爲datetime對象
# t3 = datetime.strptime('2019-11-11 08:00:00', '%Y-%m-%d %H:%M:%S')  #2019-11-11 08:00:00
# print(t3)
# #計算時間差
# from datetime import datetime, timedelta
# t1 = datetime.now()
# days = timedelta(days=50, hours=1)
# t1 - days #50天1小時之前
# t1 + days #50天1小時之後
#****************異常處理**************
"""
-如果沒有異常處理,當程序運行遇到錯誤使,程序將崩潰,終止執行.
-異常處理就是檢測到發生的錯誤,並給出解決方案,使程序可以繼續運行.
"""
# try:
#     '有可能發生異常的語句'
# except ('異常1', '異常2'):
#     '發生異常時執行的代碼'
# except ('異常3', '異常3'):
#     '發生異常時執行的代碼'
# else:
#     '不發生異常才執行的代碼'
# finally:
#     '發不發生異常都要執行的代碼'
# #實例
# try:
#     n = int(input('number: '))
#     result = 100 / n
#     print(result)
#     print('Done')
# except ValueError: #值類型錯誤
#     print('Invalid input.')
# except  ZeroDivisionError:  #被除數不能爲0
#     print('Invalid input.')
# except KeyboardInterrupt:   #Ctrl + c 打斷程序
#     print('\nBye-bye')
# except EOFError: #Ctrl + d #真正什麼都不輸入
#     print('\nBye-bye')
#
# try:
#     n = int(input('number: '))
#     result = 100 / n
#     print(result)
#     print('Done')
# #將異常保存到變量e中
# except (ValueError, ZeroDivisionError) as echo:
#     print('Invalid input:', echo)
# except (KeyboardInterrupt,EOFError):
#     print('\nBye-bye')

"""主動觸發異常
-使用raise,觸發指定類型的異常
-使用assert,觸發斷言異常AssertionError
"""
#實例
def set_age(name, age):
    if not 0 < age < 120:
        raise ValueError('年齡超過範圍')
    print('%s is %d years old' % (name, age))

def set_age2(name, age):
    assert 0 < age < 120, '年齡超過範圍'
    print('%s is %d years old' % (name, age))


if __name__ == '__main__':
    set_age('牛老師', 20)
    #set_age2('牛老師', 200)

"""set_age
(csdnak) [root@room9pc01 untitled]# ./14.day.py 
Traceback (most recent call last):
  File "./14.day.py", line 669, in <module>
    set_age('牛老師', 200)
  File "./14.day.py", line 660, in set_age
    raise ValueError('年齡超過範圍')
ValueError: 年齡超過範圍
(csdnak) [root@room9pc01 untitled]# ./14.day.py 
牛老師 is 20 years old
"""
"""set_age2:
(csdnak) [root@room9pc01 untitled]# ./14.day.py 
Traceback (most recent call last):
  File "./14.day.py", line 670, in <module>
    set_age2('牛老師', 200)
  File "./14.day.py", line 664, in set_age2
    assert 0 < age < 120, '年齡超過範圍'
AssertionError: 年齡超過範圍
(nsd1906) [root@room9pc01 untitled]# ./14.day.py 
牛老師 is 20 years old
"""






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