vpc-tools.py 4.01 KB
Newer Older
e0d committed
1 2 3
"""VPC Tools.

Usage:
4
    vpc-tools.py ssh-config (vpc <vpc_id> | stack-name <stack_name>) identity-file <identity_file> user <user> [(config-file <config_file>)] [(strict-host-check <strict_host_check>)]
e0d committed
5 6 7 8 9 10 11 12 13 14
    vpc-tools.py (-h --help)
    vpc-tools.py (-v --version)

Options:
    -h --help       Show this screen.
    -v --version    Show version.

"""
import boto
from docopt import docopt
15
from vpcutil import vpc_for_stack_name
16 17
from vpcutil import stack_name_for_vpc
from collections import defaultdict
e0d committed
18 19 20 21


VERSION="vpc tools 0.1"
DEFAULT_USER="ubuntu"
22
DEFAULT_HOST_CHECK="ask"
e0d committed
23 24 25 26 27 28 29

JUMPBOX_CONFIG = """
    Host {jump_box}
      HostName {ip}
      IdentityFile {identity_file}
      ForwardAgent yes
      User {user}
30
      StrictHostKeyChecking {strict_host_check}
e0d committed
31 32
    """

e0d committed
33
HOST_CONFIG = """
34
    # Instance ID: {instance_id}
e0d committed
35
    Host {name}
36
      ProxyCommand ssh {config_file} -W %h:%p {jump_box}
e0d committed
37 38 39 40
      HostName {ip}
      IdentityFile {identity_file}
      ForwardAgent yes
      User {user}
41
      StrictHostKeyChecking {strict_host_check}
e0d committed
42 43 44 45 46 47 48 49 50
    """


def dispatch(args):

    if args.get("ssh-config"):
        _ssh_config(args)

def _ssh_config(args):
51 52
    if args.get("vpc"):
      vpc_id = args.get("<vpc_id>")
53
      stack_name = stack_name_for_vpc(vpc_id)
54 55 56 57
    elif args.get("stack-name"):
      stack_name = args.get("<stack_name>")
      vpc_id = vpc_for_stack_name(stack_name)
    else:
Feanil Patel committed
58
      raise Exception("No vpc_id or stack_name provided.")
e0d committed
59 60 61 62

    vpc = boto.connect_vpc()

    identity_file = args.get("<identity_file>")
63
    user = args.get("<user>")
64
    config_file = args.get("<config_file>")
65
    strict_host_check = args.get("<strict_host_check>")
66 67 68 69

    if not user:
      user = DEFAULT_USER

70 71 72
    if not strict_host_check:
      strict_host_check = DEFAULT_HOST_CHECK

73 74 75
    if config_file:
      config_file = "-F {}".format(config_file)
    else:
76
      config_file = ""
e0d committed
77

78 79 80
    jump_box = "{stack_name}-jumpbox".format(stack_name=stack_name)
    friendly = "{stack_name}-{logical_id}-{instance_number}"
    id_type_counter = defaultdict(int)
e0d committed
81 82 83 84 85 86

    reservations = vpc.get_all_instances(filters={'vpc-id' : vpc_id})

    for reservation in reservations:
        for instance in reservation.instances:

87 88 89
            if 'role' in instance.tags:
                logical_id = instance.tags['role']
            elif 'group' in instance.tags:
90 91 92 93 94
                logical_id = instance.tags['group']
            else:
                logical_id = instance.tags['aws:cloudformation:logical-id']
            instance_number = id_type_counter[logical_id]
            id_type_counter[logical_id] += 1
e0d committed
95

96
            if logical_id == "BastionHost" or logical_id == 'bastion':
e0d committed
97 98 99 100 101

                print JUMPBOX_CONFIG.format(
                    jump_box=jump_box,
                    ip=instance.ip_address,
                    user=user,
102 103
                    identity_file=identity_file,
                    strict_host_check=strict_host_check)
e0d committed
104

105 106 107 108 109 110 111 112 113 114 115
            # Print host config even for the bastion box because that is how
            # ansible accesses it.
            print HOST_CONFIG.format(
                name=instance.private_ip_address,
                jump_box=jump_box,
                ip=instance.private_ip_address,
                user=user,
                identity_file=identity_file,
                config_file=config_file,
                strict_host_check=strict_host_check,
                instance_id=instance.id)
e0d committed
116 117

            #duplicating for convenience with ansible
118
            name = friendly.format(stack_name=stack_name,
e0d committed
119
                                   logical_id=logical_id,
120 121
                                   instance_number=instance_number)

e0d committed
122 123
            print HOST_CONFIG.format(
                name=name,
e0d committed
124 125 126
                jump_box=jump_box,
                ip=instance.private_ip_address,
                user=user,
127
                identity_file=identity_file,
128
                config_file=config_file,
129 130
                strict_host_check=strict_host_check,
                instance_id=instance.id)
e0d committed
131 132 133

if __name__ == '__main__':
    args = docopt(__doc__, version=VERSION)
134
    dispatch(args)