Class: Messhy::SSHExecutor
- Inherits:
-
Object
- Object
- Messhy::SSHExecutor
- Includes:
- SSHKit::DSL
- Defined in:
- lib/messhy/ssh_executor.rb
Instance Attribute Summary collapse
-
#config ⇒ Object
readonly
Returns the value of attribute config.
Instance Method Summary collapse
- #enable_and_start_wireguard(node_name) ⇒ Object
- #execute_on_all_nodes(skip: nil) ⇒ Object
- #execute_on_node(node_name) ⇒ Object
- #generate_keypair_on_node(node_name) ⇒ Object
- #generate_psk_on_node(node_name) ⇒ Object
- #get_wireguard_status(node_name) ⇒ Object
-
#initialize(config) ⇒ SSHExecutor
constructor
A new instance of SSHExecutor.
- #install_wireguard(node_name) ⇒ Object
- #install_wireguard_on_all_nodes(skip: nil) ⇒ Object
- #measure_latency(source_node, target_ip) ⇒ Object
- #ping_node_from(source_node, target_ip) ⇒ Object
- #purge_wireguard(node_name) ⇒ Object
- #restart_wireguard(node_name) ⇒ Object
- #stop_wireguard(node_name) ⇒ Object
- #test_tcp_connectivity(source_node, target_ip, port = 22) ⇒ Object
- #upload_and_start_configs(configs) ⇒ Object
- #upload_config(node_name, config_content) ⇒ Object
Constructor Details
#initialize(config) ⇒ SSHExecutor
Returns a new instance of SSHExecutor.
13 14 15 16 |
# File 'lib/messhy/ssh_executor.rb', line 13 def initialize(config) @config = config setup_sshkit end |
Instance Attribute Details
#config ⇒ Object (readonly)
Returns the value of attribute config.
11 12 13 |
# File 'lib/messhy/ssh_executor.rb', line 11 def config @config end |
Instance Method Details
#enable_and_start_wireguard(node_name) ⇒ Object
141 142 143 144 145 146 147 148 149 150 151 152 153 |
# File 'lib/messhy/ssh_executor.rb', line 141 def enable_and_start_wireguard(node_name) execute_on_node(node_name) do # Enable systemd service execute :sudo, 'systemctl', 'enable', 'wg-quick@wg0' # Restart WireGuard if test('systemctl is-active wg-quick@wg0') execute :sudo, 'systemctl', 'restart', 'wg-quick@wg0' else execute :sudo, 'systemctl', 'start', 'wg-quick@wg0' end end end |
#execute_on_all_nodes(skip: nil) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/messhy/ssh_executor.rb', line 26 def execute_on_all_nodes(skip: nil, &) hosts = config.each_node.with_object([]) do |(node_name, node_config), collection| next if skip && node_name == skip collection << host_for(node_name, node_config) end return if hosts.empty? on(hosts, in: :parallel, &) end |
#execute_on_node(node_name) ⇒ Object
18 19 20 21 22 23 24 |
# File 'lib/messhy/ssh_executor.rb', line 18 def execute_on_node(node_name, &) node_config = config.node_config(node_name) raise Error, "Node not found: #{node_name}" unless node_config host = host_for(node_name, node_config) on(host, &) end |
#generate_keypair_on_node(node_name) ⇒ Object
60 61 62 63 64 65 66 67 |
# File 'lib/messhy/ssh_executor.rb', line 60 def generate_keypair_on_node(node_name) keypair = {} execute_on_node(node_name) do keypair[:private_key] = capture('wg', 'genkey').strip keypair[:public_key] = capture(:echo, keypair[:private_key], '|', 'wg', 'pubkey').strip end keypair end |
#generate_psk_on_node(node_name) ⇒ Object
69 70 71 72 73 74 75 |
# File 'lib/messhy/ssh_executor.rb', line 69 def generate_psk_on_node(node_name) psk = nil execute_on_node(node_name) do psk = capture('wg', 'genpsk').strip end psk end |
#get_wireguard_status(node_name) ⇒ Object
155 156 157 158 159 160 161 |
# File 'lib/messhy/ssh_executor.rb', line 155 def get_wireguard_status(node_name) result = nil execute_on_node(node_name) do result = capture(:sudo, 'wg', 'show', 'wg0') end result end |
#install_wireguard(node_name) ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 |
# File 'lib/messhy/ssh_executor.rb', line 38 def install_wireguard(node_name) execute_on_node(node_name) do # Check if WireGuard is already installed if test('[ -f /usr/bin/wg ]') info 'WireGuard already installed' else info 'Installing WireGuard...' execute :sudo, 'apt-get', 'update', '-qq' execute :sudo, 'DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', '-y', '-qq', 'wireguard', 'iputils-ping' end # Install ping if not available unless test('which', 'ping', raise_on_error: false) info 'Installing ping utility...' execute :sudo, 'apt-get', 'update', '-qq', raise_on_error: false execute :sudo, 'DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', '-y', '-qq', 'iputils-ping', raise_on_error: false end end end |
#install_wireguard_on_all_nodes(skip: nil) ⇒ Object
77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/messhy/ssh_executor.rb', line 77 def install_wireguard_on_all_nodes(skip: nil) execute_on_all_nodes(skip: skip) do # Check if WireGuard is already installed if test('[ -f /usr/bin/wg ]') info 'WireGuard already installed' else info 'Installing WireGuard...' execute :sudo, 'apt-get', 'update', '-qq' execute :sudo, 'DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', '-y', '-qq', 'wireguard', 'iputils-ping' end # Install ping if not available unless test('which', 'ping', raise_on_error: false) info 'Installing ping utility...' execute :sudo, 'apt-get', 'update', '-qq', raise_on_error: false execute :sudo, 'DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', '-y', '-qq', 'iputils-ping', raise_on_error: false end end end |
#measure_latency(source_node, target_ip) ⇒ Object
175 176 177 178 179 180 181 182 183 184 |
# File 'lib/messhy/ssh_executor.rb', line 175 def measure_latency(source_node, target_ip) latency = nil execute_on_node(source_node) do output = capture(:ping, '-c', '3', '-W', '2', '-I', 'wg0', target_ip, raise_on_non_zero_exit: false) latency = ::Regexp.last_match(1).to_f if output =~ %r{rtt min/avg/max/mdev = [\d.]+/([\d.]+)/} end latency rescue StandardError nil end |
#ping_node_from(source_node, target_ip) ⇒ Object
163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/messhy/ssh_executor.rb', line 163 def ping_node_from(source_node, target_ip) success = false execute_on_node(source_node) do if test('which', 'ping', raise_on_error: false) success = test('timeout', '3', 'ping', '-c', '1', '-W', '1', '-I', 'wg0', target_ip, raise_on_error: false) end end success rescue StandardError false end |
#purge_wireguard(node_name) ⇒ Object
220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/messhy/ssh_executor.rb', line 220 def purge_wireguard(node_name) execute_on_node(node_name) do # Stop and disable service if test('systemctl is-active wg-quick@wg0', raise_on_error: false) execute :sudo, 'systemctl', 'stop', 'wg-quick@wg0', raise_on_error: false end if test('systemctl is-enabled wg-quick@wg0', raise_on_error: false) execute :sudo, 'systemctl', 'disable', 'wg-quick@wg0', raise_on_error: false end # Remove interface if test('[ -d /sys/class/net/wg0 ]', raise_on_error: false) execute :sudo, 'ip', 'link', 'delete', 'wg0', raise_on_error: false end # Remove config if test('[ -f /etc/wireguard/wg0.conf ]', raise_on_error: false) execute :sudo, 'rm', '-f', '/etc/wireguard/wg0.conf', raise_on_error: false end end end |
#restart_wireguard(node_name) ⇒ Object
197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 |
# File 'lib/messhy/ssh_executor.rb', line 197 def restart_wireguard(node_name) execute_on_node(node_name) do # Stop service first if test('systemctl is-active wg-quick@wg0', raise_on_error: false) execute :sudo, 'systemctl', 'stop', 'wg-quick@wg0' end # Remove interface if it exists if test('[ -d /sys/class/net/wg0 ]', raise_on_error: false) execute :sudo, 'ip', 'link', 'delete', 'wg0', raise_on_error: false end # Start fresh execute :sudo, 'systemctl', 'start', 'wg-quick@wg0' end end |
#stop_wireguard(node_name) ⇒ Object
214 215 216 217 218 |
# File 'lib/messhy/ssh_executor.rb', line 214 def stop_wireguard(node_name) execute_on_node(node_name) do execute :sudo, 'systemctl', 'stop', 'wg-quick@wg0' if test('systemctl is-active wg-quick@wg0') end end |
#test_tcp_connectivity(source_node, target_ip, port = 22) ⇒ Object
186 187 188 189 190 191 192 193 194 195 |
# File 'lib/messhy/ssh_executor.rb', line 186 def test_tcp_connectivity(source_node, target_ip, port = 22) success = false execute_on_node(source_node) do success = test('timeout', '2', 'bash', '-c', "exec 3<>/dev/tcp/#{target_ip}/#{port} 2>&1 && exec 3<&- && exec 3>&-", raise_on_error: false) end success rescue StandardError false end |
#upload_and_start_configs(configs) ⇒ Object
111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/messhy/ssh_executor.rb', line 111 def upload_and_start_configs(configs) hosts = configs.filter_map do |node_name, config_content| node_config = config.node_config(node_name) next unless node_config host = host_for(node_name, node_config) manage_property(host.properties, :config_content, config_content) host end return if hosts.empty? executor = self on hosts, in: :parallel do |host| properties = host.properties config_content = executor.send(:manage_property, properties, :config_content) temp_file = '/tmp/wg0.conf' upload! StringIO.new(config_content), temp_file execute :sudo, 'mv', temp_file, '/etc/wireguard/wg0.conf' execute :sudo, 'chmod', '600', '/etc/wireguard/wg0.conf' execute :sudo, 'systemctl', 'enable', 'wg-quick@wg0' if test('systemctl is-active wg-quick@wg0') execute :sudo, 'systemctl', 'restart', 'wg-quick@wg0' else execute :sudo, 'systemctl', 'start', 'wg-quick@wg0' end end end |
#upload_config(node_name, config_content) ⇒ Object
99 100 101 102 103 104 105 106 107 108 109 |
# File 'lib/messhy/ssh_executor.rb', line 99 def upload_config(node_name, config_content) execute_on_node(node_name) do # Create temporary file temp_file = '/tmp/wg0.conf' upload! StringIO.new(config_content), temp_file # Move to /etc/wireguard with proper permissions execute :sudo, 'mv', temp_file, '/etc/wireguard/wg0.conf' execute :sudo, 'chmod', '600', '/etc/wireguard/wg0.conf' end end |