[saltstack]常用命令和函数-迁

命令行

帮助

# 查看相关函数
sys.list_functions cmd
    - cmd.exec_code
    - cmd.has_exec
    - cmd.retcode
    - cmd.run​

# 查看所有module列表
sys.list_modules
    - aliases
    - apache
    - at
    - blockdev​

# 查看使用方法 
sys.doc cmd​

# 查看states 支持的模块列表
sys.list_state_modules​

# states 支持的函数列表
sys.list_state_functions file​

# states 支持的函数用法
sys.state_doc file.managed 

  

匹配规则

#匹配nodegroup
salt -N group1​

#minions列表匹配
salt -L 'platapp2,platapp1'​

#匹配正则表达式
salt -E 'nljkapp[1-3]'


#IP地址匹配[192.168.1.0/24],貌似只能用 /16 /24 之类的段
salt -S '172.23.4.57'
salt -S '192.168.100.0/24'​

#复合匹配: compound matchers 
salt -C 'P@max_open_file:[0-9]{4}$ and S@192.168.100.0/24' ​

# 复合匹配在nodegroup中的写法
phy_linux: '* and not E@KQ-* and G@virtual:physical'​

# 在指定数量或百分比的机器上执行命令。
salt \* -b 10 test.ping   # 每次执行10%
salt -G 'os:RedHat' --batch-size 25% apache.signal restart​

第一条命令在所有的客户端上执行test.ping,但同一时间只有10台机器运行此命令,
当有minion返回执行结果是,再让下一个minion执行。 第二条命令在系统是RedHat的客户端中重启apache服务,
但同一时间只有25%的机器执行重启,直到所有目标机器执行完成。
Batch Size并不减少总的数量,只是限制同时执行任务的机器数量。这非常有用,
比如,在负载均衡web集群中,可以只用一条命令分批的重启web服务。

#匹配 grains定义值 ,正则 grains :P, Grains PCRE
salt -G 'osrelease:6*'​

#匹配pillar定义的值
salt -I 'flow:maxconn:30000'

# 需要先在/etc/pillar/top.sls 中定义范围:
cat /srv/pillar/top.sls 
 base:
 'webcall':
 - match: nodegroup
 - data​
# 结合pillar和nodegroup 会比较灵活
# 注意下 match,不要直接写 'N@webcall' 

  

全局命令

# 列出详细输出,当Minions运行命令超时无返回结果时会显示"Minion did not return"
salt -v 'vnljkapp2' test.ping --out=json

# 更多的 salt例子可以使用以下命令查看:
salt '*' sys.doc | grep "salt '*'" 

#把文件传输到服务器上去(但是注意只能传文件)
salt-cp 'KQ-172.23.4.219' win.bat D:/
salt-cp -N lvs /var/www/html/soft/lvs/install_lvs.sh /tmp/install_lvs.sh

  

salt-ssh 

/etc/salt/roster
 192.168.21.4:
 host: 192.168.21.4
 user: root
 password: redhat​

  

salt-ssh 192.168.21.1 --roster-file /etc/salt/roster -r 'uptime' 
 192.168.21.1:
 ----------
 retcode:
 0
 stderr:
 stdout:
 10:35:04 up 19:50, 0 users, load average: 0.12, 0.10, 0.06​

  

可以不装客户端 或者装不上的情况,用这个方式

 salt-ssh -L "192.100.2.2" -r "/root/salt_tomcatManager.sh /usr/local/tomcatawo status"

-i 默认全部接收auth key,貌似是用auth key 来做互信的

salt-ssh '*' -i --roster-file /etc/salt/roster -r 'uptime' 

  

#打印出日志来,看到是一个很复杂的ssh命令

salt-ssh -i 172.23.4.80 --roster-file /etc/salt/roster -r 'uptime' -l all mylog
 [DEBUG ] Executing command: ssh 172.23.4.80 -o KbdInteractiveAuthentication=no -o GSSAPIAuthentication=no -o PasswordAuthentication=no -o ConnectTimeout=75 -o StrictHostKeyChecking=no -o Port=22 -o IdentityFile=/etc/salt/p​ki/master/ssh/salt-ssh.rsa -o User=root 'uptime mylog'

  
通过把 /etc/salt/pki/master/ssh/salt-ssh.rsa.pub 手动烤过去,authorized_keys

文档:
https://docs.saltstack.com/en/latest/topics/ssh/

问题:

{'_error': 'Failed to return clean data'} 
salt.client.ssh.wrapper.FunctionWrapper(

  

 salt-ssh ‘test85′ -key-deploy test.ping​

  

当调用master模块时,并加上参数 –key-deploy 即可在minions生成keys,下次开始就不使用密码

This – let's call it a workaround – "fixes" the issue. The main disadvantage is, that it breaks current configuration.

--- ./returners/mysql.py.orig   2017-02-23 00:32:57.628630209 +0100
+++ ./returners/mysql.py        2017-02-23 00:33:03.173848441 +0100
@@ -178,7 +178,7 @@
     Returns options used for the MySQL connection.
     '''
     defaults = {'host': 'salt',
-                'user': 'salt',
+                'dbuser': 'salt',
                 'pass': 'salt',
                 'db': 'salt',
                 'port': 3306,
@@ -187,7 +187,7 @@
                 'ssl_key': None}

     attrs = {'host': 'host',
-             'user': 'user',
+             'user': 'dbuser',
              'pass': 'pass',
              'db': 'db',
              'port': 'port',
# master.d/mysql.conf
master_job_cache: mysql
event_return: mysql

mysql.host: '192.168.255.1'
#mysql.user: 'salt-master'
mysql.dbuser: 'salt-master'
mysql.pass: 'mypassword'
mysql.db: 'salt'
mysql.port: 3306

  

salt-run

salt-run 只能在master上使用!

这个runners就是给salt-run 命令写的 你如果写了一个 runners 脚本名字叫cpis.py 里面在定义几个函数
这个时候 你就可以直接运行salt-run cpis.某个函数名称 就能实现 脚本内函数的功能

官方提供的一些模块,作为一些自定义的模块功能,作为扩展,其实ConfigManage 也可以写成runner
https://github.com/saltstack/salt/tree/develop/salt/runners

比如 控制dns network fileserver等等服务,以后可以钻研一下!

先设定 /etc/salt/master
runner_dirs: ['/src/salt/_runner']
重启服务
mkdir -p /src/salt/_runner ; cd /src/salt/_runner

#可以查询在线的服务器
salt-run manage.status / salt-run manage.down / salt-run manage.up
down:
- vapp1
up:
- IMHDCL
- NEWDB1
....

#查询未完成的jobs
salt-run jobs.lookup_jid 20150311110102979290
salt-run manage.up                 查看存活的minion
salt-run manage.down            查看死掉的minion
salt-run manage.down removekeys=True    查看down掉的minion,并将其删除
salt-run manage.status            查看minion的相关状态
salt-run manage.versions        查看slat的所有master和minion的版本信息

 

salt-call

salt-call 是客户端(minion)自我调用时用到的命令,注意: 使用时还是会连接master,加上--local后就可以without master了

 本地测试 stat 是否正确

salt-call  state.sls logstash.test saltenv='prod'
local:
----------
          ID: envtest
    Function: cmd.run
        Name: echo '[prod]' env
      Result: True
     Comment: Command "echo '[prod]' env" run

  

window

直接下载安装版本,修改salt-master ID keepalive

#查询在线用户
salt 'KQ-172.23.4.219' cmd.run 'query user'

#重启系统
salt 'KQ-172.23.4.219' system.reboot 

  

#管理用户 
salt 'WIN_IP' user.add ADD_USER_NAME PASSWORD
salt 'WIN_IP' user.setpassword ADD_USER_NAME PASSWORD
salt 'WIN_IP' user.delete USER_NAME
salt 'WIN_IP' user.list_users
salt 'WIN_IP' user.addgroup ADD_USER_NAME Administrators
salt 'WIN_IP' group.info administrators


# 使用win自带命令
salt 'KQ-172.23.4.219' cmd.run 'net user'
KQ-172.23.4.219:
User accounts for \\
-------------------------------------------------------------------------------
Administrator ecp Guest 
huhk huli lilian 
linxw tanxg wangc 
wangxj xiaoxm xud 
yangxj yingl zhangjm 
zhongsh 
The command completed with one or more errors.


# salt 'KQ-172.23.4.219' user.delete 'xud'
KQ-172.23.4.219:
True


# salt 'KQ-172.23.4.219' cmd.run 'net user zgt DLwfg8 /add' 
KQ-172.23.4.219:
The command completed successfully.

#修改用户密码
salt 'TEST-192.168.38.224' cmd.run 'net user wuhh J4pZ0w'
#查询账号密码 规则
'net accounts'

#将zgt添加到 Remote Desktop Users 内
'net localgroup "Remote Desktop Users" zgt /add' 

#将zgt从 组中删去
'net localgroup "Remote Desktop Users" zgt /del'

#zgt 提升为admin组
'net localgroup "Administrators" zgt /add'

  

模块

grains

# 查看grains分类
salt '*' grains.ls 

# 查看 grains所有信息
salt '*' grains.items 

# 查看 grains某个信息
salt '*' grains.item osrelease 
salt -N group1 grains.item osrelease
 platapp6:
 osrelease: 6.4​

# 匹配6.*的系统版本
salt -G 'osrelease:6*' cmd.run 'ls /etc/yum.repos.d/' 

# 查询cpu
salt -L 'platapp2' grains.item cpu_model
platapp2:
     cpu_model: Intel(R) Xeon(R) CPU E7- 4807 @ 1.87GHz​

# 查ip地址的方式
salt 'website1' grains.item fqdn_ip4​

  

用正则的方式,来实现<10000,--grain-pcre用正则表达式

salt --grain-pcre 'max_open_file:[0-9]{4}$' grains.item id max_open_file runas='ecp'
ommoniter:
    id: ommoniter
    max_open_file: 1024
testit:
    id: testit
    max_open_file: 1024​

  

 grains目录优先级 

grains可以保持在minion端、通过master端下发等多个方式来分发。但不同的方法有不同的优先级的:
1. /etc/salt/grains  # minion端
2. /etc/salt/minion  # minion端
3. /srv/salt/_grains/  # master端_grains目录下 

通过master下发的grains优先级是最高的可,/etc/salt/minion次之,/etc/salt/grains最低

minion上的目录
 /var/cache/salt/minion/extmods/grains
 /var/cache/salt/minion/files/base/_grains/

  

自定义grains的下发

saltutil.clear_cache 清理缓存
saltutil.sync_grains 下发 本地grains配置
saltutil.sync_all 批量下发master配置的grains pillar return等
切记所有在_grains目录下的所有自定义grains值都会下发到minion,这是“血”的教训。
-- 如果脚本错误,会引起minion无法启动!(minion启动先检测一遍脚本)

 

可以放一些不改变配置的脚本,如果有设置的脚本,需要用固定放在Minion端的配置文件中可以通过file manager
的方法去批量

1. 通过state.highstate 下发的grains好处是无须重启minion即可生效,但通过下发/etc/salt/grains文件下发的grains值则必须重启minion端服务才可以生效。
2. 自定义的_grains每次在highstate调用的时候就会自动下发、刷新,而/etc/salt/grains文件的则不会。

现在在master里面设置好 file_roots ,新建一个_grains 文件夹,然后编写脚本
将 /srv/salt/_grains 中的文件直接同步到minion中

/var/cache/salt/minion/files/base/_grains
/var/cache/salt/minion/extmods/grains​

  注意: salt-ssh 中也会同步到,位置在/tmp目录下

举个栗子:

salt/_grains/abc.py
import sys
def abc():
      return {'abc': '00000000000000000'}

  

salt "50bb1d42d8f869501d9f5c2f4430060f" grains.item abc
50bb1d42d8f869501d9f5c2f4430060f:
    ----------
    abc:
        00000000000000000

  

salt 'website1' grains.item nets
website1:
nets: 192.168.100.122
work_dir: /usr/local
work_disk_per: 37.01 %
work_disk_size: 19.84 G

  

通过grains模块定义grains

salt 'ywjk' grains.append saltbool 'verycool'

saltbool 将写在minion端的 /etc/salt/grains 里面,如果有重复的item将会替换成新的


可以使用grains.setvals 设置更多的grains

salt 'ywjk' grains.setvals "{'salt':'good','saltbool':'True'}"

  

跟pillar比的对比

1.grains存储的是静态、不常变化的内容,pillar则相反
2.grains是存储在minion本地,而pillar存储在master本地
3.minion有权限操作自己的grains值,如增加、删除,但minion只能查看自己的pillar,无权修改

 

pillar

就是将一些指定的配置,通过pillar设置到对应的服务器上,这样做的好处就是我可以指定服务器执行及带入我设置的变量
说白了就是根据不同的服务器来配置,这个配置是放在服务端的,可是这样nodegroup确实鸡肋了

设置 pillar_roots:
设置 pillar_opts: True
saltutil.refresh_pillar 同步到minion上去(貌似有自动同步的机制,只要配置上去,就直接在master查到)

  

# 提取pillar数据
salt 'website1' pillar.data flow​

# 指定pillar选择器
salt -I 'flow:maxconn:30000'

  

pillar.item和pillar.get的不同
get 会把相关的都搜索出来

比如提取 master上配置

salt website1 pillar.get master:nodegroups

item 只匹配

 

多环境pillarenv和saltenv

pillar_roots:
  base:
    - /srv/pillar/base
  live:
    - /srv/pillar/live


# 执行
salt-call  state.sls logstash.test saltenv='base'  pillarenv='live'
local:
----------
          ID: envtest
    Function: cmd.run
        Name: echo 'pillar [live]' base env
      Result: True
     Comment: Command "echo 'pillar [live]' base env" run
     Started: 14:43:27.608350
    Duration: 5.733 ms
     Changes:   
              ----------
              pid:
                  31256
              retcode:
                  0
              stderr:
              stdout:
                  pillar [live] base env

Summary for local
------------
Succeeded: 1 (changed=1)
Failed:    0
------------
Total states run:     1
Total run time:   5.733 ms

 

schedule

文档

schedule 是配置在master上的

cat /srv/pillar/top.sls 
base:
 'webcall':
   - match: nodegroup
   - data
 'mykvm1':
   - schedule​

  

举例1

cat schedule.sls 
schedule: 
  #自动执行highstate
  highstate:
  function: state.highstate
  minutes: 10​

  

举例2

schedule:
  zabbix-agent-monitor:
    function: state.sls
    minutes: 10
    args:
      - base.init.zabbix.service 
    kwargs:
      stateful: True
      pillarenv: dev
  
  auto-clean-log:
    functioin: cmd.script
    source: salt://script/auto_clean.sh
    statefull: False
    shell: /bin/bash
    minutes: 10

  

执行任务

testcase:
    function: cmd.run
    seconds: 5
    args:
        - 'echo 1>> /tmp/test.cmd.log'
    kwargs:
    stateful: False
    shell: /bin/bash -- 不要写True之类的bool值

  

# 创建完文件之后执行下面的命令把pillar的修改刷到minion端去,_returner也会传到客户端

salt '*' saltutil.refresh_pillar​

  

# 想查看minion端都有哪些计划任务可以用

salt gotonecore-98-9 pillar.item schedule(在schedule.sls下的函数)​

  

#所有schedule全部enable/disable
schedule.enable/disable​

# 针对job进行 enable/disable
schedule.enable_job/disable_job testcase​

# 删除job
schedule.delete job_name
schedule.purge ​== 删除所有job

# 获取minion端的schedule信息
salt 'message-1-1' schedule.list show_all=True
pillar.get schedule​

# 获取minion端的schedule信息 -- master本地的
salt '*' config.option schedule​

  

salt 'mongodb-1-1' config.option schedule

mongodb-1-1:
    ----------
    __mine_interval:
        ----------
        enabled:
            True
        function:
            mine.update
        jid_include:
            True
        maxrunning:
            2
        minutes:
            60
        name:
            __mine_interval
        return_job:
            False
    om-agent-monitor:
        ----------
        args:
            - base.init.om_monitor_agent.install
        function:
            state.sls
        jid_include:
            True
        kwargs:
            ----------
            stateful:
                True
        maxrunning:
            1
        minutes:
            10
        name:
            om-agent-monitor

  

cron

本身会在minion上创建一条crontab任务

cron.present:
    - name: /root/PatrolAgent.sh 
    - identifier: PatrolAgent_monitor
    - comment: salt_PatrolAgent_monitor
    - user: root
    - minute: 5 // 每小时 05 分的时候执行
    - require:
        - file: PatrolAgent
    - onlyif: test -f /root/PatrolAgent.sh​

  

salt 'website1' cron.list_tab root 
pre:  //说明是在# Lines 这句comment下面的
 - 05 0 * * 1 /usr/sbin/logrotate -f /etc/logrotate.d/f​

  

添加,注意后面加上'',不加参数错误,加了其他内容不能remove

salt 'website1' cron.set_job root '*/10' '*' '*' '*' '*' '/usr/sbin/ntpdate 134.98.5.80' ''​

  

删除

salt 'sjkr14' cron.rm_job root '/usr/sbin/ntpdate -s 210.72.145.44'​

  


注意需要添加 # Lines below here are managed by Salt, do not edit 不然只能加不能删

salt '*' cmd.run 'sed -i "1 i # Lines below here are managed by Salt, do not edit" /var/spool/cron/root'
salt '*' cmd.run 'ps -ef|grep ./agent_mobilelocalxd|grep -v grep|awk "{print \$2}"|xargs kill -9'
salt '*' cmd.run 'ps -ef|grep java|grep target|grep -v grep|awk "{print \"cat /proc/\"\$2\"/oom_score\"}"'​ # 带变量的awk
salt-ssh -L pointcore-1-6,pointcore-1-5,dns-1-1,bops-1-1,pointcore-1-7,pointcore-1-8 -i -r "ps -ef|grep salt|grep python|awk '{print \$2}'|xargs sudo kill -9"  

  

sysctl

vm.overcommit_memory:
 sysctl.present:
 - value: 1​

  

service

# 检查是否在chkconfig 启动列表
salt '*' service.available sshd ​

# 获取所有
salt '*' service.get_all​

# Disable the named service to start at boot
service.disable​

# Check to see if the named service is disabled to start on boot
service.disabled

# Enable the named service to start at boot
service.enable​

# Check to see if the named service is enabled to start on boot
service.enabled​

#管理服务
salt '*' service.restart/status/start/stop <service name>​

# cat httpd.sls
apache:
    service:
        - name: httpd
        - running
        - reload: True
        - watch:
            - file: /etc/httpd/conf/httpd.conf
/etc/httpd/conf/httpd.conf:
    file:
        - managed
        - source: salt://httpd/httpd.conf
        - backup: minion​


客户端的备份目录:
/var/cache/salt/minion/file_backup/usr/local/yixinb_tomcat/webapps/ROOT/common/js

  

cmd

exec_code

salt 'server' cmd.exec_code bash 'if [ -f "/tmp/lixc" ];then echo yes;else echo no;fi'
salt-minion:
    no​

  

cmd.script

salt -N website cmd.script salt://MyScript.sh args='-o' 
 要把绝对路径写进去
salt 'nljkapp1' cmd.script salt://script/salt_tomcatManager.sh args='/home/ecp/tomcatzgt start' runas='ecp' shell='/bin/bash'
 可以支持runas 的有cmd.retcode (执行shell命令返回状态码), cmd.run(执行命令,输出), cmd.run_all(执行命令,结果以字典的形式返回,包含状态码及返回结果)
salt -N 'website' cmd.script salt://script/salt_tomcatDeploy.sh args='/usr/local/yixinb_tomcat /home/ecp/yixin-guan.war' runas='ecp' shell='/bin/bash' ​

  

cmd.run_stderr(执行命令,返回标准错误输出)
cmd.run_stdout(执行命令,返回标准输出), 
cmd.script(从远端下载脚本,然后本地运行), 
cmd.script_retcode(从远端下载脚本,然后本地运行,返回状态码
salt -N 'website' cp.get_file salt://file/website/yixin-guan.war /home/ecp/yixin-guan.war

   

salt newtxl1 cmd.run 'sh /etc/salt/check_salt.sh 1>/dev/null 2>/dev/null &'   

salt "walle-1-1" cmd.run  'sed -i "s/1-1.yum/yum.ops.net/" `ls /etc/yum.repos.d/*`'

salt 'gotonecore-1-1' cmd.run template=jinja 'sed -i "/^id:/c id: live-{{grains.id}}" /etc/salt/minion'

# 带变量表达式的命令写法
salt '*' cmd.run 'sed -i "s/^#tcp_keepalive/tcp_keepalive/" /etc/salt/minion'

salt -N oradb cmd.run 'multipath -l|awk "{x++}END{if(x>1)print a,\": exist multipath\"}" a=`hostname`'

   

return 储存接口

return 接口只能加在minion端,用于异步返回
sys.list_returners
- carbon
- couchdb
- etcd
- hipchat
- local
- local_cache
- multi_returner
- mysql
- slack
- smtp
- sqlite3
- syslog

salt-call test.ping --return redis_pub

  

https://docs.saltstack.com/en/latest/ref/returners/

salt/_returners/redis_pub.py

# -*- coding: utf-8 -*-

import salt.utils.json
import time

try:
    import redis
    HAS_REDIS = True
except ImportError:
    HAS_REDIS = False

__virtualname__ = 'redis_pub'

def __virtual__():
    if not HAS_REDIS:
        return (False, "Please install the redis package.")
    return __virtualname__

def returner(ret):
    '''
    Return data to redis
    '''
    retry = 3
    r = redis.Redis(host='salt-redis.xxxxxx.cn', port=16379, db=0, password='xxxxxxxxxxxx')

    pipeline = r.pipeline(transaction=False)
    minion, jid = ret['id'], ret['jid']
    pipeline.hset('ret:{0}'.format(jid), minion, salt.utils.json.dumps(ret))
    pipeline.expire('ret:{0}'.format(jid), 86400)
    pipeline.execute()

    sub_num = r.publish('ret:' + ret['jid'], salt.utils.json.dumps(ret))
    while sub_num == 0 and retry > 0:
        retry -= 1
        time.sleep(1)
        sub_num = r.publish('ret:' + ret['jid'], salt.utils.json.dumps(ret))

 

其他

# 查询磁盘使用情况
disk.usage

# 删除用户
user.delete 

# 用户操作 在windows下不行,用net命令解决
user.add 
user.list_users
user.list_groups

# 修改密码
还是用 echo xxx|passwd zgt --stdin

# 将文件从master传输到minion
salt 'jkcj' cp.cache_file salt://zgt

# 将文件从master传输到minion并改名
salt 'jkcj' cp.get_file salt://zgt /tmp/123


#将minion文件 传输到master,注意打开recv_file
cp.push /etc/passwd
/var/cache/salt/master/minions/files/jkcj/files/etc/passwd -- master端

#将monitor_agent目录推送到服务器/usr/local目录
cp.get_dir salt://monitor_agent '/usr/local'

#修改文件属性
file.chown /tmp/123 ecp ecp 

#修改文件属性 chmod
file.set_mode /etc/passwd 0644

# 命令行创建超链接
file.symlink /usr/log_bak /home/ecp/logs/log_bak 

# 查询版本
pkg.version vim-common

# 软件安装
pkg.install ntp 

#安装多个文件
pkg.install "gettext gettext-devel libXft libXft-devel libXpm libXpm-devel autoconf "

  

#启动一个定时任务--实用
salt 'website1' at.at 'now + 1 minutes' '/etc/init.d/salt-minion restart'

   

state.sls

语法

使用state的优势在于可以写执行脚本,注意top.sls文件里面
如果用了 '*' ,执行 salt '*' state.highstate 那就全执行了一遍,如果有危险操作请注意

cat top.sls
base: 
'*': --- 这里可以写一些基础的设置和配置
- mypkg
- one # 引用one.sls 或者 one/init.sls states文件
- update_zmq.update
- update_zmq.at
'platapp1': -- 这里可以设置服务器分类,比如应用、数据库、redis、测试等等类别
- appplat.nginx
'platapp2':
- appplat.nginx

'website[1-3]':
- website.b_yixin_im


# 命令行执行
salt -E 'nljkapp[1-3]' state.sls update_zmq.update

#将所有的执行命令都下发下去
salt '*' state.sls mypkg

  

top.sls文件
创建一个 top.sls文件,这个也是入口文件,也就是说,你执行相关命令的时候,会先检测
这个文件,这文件提供了其它文件的映射,可以用于作为其它服务器的基础配置文件。 [http://my.oschina.net/u/877567/blog/183959] sls文件解读

base:
'jkcj':
   - httpd.httpd

   

 include

include:
- prod.jdk.install_1.7.20_60 // 这样是找不到的,
可以把 dot转义一下 prod.jdk.install_{{jdk_version.replace(".","_")}}
这样就能用了

  

state逻辑关系列表

  match -> require -> watch -> order

require: 依赖某个state,在运行此state前,先运行依赖的state,依赖可以有多个

match: 配模某个模块,比如 match: grain match: nodegroup

require: 依赖某个state,在运行此state前,先运行依赖的state,依赖可以有多个
只是执行那个state,不管是不是成功或者匹配到unless ifonly,即使unless 也成功返回

   

watch: 在某个state变化时运行此模块,watch除具备require功能外,还增了关注状态的功能,比如配置改了后,后续动作
redis:
 pkg:
 - latest
 file.managed:
 - source: salt://redis/redis.conf
 - name: /etc/redis.conf
 - require:
    - pkg: redis
 service.running:
 - enable: True
 - watch:
 - file: /etc/redis.conf
 - pkg: redis​

  

order: 优先级比require和watch低,有order指定的state比没有order指定的优先级高

vim:
pkg.installed:
- order: 1

想让某个state最后一个运行,可以用last

  

unless: unless: test -d /usr/local/nginx 如果结果为 False,才执行该 state,True 则跳过
只能写一个 unless,如果写两会有先后顺序,最下面那个来判断是否执行,unless execution succeeded,命令就不执行下去
使用复合表达:
cmd.run:
- name: mkdir /tmp/zgt
- unless: test -d /home/nginx
- unless: test -d /home/ecp/nginx
例1
- unless: 
   - test -d /usr/local/jdk1.7.0_60 || java -version
例2
- unless:
   - rpm -q vim-enhanced
   - ls /usr/bin/vim

# 判断系统环境变量
test "{{ fqdn }}" = "$(hostname)"

  

onlyif:
    - onlyif: ps -ef|grep -v grep|grep PatrolAgent // 返回True 则执行​


echo-ok:
   cmd.run:
      - name: "echo ok"
      - onlyif: ps -C java -f --width 1000|grep jboss|grep -vE "grep|salt|ssh" 

yaml和jinja语法

1 FILE 状态使用template参数

- template: jinja 

2 模板文件里面变量使用{{ PORT }}
3 FILE 状态模块要指定变量列表

- defaults:
  PORT: 8080

   

pillar数据

cat /srv/pillar/base/top.sls 
base:
    '*':
        - prod_env

cat /srv/pillar/live/top.sls 
live:
    '*':
        - prod_env

  

match 貌似只能用list,用nodegroup就找不到servers了

base:
    'website1,website2,website3':
        - match: list 
        - data
    'udbxh1,udbxh2':
        - match: list
        - data_udb
    'yxqdgk1,yxqdgk2':
        - match: list
        - data_yxqdgk

  

数据格式

字典:
test:
    wojiushikk: test666
    

多层字典
salt-minion:
 tmp: {'name': 'lixc', 'remove': 'True'} 
 {% set size=salt['grains.get']('tmp:remove', '') %}
 {% if size %}
 ....
 {% endif %}​


列表:
test:
    - nni
    - sddd
    - wddd

  

获取pillar变量

# 获取变量
{{ pillar['user'] }}
{{ pillar.get('user',{}) }} # 更好

     

将参数带入到state中渲染

salt/mypkg.sls:
packages:
 pkg:
 - installed
 - pkgs: {{ salt['pillar.get']('packages') }}​


salt '*' state.sls package-list pillar='{packages: [foo, bar, baz]}'​

  

pillar.get() vs salt['pillar.get']()
用 : 可以快速地找 dict 中的值,注意参数要加 '' 引号

# /srv/salt/apache/conf.sls
{% from "apache/map.jinja" import apache with context %}
apache_conf:
file:
- managed
- name: {{ salt['pillar.get']('apache:lookup:name') }}
- source: {{ salt['pillar.get']('apache:lookup:config:tmpl') }}

   

grains数据

# cat nginx.sls 
{% if grains['nodename'].startswith('website') %}
toms: 
    tom1: gjdx_tomcat
    tom2: tomcatecp
    tom3: yixinb_tomcat
    tom4: tomcatecp
{% endif %}

  

在 jinja中的调用 :
{{ grains['ipinfo'][0]['IP'] }}

 

 

正则表达式

现在jinja支持的表达式不多,很多应用暂时无解

{% if grains['osrelease'].startswith('6') %} 
{{ grains['nodename'].split("-")[0] }}

  

判断

{% if grains['osrelease'] < '6' %}
- name: /etc/yum.repos.d/epel5.repo
- source: salt://base/init/repo/files/epel5.repo
{% else %}
- name: /etc/yum.repos.d/epel6.repo
- source: salt://base/init/repo/files/epel6.repo
{% endif %}


{% if grains['os'] in ('RedHat','CentOS') %}
salt-test:
cmd.run:
- name: echo "oko"
{% endif %}
# 判读目录是否存在
{% if salt['file.directory_exists']('/etc/logrotate.d') and not salt['file.file_exists']('/etc/logrotate.d/nginx') %}
{% endif %}

  

字符串操作

# 变量修改,加上字符
{% set value='/home' %}
{% set ecp='/ecp' %}
{% if salt['file.directory_exists'](value+"/"+ecp) %}


# jinja 使用执行模块
{{ salt['network.hw_addr']('eth0') }}

# 赋值
{% set slave_ip = '172.23.4.43' %}

# 如果是多级字典
{{ pillar['user']['user'] }}

# 两种都可以
{{ foo.bar }}
{{ foo['bar'] }}

# 取值,如果为 None,用默认值
{{ foo.bar | default('zoo') }}

# 获取变量后替换字符串
{% set mystr = grains['cpu_model'] | replace("CPU","GGG") %}

      

循环操作

pillar/data/toms.sls
tom1:
    8081
tom2:
    8082

{% for item in pillar['toms'].items() %}  # for 循环
# item的类型是(tuple)  = ('tom1',8081) 
# item[1] = 8081
tom-tar-{{ item[1] }}: ==> tom-tar-8081
cmd.run:
    - name: echo {{item[1]}} >> /tmp/foo
{% endfor %}​



{% for item in pillar['vhost'] %}
{{ item['name'] }}:
cmd.run:
    - name: echo "{{ item['source'] }}" > /tmp/bar
{% endfor %}

{% for i in pillar.get('user',{}).items %}
{{ i }}
{% endfor %}

  

文件操作

# 添加内容
/srv/salt/test/file.sls
/tmp/a.txt:
 file.append:
 - text:
     - 'this is append line1'  #注意用单引号或双引号
     - 'this is append line2'​

file.append:
 - text:
 - local3.* /var/log/keepalived.log
 - unless: cat /etc/rsyslog.conf|grep keepalived​

# 可以追加模板
/etc/motd:
file:
- append
- template: jinja 
- sources:
- salt://motd/devops-messages.tmpl
- salt://motd/hr-messages.tmpl
- salt://motd/general-messages.tmpl

# 修改内容: 
/etc/sysconfig/network
file.replace:
- pattern: HOSTNAME=
- repl: HOSTNAME={{ fqdn }}
/etc/yum.repos.d/epel.repo:
file.sed:
- before: 1
- after: 0
- limit: ^enabled=

# 文件管理
/usr/local/src/nginx-1.9.2.tar.gz
file.managed:
- source: salt://prod/nginx/files/nginx-1.9.2.tar.gz
- user: root
- group: root
- mode: 755
- unless: test -f /usr/local/src/nginx-1.9.2.tar.gz

# 创建目录
file.mkdir /usr/log_bak​
haproxy-config-dir:
 file.directory:
 - name: /etc/haproxy
 - mode: 755
 - user: root
 - group: root​

  

用户操作

ecp-user-group:
group.present:
- name: ecp
- gid: 550
user.present:
- name: ecp
- fullname: ecp
- shell: /bin/bash
- uid: 550
- gid: 550
- password: $6$SALTsalt$UiZikbV3VeeBPsg8./Q5DAfq9aj7CVZMDU6ffBiBLgUEpxv7LMXKbcZ9JSZnYDrZQftdG319XkbLVMvWcF/Vr/
- enforce_password: True

# password生成方法
python -c "import crypt; print crypt.crypt('password', '\$6\$SALTsalt\$')"
或者用openssl (用这个靠谱),不加盐的话每次生成的字符串都不一样,但是反解出来是一样的密码。
加了盐之后生成的字符串每次都一样了
$ openssl passwd -1 -salt "SALT"
Password: 
$1$SALT$3ATlhGooo9OTS0VrH2L0y0

  

环境变量

cmd.run:
    - env:
        - PATH: "JAVA_HOME:/usr/local/jdk1.6.0_32"
    - name: cd /usr/local/monitor_agent && /usr/bin/nohup ./monitor-agent start &
    - unless: ps -ef|grep -v grep|grep "appname=MonitorAgent"

  

salt://scripts/bar.sh:
cmd.script:
    - env: "PATH=/some/path:$PATH"​ 

  

{% set current_path = salt['environ.get']('PATH', '/bin:/usr/bin') %}
mycommand:
    cmd.run:
        - name: ls -l /
        - env:
            - PATH: {{ [current_path, '/my/special/bin']|join(':') }} //按 : 表达​

  

cmd

echo-ok:
   cmd.script:
      - source: salt://script/auto_clean.sh
      - shell: '/bin/bash'


cmd.run:
- env: 
- CFLAGS:"-fPIC" // 设置环境环境变量
- names:
- cd /usr/local/s

  

 

 

 

常遇错误

1 编写错误

2 tab键错误Illegal tab character(jinja不支持tab)

3 key后面要空格  mode: 644 -- 注意空格: 不然会 报错:Too many functions declared in state "file"

4 注意要顶格写,不然会报格式错误

{% if <statment1> %}
{% if <statment2> %}
/etc/logrotate.d/nginx:
file.append: 

  

posted @ 2019-12-23 18:40  richardzgt  阅读(1194)  评论(0编辑  收藏  举报