blob: 43ba44a607b63884bc17eae19cd697e6e766ab7c [file] [log] [blame]
koder aka kdanilove06762a2015-03-22 23:32:09 +02001import re
koder aka kdanilov3a6633e2015-03-26 18:20:00 +02002import getpass
koder aka kdanilov73084622016-11-16 21:51:08 +02003from typing import List
koder aka kdanilov22d134e2016-11-08 11:33:19 +02004
koder aka kdanilove06762a2015-03-22 23:32:09 +02005
koder aka kdanilov73084622016-11-16 21:51:08 +02006from .common_types import IPAddr
koder aka kdanilove06762a2015-03-22 23:32:09 +02007
8
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +02009class URIsNamespace:
10 class ReParts:
koder aka kdanilove06762a2015-03-22 23:32:09 +020011 user_rr = "[^:]*?"
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +030012 host_rr = "[^:@]*?"
koder aka kdanilove06762a2015-03-22 23:32:09 +020013 port_rr = "\\d+"
14 key_file_rr = "[^:@]*"
15 passwd_rr = ".*?"
16
17 re_dct = ReParts.__dict__
18
19 for attr_name, val in re_dct.items():
20 if attr_name.endswith('_rr'):
21 new_rr = "(?P<{0}>{1})".format(attr_name[:-3], val)
22 setattr(ReParts, attr_name, new_rr)
23
24 re_dct = ReParts.__dict__
25
26 templs = [
27 "^{host_rr}$",
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +030028 "^{host_rr}:{port_rr}$",
koder aka kdanilov416b87a2015-05-12 00:26:04 +030029 "^{host_rr}::{key_file_rr}$",
30 "^{host_rr}:{port_rr}:{key_file_rr}$",
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +030031 "^{user_rr}@{host_rr}$",
32 "^{user_rr}@{host_rr}:{port_rr}$",
koder aka kdanilove06762a2015-03-22 23:32:09 +020033 "^{user_rr}@{host_rr}::{key_file_rr}$",
34 "^{user_rr}@{host_rr}:{port_rr}:{key_file_rr}$",
koder aka kdanilov7e0f7cf2015-05-01 17:24:35 +030035 "^{user_rr}:{passwd_rr}@{host_rr}$",
36 "^{user_rr}:{passwd_rr}@{host_rr}:{port_rr}$",
koder aka kdanilove06762a2015-03-22 23:32:09 +020037 ]
38
koder aka kdanilov22d134e2016-11-08 11:33:19 +020039 uri_reg_exprs = [] # type: List[str]
koder aka kdanilove06762a2015-03-22 23:32:09 +020040 for templ in templs:
41 uri_reg_exprs.append(templ.format(**re_dct))
42
43
koder aka kdanilov22d134e2016-11-08 11:33:19 +020044class ConnCreds:
koder aka kdanilov73084622016-11-16 21:51:08 +020045 def __init__(self, host: str, user: str, passwd: str = None, port: int = 22,
46 key_file: str = None, key: bytes = None) -> None:
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020047 self.user = user
48 self.passwd = passwd
koder aka kdanilov73084622016-11-16 21:51:08 +020049 self.addr = IPAddr(host, port)
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020050 self.key_file = key_file
koder aka kdanilov73084622016-11-16 21:51:08 +020051 self.key = key
koder aka kdanilov22d134e2016-11-08 11:33:19 +020052
53 def __str__(self) -> str:
koder aka kdanilov73084622016-11-16 21:51:08 +020054 return "{}@{}:{}".format(self.user, self.addr.host, self.addr.port)
koder aka kdanilov22d134e2016-11-08 11:33:19 +020055
56
koder aka kdanilov22d134e2016-11-08 11:33:19 +020057def parse_ssh_uri(uri: str) -> ConnCreds:
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020058 """Parse ssh connection URL from one of following form
59 [ssh://]user:passwd@host[:port]
60 [ssh://][user@]host[:port][:key_file]
61 """
koder aka kdanilove06762a2015-03-22 23:32:09 +020062
koder aka kdanilov4d4771c2015-04-23 01:32:02 +030063 if uri.startswith("ssh://"):
64 uri = uri[len("ssh://"):]
65
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020066 res = ConnCreds("", getpass.getuser())
koder aka kdanilove06762a2015-03-22 23:32:09 +020067
koder aka kdanilov22d134e2016-11-08 11:33:19 +020068 for rr in URIsNamespace.uri_reg_exprs:
koder aka kdanilove06762a2015-03-22 23:32:09 +020069 rrm = re.match(rr, uri)
70 if rrm is not None:
71 res.__dict__.update(rrm.groupdict())
72 return res
koder aka kdanilov652cd802015-04-13 12:21:07 +030073
koder aka kdanilove06762a2015-03-22 23:32:09 +020074 raise ValueError("Can't parse {0!r} as ssh uri value".format(uri))
75
76