大多时,在使用pillar我们都是直接用的SLS文件存储数据,但其实pillar可以支持多种数据存储方式,例如: mysql、mongo、json等等;这些都可以在官网或者代码中看到ext_piilar的代码;

  pillar支持的数据存储模块列表地址:http://docs.saltstack.com/en/latest/ref/pillar/all/index.html#all-salt-pillars


 需求:

    先说说为什么会有这个需求,某些时候我们需要把pillar数据存储在CMDB中,或者去拉取CMDB的数据提供pillar使用,这个时候再去编辑pillar下的SLS文件就有点不优雅了;ext_pillar就是解决这个问题,它作为pillar数据映射和数据存储(CMDB)的一个枢纽。

    最近在写代码发布,需要用到pillar数据(平台上提供一个版本号,代码url,在打包完代码推送到repo时,把版本号更新到pillar数据上,供saltstack调取),就想起了ext_pillar这个事儿,OMS运维平台用到了MySQL数据库,就想直接使用这个模块;在接触的时候,有点淡淡的忧伤,文档真少~~  找到一个翻译文章采用的是MongoDB,想到再去搭个mongodb就有点过了; 肥肥给我的建议是不要采用MySQL,建议做成Http API接口方式;

  

pillar是一大利器,不仅可以存储安全性数据,也可以作为业务数据存储; 利用ext_pillar对接CMDB系统,state用来描述业务处理逻辑,而真实数据取自CMDB;以前没想到还可以这么玩,这块绿肥、jacky两人最早实现,很有经验

  

 

 讲了这么多,来说说这么实现这个Http API的ext_pillar(无CMDB)

  1. 实现后端数据  ->   根据业务场景,设计数据结构(dict)来满足业务,控制权在你手上,你想要什么样子就可以实现什么样子,关键点符合你业务

  2. 实现ext_pillar,能访问到http访问到后端数据

  3. 配置salt master配置文件,重启master

  4. pillar测试


 实现:

  1. 后端数据实现.

     采用http方式用的就是JSON数据,不仅能生成json数据,也能变更json数据;首先来看下pillar数据映射SLS文件格式

     hdworkers:

       ver: 2014102202

     上述数据格式转换下dict,{'hdworkers': {'ver': '2014102202'}} ,我只需要实现简单的版本号映射就行,那么复杂的数据,大家可以自行设计;下面贴程序代码(代码很烂,莫喷~)

 # -*- coding: utf-8 -*-
import json
import os

class BuildJson(object):
    '''
    Build JSON data(base and minion_id etc..)
    '''
    def base_data(self,args):
        '''
        build base data
        '''
        info = {}
        ret = dict(info,**args)
        self.write_data('base',ret)

    def build_data(self,id,args):
        if not os.path.exists('/home/api/pillar/%s' % (id)):
            with open('/home/api/pillar/base') as f:
                obj = f.readlines()[0]
            ret = eval(obj)
            self.write_data(id,ret)
        with open('/home/api/pillar/%s' % (id)) as f:
            data = f.readlines()[0]
        cov_data = eval(data)
        if not cov_data.has_key(args.keys()[0]):
            ret = dict(cov_data,**args)
            self.write_data(id,ret)
        else:
            cov_data.update(args)
            self.write_data(id,cov_data)

    def write_data(self,file,ret):
        f = open('/home/api/pillar/%s' % (file),'w+')           
        f.write(str(ret))
        f.close()

    #data = {'hdworkers':{'ver':'2014103105'}}

    #bapi = BuildJson()

    #bapi.base_data(data)

    #bapi.build_data('test-01',data)


    生成base数据,再调用build_data(继承base数据,同时更新数据),而有些数据是会在id上有,但base是没的~,所以上述是我写的;  看官可以自行玩耍,,有好的可以反馈给我,我在修改~


 2. 实现ext_pillar,能通过http方式访问

   因为是和OMS平台结合,上述生成的文件,我在nginx做了localtion设置,让数据能通过http访问;不然ext_pillar没法玩了

   Nginx配置过程我就忽略,直接贴结果

     wKiom1RTRYnBk6SRAABWZ4qyD_U841.jpg

     ID数据能通过http访问到,OK,往下走,配ext_pillar


    ext_pillar实现

   more /usr/lib/python2.6/site-packages/salt/pillar/oms.py

# -*- coding: utf-8 -*-
'''
author: pengyao
A module to pull data from OMS system via its API into the Pillar dictionary


Configuring the Wolf system ext_pillar
==================================

.. code-block:: yaml

  ext_pillar:
  - oms:
      api: http://oms.example.com/api/pillar/

Module Documentation
====================
'''

# Import python libs
import logging
import urllib2
import json


# Set up logging
log = logging.getLogger(__name__)


def ext_pillar(minion_id, pillar, api):
    '''
    Read pillar data from OMS system via its API.
    '''
    pillar_url = api + "/" + minion_id

    log.info("Querying OMS system Pillar for %r" %(minion_id))
    try:
        request = urllib2.urlopen(pillar_url).read()
        ret = eval(request)
        result = json.loads(json.dumps(ret))
    except Exception, e:
        log.exception(
            'Query OMS system failed! Error: %s' %(e)
        )
        return {}

    return result

    上述代码很简单,urllib2请求minion_id数据,json.loads把数据转换成dict返回给saltstack。 注意urllib请求得到的数据是str,我这把str先给转换成dict在传递给json去转,避免成为unicode......(赶脚json是不是有点多~)


  3. 配置salt master配置文件,pillar测试

    根据ext_pillar代码配置master配置文件,让master会去加载pillar数据

    cat /etc/salt/master

    ext_pillar: 

      - oms:           #代码名字,oms.py
         api: 
http://X.X.X.X/pillar/       # api前缀,http://访问域名/IP/pillar/minion_id能访问到数据

    重启master

    /etc/init.d/salt-master restart

   

   4. pillar测试

       salt  'minion_id' pillar.item hdworkers

       使用Http API接口来读取pillar数据 -- ext_pillar_第1张图片

       我这就不演示数据生成过程,只要后端数据更新,执行对应minion id的pillar就能获取到最新数据,因为pillar是动态的~

       希望这篇文章能帮助大家,玩的开心~~~   以后再也不用和我一样找不到文章了。。