saltstack扩展夜莺树信息到pillar
pillar配置
比较早的一个脚本,主要是夜莺的接口文档补全,前期对接的时候找接口都要去翻下源代码..。
大概过程:
-
- 入口方法 ext_pillar 查询主机,返回主机所有的pillar
- 调用get_host_info 获取主机信息,这里面有比较多的内容主要是在判断是物理机、虚拟机等..,因业务有历史原因,有些业务逻辑在里面。
- 获得主机所在的所有树节点信息,进行合并(不通的树节点信息,可以绑定不同的state)
- 获得节点的用户列表信息,进行合并(如果用户存在于某个节点下,可以给用户在主机上的授权动作)
- 获得节点的所有扩展字段,进行合并(扩展字段,看用途吧..,比如可以写个state的名字,存在的话,自动绑定state)
脚本位置:/srv/salt/modules/pillar/salt.py
master配置:/etc/salt/master
1 2 |
ext_pillar: - salt: [] |
脚本内容:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 |
#!/usr/bin/python3 import json import requests import sys import traceback import logging token = "abcdef" n9e_api = "http://127.0.0.1:8000" def get_host_info(host): uuid = "" if host.endswith("host.local"): url = n9e_api + "/api/rdb/resources/search?batch=%s&field=name" % host hosts = requests.get(url, headers={"X-User-Token": token }).json()["dat"] if hosts == None: t_host = host.replace('.host.local', '') url = n9e_api + "/api/rdb/resources/search?batch=%s&field=name" % t_host hosts = requests.get(url, headers={"X-User-Token": token }).json()["dat"] logging.error(host, t_host, hosts) if len(hosts[0]["uuid"]) > 25: uuid = hosts[0]["uuid"] elif len(host) > 25: uuid = host.split("-")[2] url = n9e_api + "/api/rdb/resources/search?batch=%s&field=uuid" % uuid hosts = requests.get(url, headers={"X-User-Token": token }).json()["dat"] else: url = n9e_api + "/api/rdb/resources/search?batch=%s&field=ident" % host hosts = requests.get(url, headers={"X-User-Token": token }).json()["dat"] if not hosts: host = host.replace('-', '.') url = n9e_api + "/api/rdb/resources/search?batch=%s&field=ident" % host hosts = requests.get(url, headers={"X-User-Token": token }).json()["dat"] if uuid: return (True, hosts[0] ) if hosts: host = hosts[0] host["host_id"] = host["uuid"] host["fields"] = {} if host: url_fields = n9e_api + "/api/ams-ce/host/%s/fields" % host["host_id"] req_host_fields = requests.get(url_fields, headers={"X-User-Token": token }).json() if "dat" in req_host_fields: for k in req_host_fields["dat"]: if k["field_value"]: host["fields"][k["field_ident"]] = k["field_value"] return (True,host) return (False, host) def get_node_ids(nid): tree_url = n9e_api + "/api/rdb/tree" tree = requests.get(tree_url, headers={"X-User-Token": token }).json()["dat"] t_data = { i["id"]: {"pid": i["pid"], "path": i["path"]} for i in tree } data = {"ids": [], "path": []} while True: if nid == 0: break if nid in t_data: data["ids"].append(nid) data["path"].append(t_data[nid]["path"]) nid = t_data[nid]["pid"] return {"ids": data["ids"][::-1], "path": data["path"][::-1]} def get_node_info(host): url = n9e_api + "/api/rdb/resources/bindings?ids=%s" % host["id"] nodes = requests.get(url, headers={"X-User-Token": token }).json()["dat"] merge_key = ["salt"] if nodes: nodes = nodes[0]["nodes"] ids_list = {"ids": [], "path": []} for n in nodes: t = get_node_ids(n["id"]) ids_list["ids"].extend(t["ids"]) ids_list["path"].extend(t["path"]) nodes_fields = {} for nid in ids_list["ids"]: t_fields = get_node_fields(nid) for i in t_fields.keys(): if i in merge_key and i in nodes_fields.keys(): if isinstance(nodes_fields[i],str): t_fields[i] = list(set([nodes_fields[i], t_fields[i]])) if isinstance(nodes_fields[i],list): nodes_fields[i].append(t_fields[i]) t_fields[i] = list(set(nodes_fields[i])) nodes_fields.update(t_fields) return {"ids": list(set(ids_list["ids"])), "path": list(set(ids_list["path"])), "fields": nodes_fields } def get_node_fields(nid): url = n9e_api + "/api/rdb/node/%s/fields" % nid req = requests.get(url, headers={"X-User-Token": token }).json()["dat"] data = {} if req: data = { i["field_ident"]: i["field_value"] for i in req if i["field_value"]} return data def get_user(ids, path): data = [] if ids: for n in ids: url = n9e_api + "/api/rdb/node/%s/roles" % n req = requests.get(url, headers={"X-User-Token": token }).json()["dat"]["list"] if req: for i in req: if i["node_path"] in path: data.append(i["username"]) data = list(set(data) - set(["root"])) return data def ext_pillar(minion_id, pillar, *args, **kwargs): try: status, host = get_host_info(minion_id) except: host = "" return {"trace": traceback.format_exc() , "host_info": get_host_info(minion_id)} if status: node = get_node_info(host) user = get_user(node["ids"], node["path"]) return {"host": host, "node": node, "user": user } return {"status": status, "host": host} |
top配置
1 2 3 4 5 6 7 8 9 |
# 节点路径绑定 'node:path:xx.inf.log_index': - match: pillar - state.inf.logstash # 特点字段绑定 'G@virtual:kvm and I@node:fields:salt:demo': - match: compound - state.spider.demo |