Advertisement
Guest User

Untitled

a guest
Jun 16th, 2017
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.03 KB | None | 0 0
  1. #!/usr/bin/python3.4
  2. """
  3. Custom inventory script for Ansible populated by the JSS
  4. """
  5.  
  6. from functools import lru_cache
  7. from os.path import dirname, realpath, join
  8. from urllib.parse import quote
  9. import argparse
  10. import json
  11. import configparser
  12. import requests
  13. import os
  14. import time
  15. # import pprint
  16.  
  17.  
  18. CACHE_PATH = os.path.expanduser('/etc/ansible/jss.inventory')
  19. REFRESH_THRESHOLD = 600 # time in seconds to wait before refreshing the cache
  20.  
  21.  
  22. class JSS:
  23.  
  24. def __init__(self, url, username, password):
  25. self.url = url
  26. self.username = username
  27. self.password = password
  28.  
  29. def get_all_computers(self):
  30. req = requests.get(self.url + '/JSSResource/computers',
  31. auth=(self.username, self.password),
  32. headers={'Accept': 'application/json'},
  33. verify='/etc/pki/ca-trust/source/anchors/ca.crt')
  34. if req.status_code == 200:
  35. return json.loads(req.content.decode('utf-8'))
  36. return None
  37.  
  38. @lru_cache(maxsize=None)
  39. def get_computer(self, id=None, name=None):
  40. if id:
  41. url = (self.url +
  42. '/JSSResource/computers/id/' +
  43. str(id))
  44. else:
  45. url = (self.url +
  46. '/JSSResource/computers/name/' +
  47. quote(name))
  48.  
  49. req = requests.get(url,
  50. auth=(self.username, self.password),
  51. headers={'Accept': 'application/json'},
  52. verify='/etc/pki/ca-trust/source/anchors/ca.crt')
  53. if req.status_code == 200:
  54. return json.loads(req.content.decode('utf-8'))
  55. return None
  56.  
  57. def get_all_computergroups(self):
  58. req = requests.get(self.url + '/JSSResource/computergroups',
  59. auth=(self.username, self.password),
  60. headers={'Accept': 'application/json'},
  61. verify='/etc/pki/ca-trust/source/anchors/ca.crt')
  62. if req.status_code == 200:
  63. return json.loads(req.content.decode('utf-8'))
  64. return None
  65.  
  66. def get_computergroup(self, id=None, name=None):
  67. if id:
  68. url = (self.url +
  69. '/JSSResource/computergroups/id/' +
  70. str(id))
  71. else:
  72. url = (self.url +
  73. '/JSSResource/computergroups/name/' +
  74. quote(name))
  75. req = requests.get(url,
  76. auth=(self.username, self.password),
  77. headers={'Accept': 'application/json'},
  78. verify='/etc/pki/ca-trust/source/anchors/ca.crt')
  79. if req.status_code == 200:
  80. return json.loads(req.content.decode('utf-8'))
  81. return None
  82.  
  83.  
  84. # Empty inventory for testing.
  85. def empty_inventory():
  86. return {'_meta': {'hostvars': {}}}
  87.  
  88.  
  89. def main(args=None):
  90. mypath = dirname(realpath(__file__))
  91. config = read_jss_config(join(dirname(mypath),
  92. '/root/.jss'),
  93. 'JSS')
  94. refresh_cache = args.refresh_cache
  95. cache_last_modified = os.stat(CACHE_PATH).st_mtime
  96.  
  97. jss = JSS(config['url'],
  98. config['api'][0],
  99. config['api'][1])
  100.  
  101. if args.host:
  102. print(json.dumps(empty_inventory()))
  103. exit(0)
  104.  
  105. if cache_last_modified < time.time() - REFRESH_THRESHOLD:
  106. refresh_cache = True
  107.  
  108. if refresh_cache:
  109. all = jss.get_all_computers()
  110. # print(jss.get_computer(name=all['computers'][0]['name']))
  111. computers = [jss.get_computer(name=x['name'])['computer']['general']['ip_address'] for x in all['computers']]
  112. ret = {'all': computers,
  113. '_meta': {'hostvars': {}}}
  114. for group in jss.get_all_computergroups()['computer_groups']:
  115. group = jss.get_computergroup(id=group['id'])
  116. name = group['computer_group']['name'].replace(' ', '_')
  117. ret[name] = []
  118. for computer in group['computer_group']['computers']:
  119. ret[name].append(jss.get_computer(name=computer['name'])['computer']['general']['ip_address'])
  120. with open(CACHE_PATH, 'w') as cache:
  121. cache.write(json.dumps(ret))
  122.  
  123. with open(CACHE_PATH, 'r') as cache:
  124. ret = json.loads(cache.read())
  125.  
  126. config = read_ansible_config(join(dirname(mypath),
  127. '/root/ansible.conf'),
  128. 'inventory')
  129. for computer in ret['all']:
  130. ret['_meta']['hostvars'][computer] = {'ansible_ssh_pass': config[0],
  131. 'ansible_become_pass': config[1]}
  132.  
  133. print(json.dumps(ret))
  134.  
  135.  
  136. def read_ansible_config(path, section):
  137. config = configparser.ConfigParser()
  138. config.read(path)
  139. return (config.get(section, 'ansible_ssh_pass'),
  140. config.get(section, 'ansible_become_pass'))
  141.  
  142.  
  143. def read_jss_config(path, section):
  144. '''Read the jss config and return a dictionary containing the
  145. parsed settings
  146. :path - Full path to the config file
  147. :section - Section name that contains the JSS info
  148. '''
  149. config = configparser.ConfigParser()
  150. config.read(path)
  151. return {'url': config.get(section, 'URL'),
  152. 'api': (config.get(section, 'username'),
  153. config.get(section, 'password')),
  154. 'repo': (config.get(section, 'repo_rw_username'),
  155. config.get(section, 'repo_rw_password'),
  156. config.get(section, 'repo_name'),
  157. config.get(section, 'repo_mount_point'))}
  158.  
  159.  
  160. if __name__ == '__main__':
  161. if not os.path.exists(CACHE_PATH):
  162. os.makedirs(os.path.dirname(CACHE_PATH), exist_ok=True)
  163. open(CACHE_PATH, 'a').close()
  164. os.utime(CACHE_PATH,
  165. (os.stat(CACHE_PATH).st_atime,
  166. os.stat(CACHE_PATH).st_mtime - REFRESH_THRESHOLD))
  167.  
  168. PARSER = argparse.ArgumentParser()
  169. PARSER.add_argument('--host', action='store')
  170. PARSER.add_argument('--list', action='store_true')
  171. PARSER.add_argument('--refresh-cache', action='store_true')
  172. main(PARSER.parse_args())
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement