模块是个啥呢?其实就是个文件。

salt模块其实分为两类,一类模块,叫execution modules,这一类模块是在命令行上面执行的

来个内置执行模块的链接地址:

http://docs.saltstack.cn/ref/modules/all/index.html#all-salt-modules

还有一类模块,叫state modules,这一类模块是在state里面使用的

也来个内置state模块的链接:

http://docs.saltstack.cn/ref/states/all/index.html

先说执行模块是怎么写的吧。

执行模块,默认的路径在/srv/salt/_modules下



__salt__是个字典,是个啥字典呢,这个玩意,是属于salt全局的一个字典,只要我们定义的模块被minion加载后,就可以用__salt__了。

注意:这个__salt__字典,不是在我们模块里面自己定义的,而是salt全局的,我们写模块的时候直接拿来用就OK了

OK,知道__salt__是个啥之后,那个这东西里面都装了些什么玩意呢?

其实,__salt__这个字典里面装的minion上面所有的modules。__salt__的key是一个个的模块名称,value则是模块里面的一个个函数。

好,下面咱们看个例子,看看内建模块是怎么调用的。

这个foo.py是楼主自定义的一个模块,很简单,传一个参数进去,然后返回一段话
root@salt-master:~# cat /srv/salt/_modules/foo.py 
def foo(name):
    return  "I am %s" % name
    
这个cheng.py也是楼主定义的一个模块,目的是通过__salt__调用我们上面定义的那个foo模块中的
foo函数
root@salt-master:~# cat /srv/salt/_modules/cheng.py 
def cheng(name):
  return __salt__['foo.foo'](name)

OK,咱们同步一下模块
root@salt-master:~# salt  '*'    saltutil.sync_modules
salt-minion:
    - modules.cheng
    - modules.foo
    
好,看一下结果!
root@salt-master:~# salt  '*'    cheng.cheng lisisi
salt-minion:
    I am lisisi
root@salt-master:~#

通过这个例子,大家差不多该知道怎么调用__salt__里面的模块函数了吧。

好,咱们总结一下

使用格式:__salt__['模块.函数']('函数参数')


OK,下一个话题,来看看自定义的模块,怎样使用grains,pillar,以及编写文档,还有自定义输出格式。

看这个例子。

root@salt-master:~# cat -n /srv/salt/_modules/lisisi.py 
     1  '''
     2  :maintainer:    LiXiangcheng <626659817@qq.com>
     3  :maturity:      new
     4  :depends:       
     5  :platform:      all
     6  '''
     7  __outputter__ = {
     8                  'lisisi': 'json'
     9                  }
    10  def lisisi(args):
    11      '''
    12      A function just one example
    13      CLI Example:
    14          salt '*' lisisi.lisisi args
    15
    16      '''
    17      grain = __grains__['chengge']
    18      pillar = __pillar__['group']
    19      result = __salt__['cmd.run'](args)
    20      result = "%s,%s,%s" % (grain,pillar,result)
    21      return  result
root@salt-master:~#

下面解释一下,1到6行都看得明白,是一些基本信息。

7到9行,是指定输出格式,__outputter__这个东西也是个字典,这个字典会绑定salt中的一个方法,当你以    函数名:输出格式   这种形式加入__outputter__这个字典后,salt就会帮你把你指定的函数,按照指定的格式打印返回值。

好了,那输出格式有哪些个呢?看下面

'grains','yaml','json','pprint','raw','highstate','quiet','key','txt','no_return','nested','virt_query'

看到了没,这么多。一般咱们用默认的就OK了,大多数的输出格式都不好看其实。楼主这里用json输出格式测试一下。

再看一下11~16行,这个东西是干啥的呢?这个东西,是把你这个函数的用法加到sys.doc里面的。

再看一下17行。这个用到grains,咋用的呢,也是通过salt默认的一个字典__grains__,你想去哪个grain的时候,这么用就ok了,__grains__['Id']

18行,这个用到了pillar,咋用的呢?和grains一个样,__pillar__['Id']

下面的几行就不说了。

OK,来看一下结果

好同步一下模块
root@salt-master:~# salt  '*'    saltutil.sync_modules
salt-minion:
    - modules.lisisi
    
看一下doc,看看这个函数是咋用的?
root@salt-master:~# salt '*'  -d lisisi.lisisi 
lisisi.lisisi:

    A function just one example
    CLI Example:
        salt '*' lisisi.lisisi args

    
OK,可以执行了,传个命令进行
root@salt-master:~# salt '*' lisisi.lisisi  "ls /tmp" 
{
    "salt-minion": "1002,lixc,lixc1"
}
root@salt-master:~#


OK,关于执行模块,楼主看了官方文档,还有这么个功能,__virtual__, 这东西叫虚拟模块

这功能楼主一看,尼玛,这东西好像和C++里面的多态虚函数,差不多。

这东西咋用的呢?官网上的例子是pkg这个模块,安装软件,有很多平台啊,有debian用的apt-get,centos用的是yum,用这个函数就可以来自动的判断。。。

楼主举个小例子吧。

先看一下,楼主的这个模块是咋定义的?
root@salt-master:~# cat /srv/salt/_modules/foo.py 
__virtualname__ = 'sisi'
def __virtual__():
    if __grains__['chengge'] == 1002:
        return True
    return __virtualname__
def foo(name):
    return  "I am %s" % name

再看一下,chengge这个grains的value是啥,和楼主那个模块里都是1002,说明__virtual__这个函数会
返回True
root@salt-master:~# salt '*' grains.item chengge
salt-minion:
  chengge: 1002
  
同步一下模块
root@salt-master:~# salt  '*'   saltutil.sync_modules
salt-minion:
    - modules.foo
    
好,执行这个模块,正常打印了吧。
root@salt-master:~# salt  '*'   foo.foo lisisi
salt-minion:
    I am lisisi
    
接着,咱们把1002随便改为1003吧,这时候1003这个值和chengge这个grain的value是不一致的,这时候
__virtual__这个函数返回__virtualname__,也就是'sisi'
root@salt-master:~# sed -i 's#1002#1003#g' /srv/salt/_modules/foo.py

查看一下,修改成功了没 
root@salt-master:~# grep 1003 /srv/salt/_modules/foo.py 
    if __grains__['chengge'] == 1003:
    
OK,修改之后,再同步一下模块
root@salt-master:~# salt  '*'   saltutil.sync_modules                
salt-minion:
    - modules.foo
    
再执行一下模块,看到了没,模块不可用了。
root@salt-master:~# salt  '*'   foo.foo lisisi                                    
salt-minion:
    'foo.foo' is not available.
    
再这么访问一下,看到了神奇的地方了没
root@salt-master:/srv/salt/_modules# salt '*'  sisi.foo   lixc
salt-minion:
    I am lixc

哈哈,大伙应该知道这东西大概怎么用了吧。其实__virtual__这东西,返回一个string的时候,模块就可用,当它返回False的时候。模块就不可用了。。。

如果__virtual__这个函数,返会__virtualname__,那么我们的模块的名字就会被改名,修改的名字就是__vitualname__对于的值。

我们可以根据__virtual__这个函数,来控制,自定义模块的使用场景。。。

哈哈,还有一个东西忘记提了,怎么同步模块呢,上面已经写了一种方法,楼主总结下吧。以下三种方法都可以同步模块

salt '*' state.highstate

salt '*' saltutil.sync_all

salt '*' saltutil.sync_modules


exection modules官方上还介绍了一个装饰器的功能。。楼主还没看懂。自定义state modules,楼主也没有看到呢,楼主先研究研究再写吧。