大多時,在使用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配置過程我就忽略,直接貼結果
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
我這就不演示數據生成過程,只要後端數據更新,執行對應minion id的pillar就能獲取到最新數據,因爲pillar是動態的~
希望這篇文章能幫助大家,玩的開心~~~ 以後再也不用和我一樣找不到文章了。。