• saltstack运维工具包salt-api代码记录


     环境:python3

    如何调用

    from utils.salt_util import SaltApi
    salt = SaltApi("https://192.168.1.21:8001")
    salt.remote_cmd_sync_test("bj-sjhl-c-app-test01-192.168.1.25,bj-sjhl-c-app-test02-192.168.1.26", "cmd.script", arg=["salt://scripts/test.sh","1 2 3 "])

    #salt-api cmd.script 如何传入参数

    ref:Python client API

    netapi modules

    1. #!/usr/bin/python
    2. import requests
    3. import os,sys
    4. import yaml
    5. BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
    6. sys.path.append(BASE_DIR)
    7. from conf import config
    8. import urllib3
    9. import datetime
    10. #urllib3.disable_warnings()
    11. requests.packages.urllib3.disable_warnings()
    12. class SaltApi(object):
    13. def __init__(self, salt_api_url):
    14. self.username = config.get_config_item('salt', 'salt_user')
    15. self.password = config.get_config_item('salt', 'salt_password')
    16. self.eauth = config.get_config_item('salt', 'salt_auth_method')
    17. self.verify = False
    18. self.salt_api_url = salt_api_url
    19. self.__header = dict()
    20. self.__header["Accept"] = "application/json"
    21. self.token_s_time = ''
    22. self.__token = self.get_token()
    23. print(self.__token)
    24. def get_token(self, prefix='/login'):
    25. """
    26. 登录获取token
    27. """
    28. data = {
    29. "username": self.username,
    30. "password": self.password,
    31. "eauth": "pam"
    32. }
    33. loginurl = self.salt_api_url + prefix
    34. req = requests.post(loginurl, data=data, headers=self.__header, verify=False)
    35. try:
    36. self.token = req.json()["return"][0]["token"]
    37. self.token_s_time = datetime.datetime.now()
    38. return self.token
    39. except KeyError:
    40. raise KeyError
    41. def salt_request(self, data, prefix='/'):
    42. """
    43. 接收请求,返回结果
    44. """
    45. token_e_time = datetime.datetime.now()
    46. if (token_e_time - self.token_s_time).seconds/3600 > 3:
    47. print("salt-api token is Expired")
    48. self.get_token()
    49. url = self.salt_api_url + prefix
    50. self.__header["X-Auth-Token"] = self.__token
    51. # 传入data参数字典,data为None 则方法为get,有date为post方法
    52. if data:
    53. req = requests.post(url, data=data, headers=self.__header, verify=False)
    54. else:
    55. req = requests.get(url, headers=self.__header,verify=False)
    56. return req.json()
    57. def list_key(self):
    58. """
    59. 获取包括认证、未认证salt主机
    60. """
    61. prefix = '/keys'
    62. content = self.salt_request(None, prefix)
    63. accepted = content['return']['minions']
    64. denied = content['return']['minions_denied']
    65. unaccept = content['return']['minions_pre']
    66. rejected = content['return']['minions_rejected']
    67. return {"accepted": accepted, "denied": denied, "unaccept": unaccept, "rejected": rejected}
    68. def accept_key(self, key_id):
    69. """
    70. 接受salt主机
    71. """
    72. data = {'client': 'wheel', 'fun': 'key.accept', 'match': key_id}
    73. content = self.salt_request(data)
    74. ret = content['return'][0]['data']['success']
    75. return ret
    76. def minions_status(self):
    77. """
    78. salt主机存活检测
    79. """
    80. data = {'client': 'runner', 'fun': 'manage.status'}
    81. content = self.salt_request(data)
    82. ret = content['return'][0]
    83. up = ret['up']
    84. down = ret['down']
    85. ups = []
    86. downs = []
    87. for host in up:
    88. ups.append({'hostname': host, 'status': 'up'})
    89. for host in down:
    90. downs.append({'hostname': host, 'status': 'down'})
    91. ret['up'] = ups
    92. ret['down'] = downs
    93. return ret
    94. def get_result(self, jid):
    95. """
    96. 通过jid获取执行结果
    97. """
    98. data = {'client': 'runner', 'fun': 'jobs.lookup_jid', 'jid': jid}
    99. content = self.salt_request(data)
    100. ret = content['return'][0]
    101. return ret
    102. def get_job_info(self, jid=''):
    103. """
    104. 获取任务的详细执行信息
    105. """
    106. if jid:
    107. prefix = '/jobs/' + jid
    108. else:
    109. prefix = '/jobs'
    110. content = self.salt_request(None, prefix)
    111. ret = content['return'][0]
    112. return ret
    113. def running_jobs(self):
    114. """
    115. 获取运行中的任务
    116. """
    117. data = {'client': 'runner', 'fun': 'jobs.active'}
    118. content = self.salt_request(data)
    119. ret = content['return'][0]
    120. return ret
    121. def check_job(self, jid):
    122. """
    123. 检查任务是否已经执行并成功退出
    124. """
    125. data = {'client': 'runner', 'fun': 'jobs.exit_success', 'jid': jid}
    126. content = self.salt_request(data)
    127. ret = content['return'][0]
    128. return ret
    129. def delete_key(self, minion_key):
    130. self.delete_header = {"Accept": "application/x-yaml","X-Auth-Token": self.token}
    131. self.delete_data = {"client": "wheel", "fun":"key.delete", "match": minion_key}
    132. result = requests.post(url=self.salt_api_url, headers=self.delete_header, data=self.delete_data,verify=self.verify)
    133. if yaml.load(result.text)['return'][0]['data']['success']:
    134. print("%s delete success" % minion_key)
    135. else:
    136. print("% delete falied" % minion_key)
    137. def remote_cmd_sync(self, tgt, fun, client='local', tgt_type='glob', arg='', **kwargs):
    138. """
    139. 执行远程命令、部署模块 glob - Bash glob completion - Default
    140. """
    141. try:
    142. data = {'client': client, 'tgt': tgt, 'fun': fun, 'arg': arg, 'tgt_type': tgt_type}
    143. content = self.salt_request(data)
    144. #print(content)
    145. for host_result in content['return'][0]:
    146. print('%s:\n%s'%(host_result,content['return'][0][host_result]))
    147. return content
    148. except Exception as e:
    149. print('ERROR:%s'%(e))
    150. def remote_cmd_sync_list(self, tgt, fun, client='local', tgt_type='list', arg='', **kwargs):
    151. """
    152. 执行远程命令、部署模块 list - Python list of hosts
    153. """
    154. try:
    155. data = {'client': client, 'tgt': tgt, 'fun': fun, 'arg': arg, 'tgt_type': tgt_type}
    156. content = self.salt_request(data)
    157. #print(content)
    158. for host_result in content['return'][0]:
    159. print('%s:\n%s'%(host_result,content['return'][0][host_result]))
    160. return content
    161. except Exception as e:
    162. print('ERROR:%s'%(e))
    163. def remote_state_sync(self, tgt, fun, client='local', tgt_type='list', arg='', **kwargs):
    164. """
    165. 执行state.sls 标准化格式输出
    166. """
    167. try:
    168. print ('===================================salt -L "%s" %s "%s"'%(','.join(tgt),fun,arg))
    169. data = {'client': client, 'tgt': tgt, 'fun': fun, 'arg': arg, 'tgt_type': tgt_type}
    170. content = self.salt_request(data)
    171. #print('==============content:%s'%content)
    172. return_info=content['return'][0]
    173. #print('==============return_info:%s'%return_info)
    174. for saltname in return_info:
    175. print(saltname)
    176. for key in return_info[saltname]:
    177. #key: pkg_|-supervisor_|-supervisor_|-removed:
    178. #value: {'comment': 'All specified packages are already absent', 'name': 'supervisor', 'start_time': '18:39:25.024440', 'result': True, 'duration': 334.819, '__run_num__': 0, '__sls__': 'soft.supervisord', 'changes': {}, '__id__': 'supervisor'}
    179. #print('======================= %s:\n %s'%(key,return_info[saltname][key]))
    180. return_info_comment=return_info[saltname][key]
    181. salt_result_format={'Result':return_info_comment['result'],'Name':return_info_comment['name'],'__sls__':return_info_comment['__sls__'],'start_time':return_info_comment['start_time']}
    182. s=' '
    183. for result_str,value in salt_result_format.items():
    184. s='%s %s:%s'%(s,result_str,value)
    185. if return_info_comment['changes'] != {} and 'diff' in return_info_comment['changes']:
    186. print(s)
    187. #print(return_info_comment['changes'])
    188. print(return_info_comment['changes']['diff'])
    189. return content
    190. except Exception as e:
    191. print('ERROR:%s'%(e))
    192. if __name__ == "__main__":
    193. salt = SaltApi("https://192.168.1.21:8001")
    194. salt.remote_cmd_sync_test("bj-sjhl-c-app-test01-192.168.1.25,bj-sjhl-c-app-test02-192.168.1.26", "cmd.script", arg=["salt://scripts/test.sh","1 2 3 "])
    195. #salt.remote_cmd_sync_test("bj-sjhl-c-app-test01-192.168.1.25", "cmd.run", arg="ls -l /home/worker/opt/tomcat/webapps/test.war ")
    196. #salt.remote_cmd_sync("bj-sjhl-c-app-test0*", "cmd.run", arg="ls -l /home/worker/opt/tomcat/webapps/test.war ")

  • 相关阅读:
    氧化锌避雷器绝缘电阻测试
    最近5年133个Java面试问题列表
    《高性能网站建设进阶指南》阅读笔记
    linux 上设置系统时间
    代码随想录算法训练营第23期day53|1143.最长公共子序列、1035.不相交的线、53. 最大子序和
    前端 vite+vue3——写一个随机抽奖组件
    Java项目:家政服务系统(java+JSP+jquery+Servlet+Mysql)
    终端登录github两种方式
    vscode中Emmet语法的使用
    C++ Reference: Standard C++ Library reference: Containers: deque: deque: assign
  • 原文地址:https://blog.csdn.net/fhqsse220/article/details/126344579