PageRenderTime 22ms CodeModel.GetById 10ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 0ms

/plugins/inventory/ssh_config.py

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