refactoring is on the way
diff --git a/wally/node_interfaces.py b/wally/node_interfaces.py
index e0b56aa..e75c2a3 100644
--- a/wally/node_interfaces.py
+++ b/wally/node_interfaces.py
@@ -1,27 +1,27 @@
 import abc
-from typing import Any, Set, Optional, List, Dict, Callable
+from typing import Any, Set, Optional, List, Dict, Callable, NamedTuple
+from .ssh_utils import ConnCreds
+from .common_types import IPAddr
+
+
+RPCCreds = NamedTuple("RPCCreds", [("addr", IPAddr), ("key_file", str), ("cert_file", str)])
 
 
 class NodeInfo:
-    """Node information object, result of dicovery process or config parsing"""
+    """Node information object, result of discovery process or config parsing"""
+    def __init__(self, ssh_creds: ConnCreds, roles: Set[str]) -> None:
 
-    def __init__(self,
-                 ssh_conn_url: str,
-                 roles: Set[str],
-                 hops: List['NodeInfo'] = None,
-                 ssh_key: bytes = None) -> None:
-
-        self.hops = []  # type: List[NodeInfo]
-        if hops is not None:
-            self.hops = hops
-
-        self.ssh_conn_url = ssh_conn_url  # type: str
-        self.rpc_conn_url = None  # type: str
-        self.roles = roles  # type: Set[str]
+        # ssh credentials
+        self.ssh_creds = ssh_creds
+        # credentials for RPC connection
+        self.rpc_creds = None  # type: Optional[RPCCreds]
+        self.roles = roles
         self.os_vm_id = None  # type: Optional[int]
-        self.ssh_key = ssh_key  # type: Optional[bytes]
         self.params = {}  # type: Dict[str, Any]
 
+    def node_id(self) -> str:
+        return "{0.host}:{0.port}".format(self.ssh_creds.addr)
+
 
 class ISSHHost(metaclass=abc.ABCMeta):
     """Minimal interface, required to setup RPC connection"""
@@ -32,17 +32,24 @@
         pass
 
     @abc.abstractmethod
-    def get_ip(self) -> str:
+    def __str__(self) -> str:
         pass
 
     @abc.abstractmethod
-    def __str__(self) -> str:
+    def disconnect(self) -> None:
         pass
 
     @abc.abstractmethod
     def put_to_file(self, path: str, content: bytes) -> None:
         pass
 
+    def __enter__(self) -> 'ISSHHost':
+        return self
+
+    def __exit__(self, x, y, z) -> bool:
+        self.disconnect()
+        return False
+
 
 class IRPCNode(metaclass=abc.ABCMeta):
     """Remote filesystem interface"""
@@ -65,10 +72,6 @@
         pass
 
     @abc.abstractmethod
-    def forward_port(self, ip: str, remote_port: int, local_port: int = None) -> int:
-        pass
-
-    @abc.abstractmethod
     def get_interface(self, ip: str) -> str:
         pass
 
@@ -77,14 +80,13 @@
         pass
 
     @abc.abstractmethod
-    def node_id(self) -> str:
-        pass
-
-
-    @abc.abstractmethod
     def disconnect(self) -> str:
         pass
 
+    def __enter__(self) -> 'IRPCNode':
+        return self
 
+    def __exit__(self, x, y, z) -> bool:
+        self.disconnect()
+        return False
 
-RPCBeforeConnCallback = Callable[[NodeInfo, int], None]
\ No newline at end of file