blob: c494b8d6c684246dba439271d9ccde550b802f9b [file] [log] [blame]
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +02001import abc
koder aka kdanilove7e1a4d2016-12-17 20:29:52 +02002from typing import Any, Set, Optional, Dict, NamedTuple, Optional
koder aka kdanilov73084622016-11-16 21:51:08 +02003from .ssh_utils import ConnCreds
4from .common_types import IPAddr
5
6
7RPCCreds = NamedTuple("RPCCreds", [("addr", IPAddr), ("key_file", str), ("cert_file", str)])
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +02008
9
10class NodeInfo:
koder aka kdanilov73084622016-11-16 21:51:08 +020011 """Node information object, result of discovery process or config parsing"""
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020012 def __init__(self, ssh_creds: ConnCreds, roles: Set[str], params: Dict[str, Any] = None) -> None:
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020013
koder aka kdanilov73084622016-11-16 21:51:08 +020014 # ssh credentials
15 self.ssh_creds = ssh_creds
16 # credentials for RPC connection
17 self.rpc_creds = None # type: Optional[RPCCreds]
18 self.roles = roles
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020019 self.os_vm_id = None # type: Optional[int]
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020020 self.params = {} # type: Dict[str, Any]
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020021 if params is not None:
22 self.params = params
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020023
koder aka kdanilov73084622016-11-16 21:51:08 +020024 def node_id(self) -> str:
25 return "{0.host}:{0.port}".format(self.ssh_creds.addr)
26
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020027 def __str__(self) -> str:
28 return self.node_id()
29
30 def __repr__(self) -> str:
31 return str(self)
32
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020033
34class ISSHHost(metaclass=abc.ABCMeta):
35 """Minimal interface, required to setup RPC connection"""
36 info = None # type: NodeInfo
37
38 @abc.abstractmethod
39 def run(self, cmd: str, timeout: int = 60, nolog: bool = False) -> str:
40 pass
41
42 @abc.abstractmethod
koder aka kdanilov73084622016-11-16 21:51:08 +020043 def __str__(self) -> str:
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020044 pass
45
46 @abc.abstractmethod
koder aka kdanilov73084622016-11-16 21:51:08 +020047 def disconnect(self) -> None:
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020048 pass
49
50 @abc.abstractmethod
koder aka kdanilove7e1a4d2016-12-17 20:29:52 +020051 def put_to_file(self, path: Optional[str], content: bytes) -> str:
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020052 pass
53
koder aka kdanilov73084622016-11-16 21:51:08 +020054 def __enter__(self) -> 'ISSHHost':
55 return self
56
57 def __exit__(self, x, y, z) -> bool:
58 self.disconnect()
59 return False
60
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020061
62class IRPCNode(metaclass=abc.ABCMeta):
63 """Remote filesystem interface"""
64 info = None # type: NodeInfo
koder aka kdanilov70227062016-11-26 23:23:21 +020065 conn = None # type: Any
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020066 rpc_log_file = None # type: str
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020067
68 @abc.abstractmethod
koder aka kdanilovbbbe1dc2016-12-20 01:19:56 +020069 def __str__(self) -> str:
70 pass
71
72 @abc.abstractmethod
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020073 def run(self, cmd: str, timeout: int = 60, nolog: bool = False) -> str:
74 pass
75
76 @abc.abstractmethod
77 def copy_file(self, local_path: str, remote_path: str = None) -> str:
78 pass
79
80 @abc.abstractmethod
81 def get_file_content(self, path: str) -> bytes:
82 pass
83
84 @abc.abstractmethod
koder aka kdanilove7e1a4d2016-12-17 20:29:52 +020085 def put_to_file(self, path: Optional[str], content: bytes) -> str:
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020086 pass
87
88 @abc.abstractmethod
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020089 def stat_file(self, path:str) -> Any:
90 pass
91
92 @abc.abstractmethod
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +020093 def disconnect(self) -> str:
94 pass
95
koder aka kdanilov962ee5f2016-12-19 02:40:08 +020096 @abc.abstractmethod
97 def upload_plugin(self, name: str, code: bytes, version: str = None) -> None:
98 pass
99
koder aka kdanilov73084622016-11-16 21:51:08 +0200100 def __enter__(self) -> 'IRPCNode':
101 return self
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +0200102
koder aka kdanilov73084622016-11-16 21:51:08 +0200103 def __exit__(self, x, y, z) -> bool:
104 self.disconnect()
105 return False
koder aka kdanilov3d2bc4f2016-11-12 18:31:18 +0200106