如果你现在已经有了一套资产管理系统, 支持账号权限控制, 能很方便的存放一些key/value. 同时也在使用saltstack进行系统管理. 是不是会觉得如果pillar放在资产管理系统会是一个不错的做法?
下面这种方式能够让你在资产管理系统中定义pillar, 然后打通到saltstack.
知识点:
在saltstack中, ext_pillar的优先级要比定义在master的pillar/foo.sls中高.
saltstack官方提供了一个http_json接口, 但是用起来会有2个不方便的地方:
- 不支持账号认证(提了个issue, https://github.com/saltstack/salt/issues/36138 ,还没修)
- 不支持只获取某个minion的pillar.
这就好说了, 既然有了葫芦, 可以比着画个瓢, 支持这2特性.
1. 增加ops_http_json.py
2. 在salt master上增加配置:
ext_pillar:
- ops_http_json:
url: https://ops.ops.com/assets/salt/%s/pillars/
username: username
password: password
ops_http_json.py代码如下:
# -*- coding: utf-8 -*-
'''
A module that adds data to the Pillar structure retrieved by an http request
Configuring the HTTP_JSON ext_pillar
====================================
Set the following Salt config to setup http json result as external pillar source:
.. code-block:: yaml
ext_pillar:
- http_json:
url: http://example.com/api/%s
username: basic username
password: basic password
Module Documentation
====================
'''
# Import python libs
from __future__ import absolute_import
import logging
import re
# Import Salt libs
try:
from salt.ext.six.moves.urllib.parse import quote as _quote
_HAS_DEPENDENCIES = True
except ImportError:
_HAS_DEPENDENCIES = False
# Set up logging
_LOG = logging.getLogger(__name__)
def __virtual__():
return _HAS_DEPENDENCIES
def ext_pillar(minion_id,
pillar, # pylint: disable=W0613
url,
username=None,
password=None):
'''
Read pillar data from HTTP response.
:param str url: Url to request.
:param str username: username for basic auth
:param str password: password for basic auth
:return: A dictionary of the pillar data to add.
:rtype: dict
'''
url = url.replace('%s', _quote(minion_id))
_LOG.debug('Getting url: %s', url)
if username and password:
data = __salt__['http.query'](url=url, username=username, password=password, decode=True, decode_type='json')
else:
data = __salt__['http.query'](url=url, decode=True, decode_type='json')
if 'dict' in data:
return data['dict']
_LOG.error("Error on minion '%s' http query: %s\nMore Info:\n", minion_id, url)
for key in data:
_LOG.error('%s: %s', key, data[key])
return {}