day38综合架构批量管理篇

  • 批量管理服务配置应用

    • 续day37主机清单配置
    • 模块功能应用
    • 剧本功能配置

1.模块功能应用(续)

第四个模块:copy   文件模块:可以将管理端数据进行批量分发/可以移动调整被管理端数据位置
    重要模块参数:
    src:指定管理端要分发的数据路径信息
    dest:指定数据传输到被管理端什么目录中
    mode:数据传输完毕后,设置数据权限信息
    owner:数据传输完毕后,设置数据属主信息
    group:数据传输完毕后,设置数据属组信息
    backup:是否开启数据分发备份功能
    remote_src:指定源的路径信息,从被管理端进行读取
    content:可以直接不在管理端创建文件,对文件进行分发,并且可以编辑文件简单内容信息
    validate:
  模块参数用法一:
    ansible oldboy -m copy -a "src=/oldboy/oldboy.txt dest=/oldboy/ mode=600 owner=oldboy group=oldboy"
    说明:对文件进行分发
    1.修改文件权限信息和文件属主属组信息
    2.可以在被管理端创建指定目录信息

    ansible oldboy -m copy -a "src=/oldboy/ dest=/oldboy/"
    说明:对目录进行分发
    src指定目录后面有斜线 oldboy/ 表示对oldboy目录下所有数据进行传输
    src指定目录后面没有斜线 oldboy 表示对目录本身及目录下面数据进行传输
  模块参数用法二:备份/还原数据方法
    传输备份文件数据方法一:
    ansible oldboy -m copy -a "src=/oldboy/oldboy.txt dest=/oldboy/ backup=yes"
    传输备份文件数据方法二:
    ansible oldboy -m copy -a "src=/oldboy/oldboy.txt dest=/oldboy/oldboy.txt.bak remote_src=yes"
    还原数据
    ansible oldboy -m copy -a "src=/oldboy/oldboy.txt.bak dest=/oldboy/oldboy.txt remote_src=yes"
  remote_src参数说明:
  ansible oldboy -m copy -a "src=/oldboy/oldboy.txt dest=/opt/ remote_src=yes"
      == 相应被管理端  mv /oldboy/oldboy.txt  /opt/
    ansible oldboy -m copy -a "src=/oldboy/oldboy.txt dest=/opt/"
      == 相应管理端    scp -rp /oldboy/oldboy.txt  xx.xx.xx.xx:/opt/

第五个模块:fetch 文件模块:进行数据拉取操作
  重要参数:
    src:指定远程主机需要拉取数据信息
    dest:将数据保存到本地管理主机什么路径中

  拉取数据方法:
  ansible oldboy -m fetch -a "src=/oldboy/oldboy.txt dest=/oldgirl"
  拉取后数据信息:
  [root@m01 ~]#tree /oldgirl/
  /oldgirl/
  ├── 172.16.1.7
  │   └── oldboy
  │       └── oldboy.txt
  └── pob
      └── 01.txt

  3 directories, 2 files

第六个模块:file 文件模型:可以修改文件数据属性信息(直接修改数据属性)/创建或删除数据信息
  重要参数:
    path:指定要操作的远程主机数据路径信息
    mode:修改文件权限信息
    owner:修改文件属主信息
    group:修改文件属组信息
    state:状态参数信息
       创建目录(directory)
       创建文件(touch)
       创建软链接(link)
       创建硬链接(hard)
       删除文件(absent)
       查看文件是否存在(file)
  模块参数用法一:修改文件属性信息
    修改文件权限属性信息:
    ansible 172.16.1.41 -m file -a "path=/oldgirl/oldgirl.txt mode=666 owner=oldboy group=oldboy"
    修改目录权限属性信息:
    ansible 172.16.1.41 -m file -a "path=/oldboy/ mode=666 owner=oldgirl group=oldgirl"
      说明: 只是修改目录本身权限,不会进行递归修改权限信息(没有-R功能)
  模块参数用法二:创建或删除文件数据
    创建目录:
    ansible 172.16.1.41 -m file -a "path=/oldboy/ state=directory"
    创建文件:
    ansible 172.16.1.41 -m file -a "path=/oldboy/oldboy.txt state=touch"
    创建连接:
    ansible 172.16.1.41 -m file -a "src=/oldboy/oldboy.txt  path=/oldboy/oldboy_soft_link state=link"  --- 创建软链接 
    ansible 172.16.1.41 -m file -a "src=/oldboy/oldboy.txt  path=/oldboy/oldboy_hard_link state=hard"  --- 创建硬链接
    删除数据:
    ansible 172.16.1.41 -m file -a "path=/oldboy/oldboy.txt state=absent"
    检查普通文件是否存在:
    ansible 172.16.1.41 -m file -a "path=/etc/hosts state=file"

第七个模块:user 用户模块:创建或删除用户信息
  重要参数:
    name:指定创建用户名称信息
    create_name:创建用户是有有家目录
    shell:指定用户是否能够登陆系统(/sbin/nologin)
    uid:指定用户uid数值
    password:指定用户密码信息(使用密文信息设置密码)
    state:默认present表示创建用户 使用absent删除用户信息
   group:指定用户属于哪个用户组(主要组)
   groups:指定用户属于哪个用户组(附属组)
  模块参数用法一:创建用户
    ansible 172.16.1.41 -m user -a "name=rsync uid=2000 create_home=no shell=/sbin/nologin"  --- 创建虚拟用户  
    ansible 172.16.1.41 -m user -a "name=oldboy uid=2001"                                      --- 创建普通用户 
  模块参数用法二:给创建用户设置密码
    ansible 172.16.1.41 -m user -a 'name=oldboy password=$6$123456$yryajH2qY8ydGAcmwCNSmZM1/fI4gYqwTzXn9abB73ZmaDWJoe5s5Y.gOHgtBgqYrqRLB1Dsv6QTZsKsJbibJ1'
    ps:利用user模块创建密文密码信息
    方法一: 
      ansible all -i localhost, -m debug -a "msg={{ 'mypassword' | password_hash('sha512', 'mysecretsalt') }}"
      mypassword:   指定明文密码信息
      mysecretsalt: 密码加密方式
      生成密文密码
      [root@m01 ~]# ansible all -i localhost, -m debug -a "msg={{ 'oldboy123' | password_hash('sha512', '123456') }}"
      localhost | SUCCESS => {
          "msg": "$6$123456$yryajH2qY8ydGAcmwCNSmZM1/fI4gYqwTzXn9abB73ZmaDWJoe5s5Y.gOHgtBgqYrqRLB1Dsv6QTZsKsJbibJ1"
      }
      
    方法二: 利用python命令生成密文信息
      第一个历程: 安装pip下载工具
      yum install -y python-pip
      第二个历程: 利用pip工具下载python程序包
      pip install passlib
      第三个历程: 生成密文信息
      [root@m01 ~]# python -c "from passlib.hash import sha512_crypt; import getpass; print(sha512_crypt.using(rounds=5000).hash(getpass.getpass()))"
      Password: 
      $6$IQhh.egT4ow2dzmd$fk9W1.J4q1ArQ8nykkhh5A0waFbgU1Qa4sUdNm42.oYSpSMmIIl0262cSDg1Q6Ph8p3rnqHOs372A.GzD11.w/
  模块参数用法三:删除用户信息
    ansible 172.16.1.41 -m user -a 'name=oldboy state=absent' 
    ps:默认删除用户不会删除用户家目录
    [root@backup oldboy]# ll /home/oldboy -d
      drwx------ 2 2001 2001 83 Aug 23 11:33 /home/oldboy

第八个模块:group 用户模块:创建或删除用户组信息
  重要参数信息:
    name:指定创建用户组名称信息
    gid:指定创建用户组id编号信息
    state:默认present 指定absent表示删除用户
  模块参数用法一:创建指定用户组
    ansible 172.16.1.41 -m group -a "name=oldboy gid=3000"
  模块参数用法二:
    ansible 172.16.1.41 -m group -a "name=oldboy state=absent"

第九个模块:yum 安装软件模块:安装/卸载软件
  重要参数信息:
    name:指定需要安装软件名称
    state:指定状态信息
          安装软件(installed latest persent)
          卸载软件(absent removed)
  模块参数用法一:安装软件程序
    ansible 172.16.1.41 -m yum -a "name=telnet-server state=installed"
  模块参数用法二:卸载软件程序
    ansible 172.16.1.41 -m yum -a "name=telnet-server state=absent"
  
第十个模块:service 系统模块:控制服务运行状态
  重要参数:
    name:指定要管理的服务名称
    state:指定服务运行状态
          停止(stop)
          启动(started)
          重启(restarted)
          平滑重启(reloaded)
    enabled:指定服务是否开机自动启动(yes开机自启,no开机不运行)
  模块参数用法一:控制服务运行状态
    ansible 172.16.1.41 -m service -a "name=rsyncd state=started"
    ansible 172.16.1.41 -m service -a "name=rsyncd state=stopped"
    ansible 172.16.1.41 -m service -a "name=rsyncd state=restarted"
    ansible 172.16.1.41 -m service -a "name=rsyncd state=reloaded"
  模块参数用法二:设置服务开机运行状态:
    ansible 172.16.1.41 -m service -a "name=rsyncd enabled=no"
    ansible 172.16.1.41 -m service -a "name=rsyncd enabled=yes"

第十一个模块:cron 系统模块:批量设置定时任务
  重要参数信息:
    name:定义定时任务注释信息(避免出现重复的定时任务)
    minute   :  指定时间信息中分钟信息  (0-59 */5 0,10)
    hour     :  指定时间信息中小时信息  (0-23 *)
    day      :  指定时间信息中日期信息  (1-31)
    month    :  指定时间信息中月份信息  (1-12)
    weekday  :  指定时间信息中星期信息  (0-6)
    job      :  指定定时任务命令信息

    crontab -e
    * * * * * 执行定时任务&>/dev/null
  模块参数用法一:批量设置定时任务
    ansible 172.16.1.41 -m cron -a "name=crond-id-02 minute=*/5 job='ntpdate ntp1.aliyun.com &>/dev/null'"
    ps:job后面的命令注意用''扩起来
  模块参数用法二: 删除定时任务
    ansible 172.16.1.41 -m cron -a "name=crond-id-02 state=absent"
  模块参数用法三: 注释定时任务     
    ansible 172.16.1.41 -m cron -a "name=crond-id-01 minute=*/5 job='ntpdate ntp1.aliyun.com &>/dev/null' disabled=yes"
    ansible 172.16.1.41 -m cron -a "name=crond-id-01 minute=*/5 job='ntpdate ntp1.aliyun.com &>/dev/null' disabled=no"
  ps:注释定时任务时最好把时间信息的参数带上不然注释后任务时间信息会变成 * * * * *

第十二个模块:mount 系统模块:进行批量挂载操作
  重要参数信息:
    src:挂载存储设备信息
    path:挂载点目录信息
    fstype:挂载的文件系统类型
    state:指定挂载或卸载
           挂载:mounted persent
             mounted:临时挂载存储目录信息,永久也挂载了存储目录信息
             present: 只是实现永久挂载
           卸载: unmounted absent
             unmounted: 只是实现临时卸载
             absent:    临时实现卸载    永久也实现卸载操作
  参数操作方法一:进行挂载操作
    ansible 172.16.1.41 -m mount -a "src=172.16.1.31:/data path=/mnt fstype=nfs state=mounted"
    ansible 172.16.1.41 -m mount -a "src=172.16.1.31:/data path=/mnt fstype=nfs state=present"
  参数操作方法二:进行卸载操作
    ansible 172.16.1.41 -m mount -a "src=172.16.1.31:/data path=/mnt fstype=nfs state=unmounted"
    ansible 172.16.1.41 -m mount -a "src=172.16.1.31:/data path=/mnt fstype=nfs state=absent"

学习ansible执行命令时会有不同颜色提示
    01. 绿色: 对主机信息进行查看, 操作执行成功
    02. 黄色: 对主机信息进行查看, 对主机中信息有调整修改
    03. 紫色: 错误提示信息, 建议忠告信息
    04. 红色: 报错提示信息  

如何利用ansible模块进行rsync服务部署

第一个历程: 确认好管理主机信息
    管理服务端主机: 172.16.1.41 
    管理客户端主机: 172.16.1.31 172.16.1.7 
    
第二个历程: 配置主机清单信息
    vim /etc/ansible/hosts
    [rsync_server]
    172.16.1.41 
    [rsync_client]
    172.16.1.31
    172.16.1.7
    
第三个历程: 进行rsync服务部署 
    服务端:
    1) 安装软件
       ansible rsync_server -m yum -a "name=rsync state=installed"
    2) 编写配置文件
       ansible rsync_server -m copy -a "src=/ansible_file/rsync/rsyncd.conf  dest=/etc/"
    3) 创建虚拟用户 
       ansible rsync_server -m user -a "name=rsync create_home=no shell=/sbin/nologin"
    4) 创建密码文件并授权
       ansible rsync_server -m copy -a "content='rsync_backup:oldboy123' dest=/etc/rsync.password  mode=600"
    5) 创建备份目录并授权
       ansible rsync_server -m file -a "path=/backup/ state=directory owner=rsync group=rsync"
    6) 启动服务程序   
       ansible rsync_server -m service -a "name=rsyncd state=started enabled=yes"
        
    客户端:
    1) 创建密码文件 
       ansible rsync_client -m copy -a "content='oldboy123' dest=/etc/rsync.password mode=600"
    2) 进行传输测试 扩展研究:synchronize
       ansible rsync_client -m shell -a "rsync -avz /etc/hosts rsync_backup@172.16.1.41::backup --password-file=/etc/rsync.password"

剧本编写
剧本:将多个模块操作命令进行整合
  模块《====》命令
  剧本《====》脚本
剧本作用说明:
  01.可以实现服务自动部署
  02.可以提高运维工作效率
  03.可以减少运维工作问题
  04.可以节省公司运维成本
剧本编写组成:
  01.剧本角色信息:hosts:主机信息
  02.剧本任务信息:tasks:任务信息
剧本编写规范:遵循yaml语法规范(Python代码语法规范)

01.缩进规范:两个空格表示一个缩进关系
标题一
  标题二          
    标题三
 PS: 在缩进时只能用空格表示缩进,不能用tab键代替缩进
02.字典规范: 冒号后面要有空格
    oldboy: 123456  key: value
 PS: 冒号结尾时不需要有空格/冒号信息出现在注释说明中不需要有空格
03.列表规范: 横线后面要有空格
name:
  - rsync 
  - nfs 
  - rpcbind 

编写测试剧本:

[root@m01 ansible_playbook]# cat /ansible_playbook/test01.yml 
       - hosts: rsync_server
         tasks:
           - name: create user:alex
             user: name=alex uid=3000
           - name: install software:iftop
             yum: name=iftop state=installed
       
       - hosts: rsync_client
         tasks:
           - name: create user:alex
             user: name=alex uid=3000
    
       剧本测试执行方法:
       1) 进行剧本编写检查测试
          ansible-playbook --syntax-check /ansible_playbook/test01.yml
       2) 剧本运行方式
          模拟执行:
          ansible-playbook -C test01.yml
          真实执行:
          ansible-playbook -C test01.yml
如果安装cowsay执行会出小牛图像:
补充: 取消cowsay小牛图案出现
          vim /etc/ansible/ansible.cfg   --- 编写修改ansible配置文件
          217 # set to 1 if you don't want cowsay support or export ANSIBLE_NOCOWS=1
          218 nocows = 1    --- 禁止调取远程主机cowsay程序

编写剧本完成nfs一键自动部署:
第一个历程: 定义主机清单信息
[nfs_server]
172.16.1.31
[nfs_client]
172.16.1.41
172.16.1.7

第二个历程: 编写剧本信息
服务端:
  1) 安装软件程序
  2) 编写配置文件
  3) 创建存储目录
  4) 启动服务程序

客户端:
  1) 安装软件程序
  2) 进行挂载操作

剧本编写方法:
  01: 采用变量格式编写剧本
  02: 采用字典格式编写剧本
  03: 采用json语法格式编写剧本

剧本信息:方法一:变量格式编写剧本
- hosts: nfs_server
  tasks:
    - name: 01:install software
      yum: name=nfs-utils state=installed
      yum: name=rpcbind   state=installed
    - name: 02:push conf_file to server
       copy: src=./nfs/exports dest=/etc/
    - name: 03:create data dir
       file: path=/data  state=directory owner=nfsnobody group=nfsnobody
    - name: 04:boot server
       service: name=rpcbind state=started enabled=yes
       service: name=nfs state=started enabled=yes
      
- hosts: nfs_client
  tasks:
    - name: 01:install software
      yum: name=nfs-utils state=installed
    - name: 02:mount data dir
      shell: mount -t nfs 172.16.1.31:/data /mnt

剧本信息: 方法二 字典格式编写剧本  
       - hosts: nfs_server
         tasks:
           - name: 01:install software
             yum:
               name:
                 - nfs-utils 
                 - rpcbind
               state: installed
           - name: 02:push conf_file to server
             copy:
               src: ./nfs/exports
               dest: /etc/
           - name: 03:create data dir
             file:
               path: /data
               state: directory
               owner: nfsnobody
               group: nfsnobody
           - name: 04:boot server rpc
             service:
               name: rpcbind
               state: started
               enabled: yes
           - name: 05:boot server nfs
             service:
               name: nfs
               state: started
               enabled: yes

       - hosts: nfs_client
         tasks:
           - name: 01:install software
             yum:
               name: nfs-utils
               state: installed
           - name: 02:mount data dir
             shell: mount -t nfs 172.16.1.31:/data /mnt 

剧本编写扩展功能
a.在剧本中设置变量信息
b 在剧本中设置注册信息
c 在剧本中设置判断信息
d 在剧本中设置循环信息
e 在剧本中设置错误忽略
f 在剧本中设置标签信息
g 在剧本中设置触发信息

a.在剧本中设置变量信息

设置变量方法一: 在剧本中设置变量 
    - hosts: 172.16.1.41
      vars:
        data_dir: /oldboy
      tasks:
        - name: copy file 01
          copy: src={{ data_dir }}/oldboy01.txt  dest=/tmp
        - name: copy file 02
          copy: src={{ data_dir }}/oldboy02.txt  dest=/opt
        - name: copy file 03
          copy: src={{ data_dir }}/oldboy03.txt  dest=/usr/local/
    
设置变量方法二: 在命令中设置变量
    ansible-playbook -e data_dir=/oldboy test_变量配置功能.yml
    
设置变量方法三: 在主机清单中设置
    a: 单个主机设置变量
    172.16.1.41 data_dir=/oldboy
    
    b: 多个主机设置变量
    [oldboy]
    172.16.1.41
    [oldboy:vars]
    data_dir=/oldboy
三种变量设置方式, 之间优先级关系
创建环境:
    mkdir /oldboy/ -p
    mkdir /oldgirl/ -p 
    mkdir /olddog/ -p
    结论:
    命令配置变量  最优先
    剧本配置变量  其次优先
    主机清单配置  最后选择    

b 在剧本中设置注册信息

[root@m01 ansible_playbook]# cat test_注册功能配置.yml 
    - hosts: nfs_client
      tasks:
        - name: mount dir
          mount: src=172.16.1.31:/data path=/mnt fstype=nfs state=mounted
        - name: check mount
          shell: df -h
          register: oldboy
        - name: display mount info
          debug: msg={{ oldboy.stdout_lines }}

c 在剧本中设置判断信息

常见主机信息:
      ansible_all_ipv4_addresses:               仅显示ipv4的信息。
      ansible_devices:                          仅显示磁盘设备信息。
      ansible_distribution:                 显示是什么系统,例:centos,suse等。
      ansible_distribution_major_version:       显示是系统主版本。
      ansible_distribution_version:         仅显示系统版本。
      ansible_machine:                          显示系统类型,例:32位,还是64位。
      ansible_eth0:                         仅显示eth0的信息。
      ansible_hostname:                     仅显示主机名。
      ansible_kernel:                           仅显示内核版本。
      ansible_lvm:                              显示lvm相关信息。
      ansible_memtotal_mb:                      显示系统总内存。
      ansible_memfree_mb:                       显示可用系统内存。
      ansible_memory_mb:                        详细显示内存情况。
      ansible_swaptotal_mb:                 显示总的swap内存。
      ansible_swapfree_mb:                      显示swap内存的可用内存。
      ansible_mounts:                           显示系统磁盘挂载情况。
      ansible_processor:                        显示cpu个数(具体显示每个cpu的型号)。
      ansible_processor_vcpus:                  显示cpu个数(只显示总的个数)。   

只要主机名信息:
- hosts: all
        tasks:
          - name: install software
            yum: name=nfs-utils state=installed
          - name: create data dir
            file: path=/data/ state=directory
            when: (ansible_hostname == "nfs01")   
            
      判断语法结构信息:
      01. 匹配单个信息:
      when: (ansible_hostname == "nfs01")
      
      02. 匹配多个信息 ???
      when: (ansible_hostname == "nfs01") or  (ansible_hostname == "backup") 
      when: (ansible_hostname == "nfs01") and (ansible_eth0 == "10.0.0.31")
      
      03. 对匹配信息进行取反
      when: (ansible_hostname != "nfs01")
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,456评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,370评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,337评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,583评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,596评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,572评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,936评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,595评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,850评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,601评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,685评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,371评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,951评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,934评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,167评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,636评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,411评论 2 342

推荐阅读更多精彩内容