zoukankan      html  css  js  c++  java
  • doc

      一、自定义创建模块

    在base目录下创建_modules目录,你自己编写的模块都可以存放在该目录下,当前目录结构下:
    1
    2
    3
    4
    5
    6
    7
    8
    [root@localhost:]# tree -L 3 salt
    salt
    ├── etc
    ├── _grains
    │   ├── dmp_scribe.py
    │   └── zabbix_conf.py
    ├── _modules
    │   └── ip.py

    通过上图可以看到已经创建了一个名为ip.py文件,看看相关内容:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    #!/usr/bin/env python
     
    import commands
     
    def eth1():
        ip={}
        cmd = "ifconfig eth1|grep inet|awk '{print $2}'|awk -F : '{print $2}'"
        ip2=commands.getoutput(cmd).strip()
        ip['ip']=ip2
        return ip

    定义模块我们没有在/srv/salt/top.sls文件中新增模块名,现在把写好的模块同步到你需要执行的机器上,可以全部同步,也可以针对性的同步

    这里只演示同步一台

    1
    2
    3
    salt '192.168.10.128' saltutil.sync_modules
    192.168.10.128:
        - modules.ip

    在master执行编写的模块,由于不依赖state.sls文件,所以执行时命令也有变化,在主要命令后面跟模块名●函数名

    1
    2
    3
    4
    5
    [root@localhost _modules]# salt '192.168.10.128' ip.eth1
    192.168.10.128:
        ----------
        ip:
            192.168.10.128

      二、屏幕返回值输出到指定的位置

    saltstack执行命令时默认的返回值都是打印在当前屏幕上的,如果一次执行多台机器,怎么查看这些记录,为了更方便的查看这些返回结果的信息,这就用到了salt的returners功能了。关于详细介绍请参考官网地址:http://docs.saltstack.cn/ref/returners/index.html?highlight=returners

    在/srv/salt目录下创建_returners目录,将自己编写的模块都可以存放在该目录下。

    1
    2
    3
    4
    5
    ├── _returners
    │   ├── local_return.py           #输出到文件
    │   ├── mysql_log.py              #输出到数据库
    │   ├── nohup.out
    │   ├── salt_event_to_mysql.py

     在_returners目录下创建了两个文件,一个是local_return.py:表示把执行结果存在在本地

                                                                    一个是mysql_log.py:表示把结果存放在mysql数据库中

        1、返回结果存放到本地

    1
    2
    3
    4
    5
    6
    7
    8
    #coding:utf-8
    def __virtual__():
       '''调用时的名字'''
       return "local_return"
    def returner(ret):
        f=open('/var/log/salt/local_returner.log','a+')
        f.write(str(ret)[1:-1]+' ')
        f.close()

    和自建模块一样,在编写完returners之后,也要同步到客户端的,同步的规则和自建模块一样。

    1
    salt '192.168.10.128'  saltutil.sync_returners

     在执行完上面的语句后,执行salt  ‘192.168.10.128’cmd.run 'uptime' --return local_return

     验证结果是否已经输出到文件中

       2、返回结果存放在mysql中

     官方默认returners中已经包含了mysql的returners,我们先直接利用官方原生的mysql returners,里面有创建相关表的语句。

     官方的mysql returners源码在https://github.com/saltstack/salt/blob/develop/salt/returners/mysql.py

     mysql服务器192.168.10.129:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    #在mysql服务器上创建表
    CREATE DATABASE  `salt`
          DEFAULT CHARACTER SET utf8
          DEFAULT COLLATE utf8_general_ci;
     
        USE `salt`;
     
        --
        -- Table structure for table `jids`
        --
     
        DROP TABLE IF EXISTS `jids`;
        CREATE TABLE `jids` (
          `jid` varchar(255) NOT NULL,
          `load` mediumtext NOT NULL,
          UNIQUE KEY `jid` (`jid`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
        --
        -- Table structure for table `salt_returns`
        --
     
        DROP TABLE IF EXISTS `salt_returns`;
        CREATE TABLE `salt_returns` (
          `fun` varchar(50) NOT NULL,
          `jid` varchar(255) NOT NULL,
          `return` mediumtext NOT NULL,
          `id` varchar(255) NOT NULL,
          `success` varchar(10) NOT NULL,
          `full_ret` mediumtext NOT NULL,
          `alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
          KEY `id` (`id`),
          KEY `jid` (`jid`),
          KEY `fun` (`fun`)
        ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    给相关salt表赋予访问权限:

    1
    GRANT ALL PRIVILEGES ON salt.* TO 'salt'@localhost IDENTIFIED BY 'saltt';
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    mysql> show databases;
    +--------------------+
    | Database           |
    +--------------------+
    | information_schema |
    | salt               |
    +--------------------+
    2 rows in set (0.00 sec)
     
    mysql> use salt
    mysql> show tables;
    +----------------------------+
    | Tables_in_salt             |
    +----------------------------+
    | jids                       |
    | salt_returners             |
    +----------------------------+

         因为要把客户端执行命令的结果直接返回给mysql服务器,所以客户端也要配置mysql信息的,我们以192.168.10.128为例,在salt的配置文件中加入如下信息,你也可以把它单独写在一个文件中。为了方便管理推荐写在单独文件中:

    1
    2
    3
    4
    5
    6
    #/etc/salt/minion.d/mysql.conf
    mysql.host: '192.168.1.204'
    mysql.user: 'salt'
    mysql.pass: 'salt'
    mysql.db: 'salt'
    mysql.port: 3306

    然后在master上执行命令,如下:

    1
    2
    salt   '192.168.10.128' cmd.run 'uptime' --return local_return
    salt   '192,168.10.128' cmd.run 'uptime' --return mysql

    注意这里用的是salt官网原生的mysql returners,并没有使用自己定义的mysql_log returners ,我们看看数据库中的记录:(图片是借鉴大神的图片)


     第一句是刚创建好表时的结果,可以看到数据库中已经有一条记录了,下面自己定义一个mysql_log returners来试试:

    1
    salt '192.168.10.128' cmd.run 'hostname' --return mysql_log

    我们来数据库中查看一下记录:


     下面附上定义的mysql_log.py:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    #/usr/bin/python
    #coding:utf-8
    from contextlib import contextmanager
    import sys
    import json
    import logging
     
     
    # Import third party libs
    try:
        import MySQLdb
        HAS_MYSQL = True
    except ImportError:
        HAS_MYSQL = False
     
    log = logging.getLogger(__name__)
     
     
    def __virtual__():
        if not HAS_MYSQL:
            return False
        return "mysql_log"
     
     
    def _get_options():
        '''
        Returns options used for the MySQL connection.
        '''
        defaults = {'host': '192.168.1.204',
                    'user': 'salt',
                    'pass': 'salt',
                    'db': 'salt',
                    'port': 3306}
        _options = {}
     
        # Ensure port is an int
        for attr in defaults:
            _attr = __salt__['config.option']('mysql.{0}'.format(attr))
            if not _attr:
                log.debug('Using default for MySQL {0}'.format(attr))
                _options[attr] = defaults[attr]
                continue
            _options[attr] = _attr
        return _options
     
    @contextmanager
    def _get_serv(commit=False):
        '''
        Return a mysql cursor
        '''
        _options = _get_options()
        conn = MySQLdb.connect(host=_options['host'], user=_options['user'], passwd=_options['pass'], db=_options['db'], port=_options['port'])
        cursor = conn.cursor()
        try:
            yield cursor
        except MySQLdb.DatabaseError as err:
            error, = err.args
            sys.stderr.write(str(error))
            cursor.execute("ROLLBACK")
            raise err
        else:
            if commit:
                cursor.execute("COMMIT")
            else:
                cursor.execute("ROLLBACK")
        finally:
            conn.close()
     
     
    def returner(ret):
        '''
        Return data to a mysql server
        '''
        with _get_serv(commit=True) as cur:
            sql = '''INSERT INTO `salt_returns`
                    (`fun`, `jid`, `return`, `id`, `success`, `full_ret` )
                    VALUES (%s, %s, %s, %s, %s, %s)'''
     
            cur.execute(sql, (ret['fun'], ret['jid'],
                                str(ret['return']), ret['id'],
                                ret['success'], json.dumps(ret)))

        三、基于Salt Event系统构建Master端returner

    上面我们介绍Saltstack的returner是由minion端主动连接returners完成执行结果的存储,在部分场景下并不能满足需求,由于salt底层已构建了一套Event系统,所有的操作均会产生event,因此基于Salt Event系统构建Master端returner成为一种可能。

    SaltStack Event 系统 官网地址:http://docs.saltstack.com/en/latest/topics/event/index.html

    SaltStack Event 系统监听events测试:http://pengyao.org/saltstack_event_system_listen_events.html

    环境说明:

    • 测试结构:Master/Minions结构

    • Salt Version:2015.8.8.2

    • 本次测试结果将存放在mysql中

    前置配置:

     安装Mysqldb依赖: yum -y install MySQL-Python

     配置本次测试需要使用的数据库及用户:

    1
    2
    3
    4
    5
    6
    # 创建salt数据库
    mysql -e 'create database salt'
    # 创建用于连接salt数据库的用户
    mysql -e '"grant all on salt.* to salt@localhost identified by "salt_pass';
    # 将数据库配置添加至master配置文件中
    echo -e " # MySQL mysql.host: 'localhost' mysql.user: 'salt' mysql.pass: 'salt_pass' mysql.db: 'salt' mysql.port: 3306" >> /etc/salt/master

    为了与salt自带的mysql returners兼容,本次直接使用mysql returners对应的数据库表结构:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    USE `salt`;
     
    --
    -- Table structure for table `jids`
    --
     
    DROP TABLE IF EXISTS `jids`;
    CREATE TABLE `jids` (
      `jid` varchar(255) NOT NULL,
      `load` mediumtext NOT NULL,
      UNIQUE KEY `jid` (`jid`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
     
    --
    -- Table structure for table `salt_returns`
    --
     
    DROP TABLE IF EXISTS `salt_returns`;
    CREATE TABLE `salt_returns` (
      `fun` varchar(50) NOT NULL,
      `jid` varchar(255) NOT NULL,
      `return` mediumtext NOT NULL,
      `id` varchar(255) NOT NULL,
      `success` varchar(10) NOT NULL,
      `full_ret` mediumtext NOT NULL,
      `alter_time` TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
      KEY `id` (`id`),
      KEY `jid` (`jid`),
      KEY `fun` (`fun`)
    ) ENGINE=InnoDB DEFAULT CHARSET=utf8;

    编写returners:salt_event_to_mysql.py

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    #!/bin/env python
    #coding=utf8
     
    # Import python libs
    import json
     
    # Import salt modules
    import salt.config
    import salt.utils.event
     
    # Import third party libs
    import MySQLdb
     
    __opts__ = salt.config.client_config('/etc/salt/master')
     
    # Create MySQL connect
    conn = MySQLdb.connect(host=__opts__['mysql.host'], user=__opts__['mysql.user'], passwd=__opts__['mysql.pass'], db=__opts__['mysql.db'], port=__opts__['mysql.port'])
    cursor = conn.cursor()
     
    # Listen Salt Master Event System
    event = salt.utils.event.MasterEvent(__opts__['sock_dir'])
    for eachevent in event.iter_events(full=True):
        ret = eachevent['data']
        if "salt/job/" in eachevent['tag']:
            # Return Event
            if ret.has_key('id') and ret.has_key('return'):
                # Igonre saltutil.find_job event
                if ret['fun'] == "saltutil.find_job":
                    continue
     
                sql = '''INSERT INTO `salt_returns`
                    (`fun`, `jid`, `return`, `id`, `success`, `full_ret` )
                    VALUES (%s, %s, %s, %s, %s, %s)'''
                cursor.execute(sql, (ret['fun'], ret['jid'],
                                     json.dumps(ret['return']), ret['id'],
                                     ret['success'], json.dumps(ret)))
                cursor.execute("COMMIT")
        # Other Event
        else:
            pass

    运行编写的returner:   Python salt_event_to_mysql.py

     

    ​测试:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    salt '*' test.ping     #开启一个终端,运行salt指令
     
    #输出为:
    salt-minion-01.example.com:
        True
     
    #检查mysql数据库,查询salt_returns表数据:
    mysql salt -e "select * from salt_returnsG"
     
    #输出为:
    *************************** 1. row ***************************
        fun: test.ping
        jid: 20140417161103569310
        return: true
        id: salt-minion-01.example.com
        success: 1
        full_ret: {"fun_args": [], "jid": "20140417161103569310", "return": true, "retcode": 0, "success": true, "cmd": "_return", "_stamp": "2014-04-17T16:11:03.584859", "fun": "test.ping", "id": "salt-minion-01.example.com"}
        alter_time: 2014-04-17 16:11:03
     
    #入库成功
  • 相关阅读:
    synchronized内置锁
    《JavaScript闯关记》视频版硬广
    想提高团队技术,来试试这个套路!
    从国企到阿里的面试经历(二)
    从国企到阿里的面试经历(一)
    《JavaScript 闯关记》之垃圾回收和内存管理
    《JavaScript 闯关记》之原型及原型链
    《JavaScript 闯关记》之作用域和闭包
    如何排版 微信公众号「代码块」之 MarkEditor
    《JavaScript 闯关记》之事件
  • 原文地址:https://www.cnblogs.com/phennry/p/5572969.html
Copyright © 2011-2022 走看看