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    if user is None or host is None:
33        raise ValueError('Malformed SSH config did not include user and '
34                         'host keys: %s' % config)
35
36    return SshSettings(host, user, port=port, identity_file=identity_file)
37
38
39class SshSettings(object):
40    """Contains settings for ssh.
41
42    Container for ssh connection settings.
43
44    Attributes:
45        username: The name of the user to log in as.
46        hostname: The name of the host to connect to.
47        executable: The ssh executable to use.
48        port: The port to connect through (usually 22).
49        host_file: The known host file to use.
50        connect_timeout: How long to wait on a connection before giving a
51                         timeout.
52        alive_interval: How long between ssh heartbeat signals to keep the
53                        connection alive.
54    """
55
56    def __init__(self,
57                 hostname,
58                 username,
59                 port=22,
60                 host_file='/dev/null',
61                 connect_timeout=30,
62                 alive_interval=300,
63                 executable='/usr/bin/ssh',
64                 identity_file=None):
65        self.username = username
66        self.hostname = hostname
67        self.executable = executable
68        self.port = port
69        self.host_file = host_file
70        self.connect_timeout = connect_timeout
71        self.alive_interval = alive_interval
72        self.identity_file = identity_file
73
74    def construct_ssh_options(self):
75        """Construct the ssh options.
76
77        Constructs a dictionary of option that should be used with the ssh
78        command.
79
80        Returns:
81            A dictionary of option name to value.
82        """
83        current_options = {}
84        current_options['StrictHostKeyChecking'] = False
85        current_options['UserKnownHostsFile'] = self.host_file
86        current_options['ConnectTimeout'] = self.connect_timeout
87        current_options['ServerAliveInterval'] = self.alive_interval
88        return current_options
89
90    def construct_ssh_flags(self):
91        """Construct the ssh flags.
92
93        Constructs what flags should be used in the ssh connection.
94
95        Returns:
96            A dictonary of flag name to value. If value is none then it is
97            treated as a binary flag.
98        """
99        current_flags = {}
100        current_flags['-a'] = None
101        current_flags['-x'] = None
102        current_flags['-p'] = self.port
103        if self.identity_file:
104            current_flags['-i'] = self.identity_file
105        return current_flags
106