/plugins/inventory/ssh_config.py

https://github.com/ajanthanm/ansible · Python · 111 lines · 55 code · 21 blank · 35 comment · 12 complexity · ddb24ce6ead5846ebd31209d7c77f786 MD5 · raw file

  1. #!/usr/bin/env python
  2. # (c) 2014, Tomas Karasek <tomas.karasek@digile.fi>
  3. #
  4. # This file is part of Ansible.
  5. #
  6. # Ansible is free software: you can redistribute it and/or modify
  7. # it under the terms of the GNU General Public License as published by
  8. # the Free Software Foundation, either version 3 of the License, or
  9. # (at your option) any later version.
  10. #
  11. # Ansible is distributed in the hope that it will be useful,
  12. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. # GNU General Public License for more details.
  15. #
  16. # You should have received a copy of the GNU General Public License
  17. # along with Ansible. If not, see <http://www.gnu.org/licenses/>.
  18. # Dynamic inventory script which lets you use aliases from ~/.ssh/config.
  19. #
  20. # It prints inventory based on parsed ~/.ssh/config. You can refer to hosts
  21. # with their alias, rather than with the IP or hostname. It takes advantage
  22. # of the ansible_ssh_{host,port,user,private_key_file}.
  23. #
  24. # If you have in your .ssh/config:
  25. # Host git
  26. # HostName git.domain.org
  27. # User tkarasek
  28. # IdentityFile /home/tomk/keys/thekey
  29. #
  30. # You can do
  31. # $ ansible git -m ping
  32. #
  33. # Example invocation:
  34. # ssh_config.py --list
  35. # ssh_config.py --host <alias>
  36. import argparse
  37. import os.path
  38. import sys
  39. import paramiko
  40. try:
  41. import json
  42. except ImportError:
  43. import simplejson as json
  44. _key = 'ssh_config'
  45. _ssh_to_ansible = [('user', 'ansible_ssh_user'),
  46. ('hostname', 'ansible_ssh_host'),
  47. ('identityfile', 'ansible_ssh_private_key_file'),
  48. ('port', 'ansible_ssh_port')]
  49. def get_config():
  50. with open(os.path.expanduser('~/.ssh/config')) as f:
  51. cfg = paramiko.SSHConfig()
  52. cfg.parse(f)
  53. ret_dict = {}
  54. for d in cfg._config:
  55. _copy = dict(d)
  56. del _copy['host']
  57. for host in d['host']:
  58. ret_dict[host] = _copy['config']
  59. return ret_dict
  60. def print_list():
  61. cfg = get_config()
  62. meta = {'hostvars': {}}
  63. for alias, attributes in cfg.items():
  64. tmp_dict = {}
  65. for ssh_opt, ans_opt in _ssh_to_ansible:
  66. if ssh_opt in attributes:
  67. tmp_dict[ans_opt] = attributes[ssh_opt]
  68. if tmp_dict:
  69. meta['hostvars'][alias] = tmp_dict
  70. print json.dumps({_key: list(set(meta['hostvars'].keys())), '_meta': meta})
  71. def print_host(host):
  72. cfg = get_config()
  73. print json.dumps(cfg[host])
  74. def get_args(args_list):
  75. parser = argparse.ArgumentParser(
  76. description='ansible inventory script parsing .ssh/config')
  77. mutex_group = parser.add_mutually_exclusive_group(required=True)
  78. help_list = 'list all hosts from .ssh/config inventory'
  79. mutex_group.add_argument('--list', action='store_true', help=help_list)
  80. help_host = 'display variables for a host'
  81. mutex_group.add_argument('--host', help=help_host)
  82. return parser.parse_args(args_list)
  83. def main(args_list):
  84. args = get_args(args_list)
  85. if args.list:
  86. print_list()
  87. if args.host:
  88. print_host(args.host)
  89. if __name__ == '__main__':
  90. main(sys.argv[1:])