1# Copyright 2016 - The Android Open Source Project
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14"""Create a SshSettings from a dictionary from an ACTS config
15
16Args:
17    config dict instance from an ACTS config
18
19Returns:
20    An instance of SshSettings or None
21"""
22
23
24def from_config(config):
25    if config is None:
26        return None  # Having no settings is not an error
27
28    user = config.get('user', None)
29    host = config.get('host', None)
30    port = config.get('port', 22)
31    identity_file = config.get('identity_file', None)
32    ssh_config = config.get('ssh_config', None)
33    connect_timeout = config.get('connect_timeout', 30)
34    if user is None or host is None:
35        raise ValueError('Malformed SSH config did not include user and '
36                         'host keys: %s' % config)
37
38    return SshSettings(host, user, port=port, identity_file=identity_file,
39                       ssh_config=ssh_config, connect_timeout=connect_timeout)
40
41
42class SshSettings(object):
43    """Contains settings for ssh.
44
45    Container for ssh connection settings.
46
47    Attributes:
48        username: The name of the user to log in as.
49        hostname: The name of the host to connect to.
50        executable: The ssh executable to use.
51        port: The port to connect through (usually 22).
52        host_file: The known host file to use.
53        connect_timeout: How long to wait on a connection before giving a
54                         timeout.
55        alive_interval: How long between ssh heartbeat signals to keep the
56                        connection alive.
57    """
58
59    def __init__(self,
60                 hostname,
61                 username,
62                 port=22,
63                 host_file='/dev/null',
64                 connect_timeout=30,
65                 alive_interval=300,
66                 executable='/usr/bin/ssh',
67                 identity_file=None,
68                 ssh_config=None):
69        self.username = username
70        self.hostname = hostname
71        self.executable = executable
72        self.port = port
73        self.host_file = host_file
74        self.connect_timeout = connect_timeout
75        self.alive_interval = alive_interval
76        self.identity_file = identity_file
77        self.ssh_config = ssh_config
78
79    def construct_ssh_options(self):
80        """Construct the ssh options.
81
82        Constructs a dictionary of option that should be used with the ssh
83        command.
84
85        Returns:
86            A dictionary of option name to value.
87        """
88        current_options = {}
89        current_options['StrictHostKeyChecking'] = False
90        current_options['UserKnownHostsFile'] = self.host_file
91        current_options['ConnectTimeout'] = self.connect_timeout
92        current_options['ServerAliveInterval'] = self.alive_interval
93        return current_options
94
95    def construct_ssh_flags(self):
96        """Construct the ssh flags.
97
98        Constructs what flags should be used in the ssh connection.
99
100        Returns:
101            A dictonary of flag name to value. If value is none then it is
102            treated as a binary flag.
103        """
104        current_flags = {}
105        current_flags['-a'] = None
106        current_flags['-x'] = None
107        current_flags['-p'] = self.port
108        if self.identity_file:
109            current_flags['-i'] = self.identity_file
110        if self.ssh_config:
111            current_flags['-F'] = self.ssh_config
112        return current_flags
113