别问我为什么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
"""