|
15 | 15 |
|
16 | 16 | """Compute v2 Server action implementations""" |
17 | 17 |
|
| 18 | +import argparse |
18 | 19 | import getpass |
19 | 20 | import logging |
20 | 21 | import os |
@@ -977,6 +978,164 @@ def take_action(self, parsed_args): |
977 | 978 | return zip(*sorted(data.iteritems())) |
978 | 979 |
|
979 | 980 |
|
| 981 | +class SshServer(command.Command): |
| 982 | + """Ssh to server""" |
| 983 | + |
| 984 | + log = logging.getLogger(__name__ + '.SshServer') |
| 985 | + |
| 986 | + def get_parser(self, prog_name): |
| 987 | + parser = super(SshServer, self).get_parser(prog_name) |
| 988 | + parser.add_argument( |
| 989 | + 'server', |
| 990 | + metavar='<server>', |
| 991 | + help='Server (name or ID)', |
| 992 | + ) |
| 993 | + parser.add_argument( |
| 994 | + '--login', |
| 995 | + metavar='<login-name>', |
| 996 | + help='Login name (ssh -l option)', |
| 997 | + ) |
| 998 | + parser.add_argument( |
| 999 | + '-l', |
| 1000 | + metavar='<login-name>', |
| 1001 | + help=argparse.SUPPRESS, |
| 1002 | + ) |
| 1003 | + parser.add_argument( |
| 1004 | + '--port', |
| 1005 | + metavar='<port>', |
| 1006 | + type=int, |
| 1007 | + help='Destination port (ssh -p option)', |
| 1008 | + ) |
| 1009 | + parser.add_argument( |
| 1010 | + '-p', |
| 1011 | + metavar='<port>', |
| 1012 | + dest='port', |
| 1013 | + type=int, |
| 1014 | + help=argparse.SUPPRESS, |
| 1015 | + ) |
| 1016 | + parser.add_argument( |
| 1017 | + '--identity', |
| 1018 | + metavar='<keyfile>', |
| 1019 | + help='Private key file (ssh -i option)', |
| 1020 | + ) |
| 1021 | + parser.add_argument( |
| 1022 | + '-i', |
| 1023 | + metavar='<filename>', |
| 1024 | + dest='identity', |
| 1025 | + help=argparse.SUPPRESS, |
| 1026 | + ) |
| 1027 | + parser.add_argument( |
| 1028 | + '--option', |
| 1029 | + metavar='<config-options>', |
| 1030 | + help='Options in ssh_config(5) format (ssh -o option)', |
| 1031 | + ) |
| 1032 | + parser.add_argument( |
| 1033 | + '-o', |
| 1034 | + metavar='<option>', |
| 1035 | + dest='option', |
| 1036 | + help=argparse.SUPPRESS, |
| 1037 | + ) |
| 1038 | + ip_group = parser.add_mutually_exclusive_group() |
| 1039 | + ip_group.add_argument( |
| 1040 | + '-4', |
| 1041 | + dest='ipv4', |
| 1042 | + action='store_true', |
| 1043 | + default=False, |
| 1044 | + help='Use only IPv4 addresses only', |
| 1045 | + ) |
| 1046 | + ip_group.add_argument( |
| 1047 | + '-6', |
| 1048 | + dest='ipv6', |
| 1049 | + action='store_true', |
| 1050 | + default=False, |
| 1051 | + help='Use only IPv6 addresses only', |
| 1052 | + ) |
| 1053 | + type_group = parser.add_mutually_exclusive_group() |
| 1054 | + type_group.add_argument( |
| 1055 | + '--public', |
| 1056 | + dest='address_type', |
| 1057 | + action='store_const', |
| 1058 | + const='public', |
| 1059 | + default='public', |
| 1060 | + help='Use public IP address', |
| 1061 | + ) |
| 1062 | + type_group.add_argument( |
| 1063 | + '--private', |
| 1064 | + dest='address_type', |
| 1065 | + action='store_const', |
| 1066 | + const='private', |
| 1067 | + default='public', |
| 1068 | + help='Use private IP address', |
| 1069 | + ) |
| 1070 | + type_group.add_argument( |
| 1071 | + '--address-type', |
| 1072 | + metavar='<address-type>', |
| 1073 | + dest='address_type', |
| 1074 | + default='public', |
| 1075 | + help='Use other IP address (public, private, etc)', |
| 1076 | + ) |
| 1077 | + parser.add_argument( |
| 1078 | + '-v', |
| 1079 | + dest='verbose', |
| 1080 | + action='store_true', |
| 1081 | + default=False, |
| 1082 | + help=argparse.SUPPRESS, |
| 1083 | + ) |
| 1084 | + return parser |
| 1085 | + |
| 1086 | + def take_action(self, parsed_args): |
| 1087 | + self.log.debug('take_action(%s)' % parsed_args) |
| 1088 | + |
| 1089 | + compute_client = self.app.client_manager.compute |
| 1090 | + server = utils.find_resource( |
| 1091 | + compute_client.servers, |
| 1092 | + parsed_args.server, |
| 1093 | + ) |
| 1094 | + |
| 1095 | + # Build the command |
| 1096 | + cmd = "ssh" |
| 1097 | + |
| 1098 | + # Look for address type |
| 1099 | + if parsed_args.address_type: |
| 1100 | + address_type = parsed_args.address_type |
| 1101 | + if address_type not in server.addresses: |
| 1102 | + raise SystemExit("ERROR: No %s IP address found" % address_type) |
| 1103 | + |
| 1104 | + # Set up desired address family |
| 1105 | + ip_address_family = [4, 6] |
| 1106 | + if parsed_args.ipv4: |
| 1107 | + ip_address_family = [4] |
| 1108 | + cmd += " -4" |
| 1109 | + if parsed_args.ipv6: |
| 1110 | + ip_address_family = [6] |
| 1111 | + cmd += " -6" |
| 1112 | + |
| 1113 | + # Grab the first matching IP address |
| 1114 | + ip_address = None |
| 1115 | + for addr in server.addresses[address_type]: |
| 1116 | + if int(addr['version']) in ip_address_family: |
| 1117 | + ip_address = addr['addr'] |
| 1118 | + if not ip_address: |
| 1119 | + raise SystemExit("ERROR: No IP address found") |
| 1120 | + |
| 1121 | + if parsed_args.port: |
| 1122 | + cmd += " -p %d" % parsed_args.port |
| 1123 | + if parsed_args.identity: |
| 1124 | + cmd += " -i %s" % parsed_args.identity |
| 1125 | + if parsed_args.option: |
| 1126 | + cmd += " -o %s" % parsed_args.option |
| 1127 | + if parsed_args.login: |
| 1128 | + login = parsed_args.login |
| 1129 | + else: |
| 1130 | + login = self.app.client_manager._username |
| 1131 | + if parsed_args.verbose: |
| 1132 | + cmd += " -v" |
| 1133 | + |
| 1134 | + cmd += " %s@%s" |
| 1135 | + self.log.debug("ssh command: %s" % (cmd % (login, ip_address))) |
| 1136 | + os.system(cmd % (login, ip_address)) |
| 1137 | + |
| 1138 | + |
980 | 1139 | class SuspendServer(command.Command): |
981 | 1140 | """Suspend server""" |
982 | 1141 |
|
|
0 commit comments