別問我爲什麼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
"""