messhy 0.5.0 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +52 -0
- data/lib/messhy/cli.rb +10 -0
- data/lib/messhy/configuration.rb +52 -0
- data/lib/messhy/dns_manager.rb +165 -0
- data/lib/messhy/health_checker.rb +42 -3
- data/lib/messhy/installer.rb +5 -0
- data/lib/messhy/version.rb +1 -1
- data/lib/messhy.rb +1 -0
- data/lib/tasks/messhy.rake +5 -0
- metadata +3 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 2789748ffdef7b5d7d46a0c58eed766cdfeb3f0a7f9acd69ffcc6d99def48c6d
|
|
4
|
+
data.tar.gz: 640f81d5ad62ca4d736fa5643080c91d68a616a23c18feba060fd7c5c91a8031
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 8bb76d383440f0ee413e92524d5dbc275c70f4765d9f971da21ba272753a30b7d479e7ca199a4dad13d46174a456c59af3056fe4887cb6ac1c2821c463bb1e5f
|
|
7
|
+
data.tar.gz: a142538a31aacffc7dd0a80854ae09c9c98bf8430f82200e58ae8bf3c7ad4d17b6a642b17374baf23752bd428a6874084ccdb1772fa45168d5f99c2350e95ded
|
data/README.md
CHANGED
|
@@ -72,6 +72,42 @@ messhy setup --environment=production
|
|
|
72
72
|
messhy status
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
+
When mesh DNS is enabled, `messhy status` also prints DNS server health and record counts.
|
|
76
|
+
|
|
77
|
+
## Mesh DNS (optional)
|
|
78
|
+
|
|
79
|
+
Messhy can set up a lightweight internal DNS (dnsmasq) for the mesh so you can
|
|
80
|
+
use stable hostnames instead of raw IPs. It installs dnsmasq on designated nodes
|
|
81
|
+
and configures all mesh nodes to resolve a private domain over `wg0`.
|
|
82
|
+
|
|
83
|
+
Example config:
|
|
84
|
+
|
|
85
|
+
```yaml
|
|
86
|
+
production:
|
|
87
|
+
<<: *shared
|
|
88
|
+
dns:
|
|
89
|
+
enabled: true
|
|
90
|
+
provider: dnsmasq
|
|
91
|
+
domain: mesh.internal
|
|
92
|
+
interface: wg0
|
|
93
|
+
servers:
|
|
94
|
+
- app-us-1
|
|
95
|
+
- app-eu-1
|
|
96
|
+
auto_records: true
|
|
97
|
+
records:
|
|
98
|
+
db-primary.mesh.internal:
|
|
99
|
+
- db-primary
|
|
100
|
+
- db-standby-1
|
|
101
|
+
db-replica.mesh.internal:
|
|
102
|
+
- db-standby-1
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
Apply DNS without touching WireGuard:
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
messhy dns --environment=production
|
|
109
|
+
```
|
|
110
|
+
|
|
75
111
|
## Secret Management
|
|
76
112
|
|
|
77
113
|
`messhy setup` stores generated WireGuard key pairs inside `.secrets/wireguard/*.yml` with `0600` permissions. Each node gets its own YAML file (`.secrets/wireguard/<node>.yml`) and all peer pre‑shared keys live in `.secrets/wireguard/psks.yml`. The directory is gitignored by default, and the Rails generator ensures the ignore rules are present in your application. After provisioning, copy the YAML files into 1Password (or another vault) and remove them from disk if you do not want long‑lived local copies.
|
|
@@ -187,6 +223,22 @@ See `config/mesh.example.yml` for a complete example.
|
|
|
187
223
|
- `mtu`: MTU size (default: `1280` for reliability)
|
|
188
224
|
- `listen_port`: WireGuard port (default: `51820`)
|
|
189
225
|
- `keepalive`: Keepalive interval in seconds (default: `25`)
|
|
226
|
+
- `dns`: Optional mesh DNS configuration (see below)
|
|
227
|
+
|
|
228
|
+
### DNS Options
|
|
229
|
+
|
|
230
|
+
When `dns.enabled: true`, messhy installs dnsmasq on the specified `dns.servers`
|
|
231
|
+
and configures all mesh nodes to resolve the `dns.domain` over the WireGuard
|
|
232
|
+
interface.
|
|
233
|
+
|
|
234
|
+
- `dns.enabled`: Enable mesh DNS
|
|
235
|
+
- `dns.provider`: `dnsmasq` (only provider today)
|
|
236
|
+
- `dns.domain`: Internal DNS domain (default: `mesh`)
|
|
237
|
+
- `dns.interface`: WireGuard interface (default: `wg0`)
|
|
238
|
+
- `dns.servers`: Node names that will run dnsmasq
|
|
239
|
+
- `dns.auto_records`: Auto-create `<node>.<domain>` for every node (default: `true`)
|
|
240
|
+
- `dns.records`: Extra records (values can be IPs or node names)
|
|
241
|
+
- `dns.ttl`: Local DNS TTL seconds (default: `30`)
|
|
190
242
|
|
|
191
243
|
### Node Configuration
|
|
192
244
|
|
data/lib/messhy/cli.rb
CHANGED
|
@@ -26,6 +26,16 @@ module Messhy
|
|
|
26
26
|
handle_ssh_error(e, config)
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
desc 'dns', 'Setup mesh DNS (dnsmasq)'
|
|
30
|
+
option :dry_run, type: :boolean, default: false
|
|
31
|
+
option :skip_node, type: :string
|
|
32
|
+
def dns
|
|
33
|
+
config = load_config
|
|
34
|
+
DnsManager.new(config, dry_run: options[:dry_run], skip: options[:skip_node]).setup
|
|
35
|
+
rescue SSHKit::Runner::ExecuteError => e
|
|
36
|
+
handle_ssh_error(e, config)
|
|
37
|
+
end
|
|
38
|
+
|
|
29
39
|
desc 'keygen', 'Generate WireGuard keys without deploying configs'
|
|
30
40
|
option :skip_node, type: :string
|
|
31
41
|
def keygen
|
data/lib/messhy/configuration.rb
CHANGED
|
@@ -7,6 +7,7 @@ module Messhy
|
|
|
7
7
|
attr_reader :environment,
|
|
8
8
|
:network,
|
|
9
9
|
:nodes,
|
|
10
|
+
:dns,
|
|
10
11
|
:user,
|
|
11
12
|
:ssh_key,
|
|
12
13
|
:mtu,
|
|
@@ -20,6 +21,7 @@ module Messhy
|
|
|
20
21
|
|
|
21
22
|
@network = env_config['network'] || '10.8.0.0/24'
|
|
22
23
|
@nodes = env_config['nodes'] || {}
|
|
24
|
+
@dns = env_config['dns'] || {}
|
|
23
25
|
@user = env_config['user'] || 'ubuntu'
|
|
24
26
|
@ssh_key = File.expand_path(env_config['ssh_key'] || '~/.ssh/id_rsa')
|
|
25
27
|
@mtu = env_config['mtu'] || 1280
|
|
@@ -68,6 +70,16 @@ module Messhy
|
|
|
68
70
|
raise Error, "Node #{name} missing 'private_ip'" unless config['private_ip']
|
|
69
71
|
end
|
|
70
72
|
|
|
73
|
+
if dns_enabled?
|
|
74
|
+
raise Error, 'DNS domain is required when dns is enabled' if dns_domain.to_s.strip.empty?
|
|
75
|
+
raise Error, 'DNS servers are required when dns is enabled' if dns_server_nodes.empty?
|
|
76
|
+
raise Error, "Unsupported DNS provider: #{dns_provider}" unless %w[dnsmasq].include?(dns_provider)
|
|
77
|
+
|
|
78
|
+
dns_server_nodes.each do |name|
|
|
79
|
+
raise Error, "DNS server node not found: #{name}" unless node_config(name)
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
|
|
71
83
|
true
|
|
72
84
|
end
|
|
73
85
|
|
|
@@ -83,5 +95,45 @@ module Messhy
|
|
|
83
95
|
:always
|
|
84
96
|
end
|
|
85
97
|
end
|
|
98
|
+
|
|
99
|
+
def dns_enabled?
|
|
100
|
+
return false if @dns.nil? || @dns.empty?
|
|
101
|
+
|
|
102
|
+
@dns.key?('enabled') ? @dns['enabled'] == true : true
|
|
103
|
+
end
|
|
104
|
+
|
|
105
|
+
def dns_provider
|
|
106
|
+
value = @dns['provider'] || 'dnsmasq'
|
|
107
|
+
value.to_s.strip
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def dns_domain
|
|
111
|
+
value = @dns['domain'] || 'mesh'
|
|
112
|
+
value.to_s.strip
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
def dns_interface
|
|
116
|
+
value = @dns['interface'] || 'wg0'
|
|
117
|
+
value.to_s.strip
|
|
118
|
+
end
|
|
119
|
+
|
|
120
|
+
def dns_ttl
|
|
121
|
+
value = @dns['ttl'] || 30
|
|
122
|
+
value.to_i
|
|
123
|
+
end
|
|
124
|
+
|
|
125
|
+
def dns_server_nodes
|
|
126
|
+
Array(@dns['servers']).map(&:to_s).reject(&:empty?)
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
def dns_records
|
|
130
|
+
@dns['records'] || {}
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
def dns_auto_records?
|
|
134
|
+
return true unless @dns.key?('auto_records')
|
|
135
|
+
|
|
136
|
+
@dns['auto_records'] == true
|
|
137
|
+
end
|
|
86
138
|
end
|
|
87
139
|
end
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'stringio'
|
|
4
|
+
|
|
5
|
+
module Messhy
|
|
6
|
+
class DnsManager
|
|
7
|
+
attr_reader :config, :ssh_executor, :dry_run
|
|
8
|
+
|
|
9
|
+
def initialize(config, ssh_executor: SSHExecutor.new(config), dry_run: false, skip: nil)
|
|
10
|
+
@config = config
|
|
11
|
+
@ssh_executor = ssh_executor
|
|
12
|
+
@dry_run = dry_run
|
|
13
|
+
@skip = skip
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def setup
|
|
17
|
+
return unless config.dns_enabled?
|
|
18
|
+
|
|
19
|
+
case config.dns_provider
|
|
20
|
+
when 'dnsmasq'
|
|
21
|
+
setup_dnsmasq
|
|
22
|
+
else
|
|
23
|
+
raise Error, "Unsupported DNS provider: #{config.dns_provider}"
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
private
|
|
28
|
+
|
|
29
|
+
def setup_dnsmasq
|
|
30
|
+
domain = config.dns_domain
|
|
31
|
+
interface = config.dns_interface
|
|
32
|
+
ttl = config.dns_ttl
|
|
33
|
+
server_nodes = config.dns_server_nodes
|
|
34
|
+
server_ips = server_nodes.map { |name| config.node_config(name)['private_ip'] }
|
|
35
|
+
|
|
36
|
+
records = build_records(domain)
|
|
37
|
+
|
|
38
|
+
server_nodes.each do |node|
|
|
39
|
+
next if @skip && node == @skip
|
|
40
|
+
|
|
41
|
+
server_ip = config.node_config(node)['private_ip']
|
|
42
|
+
conf = build_dnsmasq_conf(domain, interface, server_ip, records, ttl)
|
|
43
|
+
|
|
44
|
+
if dry_run
|
|
45
|
+
puts "[DRY RUN] Would install dnsmasq and write /etc/dnsmasq.d/messhy.conf on #{node}"
|
|
46
|
+
next
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
ssh_executor.execute_on_node(node) do
|
|
50
|
+
execute :sudo, 'apt-get', 'update', '-qq'
|
|
51
|
+
execute :sudo, 'DEBIAN_FRONTEND=noninteractive', 'apt-get', 'install', '-y', '-qq', 'dnsmasq'
|
|
52
|
+
upload! StringIO.new(conf), '/tmp/messhy-dns.conf'
|
|
53
|
+
execute :sudo, 'mv', '/tmp/messhy-dns.conf', '/etc/dnsmasq.d/messhy.conf'
|
|
54
|
+
execute :sudo, 'chown', 'root:root', '/etc/dnsmasq.d/messhy.conf'
|
|
55
|
+
execute :sudo, 'chmod', '644', '/etc/dnsmasq.d/messhy.conf'
|
|
56
|
+
execute :sudo, 'systemctl', 'enable', 'dnsmasq'
|
|
57
|
+
execute :sudo, 'systemctl', 'restart', 'dnsmasq'
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
config.each_node do |node_name, _|
|
|
62
|
+
next if @skip && node_name == @skip
|
|
63
|
+
|
|
64
|
+
if dry_run
|
|
65
|
+
puts "[DRY RUN] Would configure DNS on #{node_name} (#{interface}) for #{domain} -> #{server_ips.join(', ')}"
|
|
66
|
+
next
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
configure_client_dns(node_name, interface, domain, server_ips)
|
|
70
|
+
end
|
|
71
|
+
end
|
|
72
|
+
|
|
73
|
+
def configure_client_dns(node_name, interface, domain, server_ips)
|
|
74
|
+
ssh_executor.execute_on_node(node_name) do
|
|
75
|
+
if test('which', 'resolvectl', raise_on_error: false)
|
|
76
|
+
execute :sudo, 'systemctl', 'enable', '--now', 'systemd-resolved', raise_on_error: false
|
|
77
|
+
execute :sudo, 'resolvectl', 'dns', interface, *server_ips
|
|
78
|
+
execute :sudo, 'resolvectl', 'domain', interface, "~#{domain}"
|
|
79
|
+
execute :sudo, 'resolvectl', 'flush-caches', raise_on_error: false
|
|
80
|
+
elsif test('[ -d /etc/resolvconf/resolv.conf.d ]', raise_on_error: false)
|
|
81
|
+
head_path = '/etc/resolvconf/resolv.conf.d/head'
|
|
82
|
+
content = server_ips.map { |ip| "nameserver #{ip}" }.join("\n") + "\n"
|
|
83
|
+
upload! StringIO.new(content), '/tmp/messhy-resolv.conf'
|
|
84
|
+
execute :sudo, 'mv', '/tmp/messhy-resolv.conf', head_path
|
|
85
|
+
execute :sudo, 'chmod', '644', head_path
|
|
86
|
+
execute :sudo, 'resolvconf', '-u'
|
|
87
|
+
else
|
|
88
|
+
info 'resolvectl not found; skipping DNS config'
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def build_records(domain)
|
|
94
|
+
records = {}
|
|
95
|
+
|
|
96
|
+
if config.dns_auto_records?
|
|
97
|
+
config.each_node do |name, node_config|
|
|
98
|
+
hostname = "#{sanitize_dns_label(name)}.#{domain}"
|
|
99
|
+
records[hostname] ||= []
|
|
100
|
+
records[hostname] << node_config['private_ip']
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
config.dns_records.each do |hostname, targets|
|
|
105
|
+
fqdn = normalize_hostname(hostname, domain)
|
|
106
|
+
Array(targets).each do |target|
|
|
107
|
+
ip = resolve_target(target)
|
|
108
|
+
next if ip.to_s.strip.empty?
|
|
109
|
+
|
|
110
|
+
records[fqdn] ||= []
|
|
111
|
+
records[fqdn] << ip
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
records.transform_values { |ips| ips.uniq }
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
def resolve_target(target)
|
|
119
|
+
return '' if target.nil?
|
|
120
|
+
|
|
121
|
+
node = config.node_config(target.to_s)
|
|
122
|
+
return node['private_ip'] if node
|
|
123
|
+
|
|
124
|
+
target.to_s
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
def normalize_hostname(name, domain)
|
|
128
|
+
value = name.to_s.strip
|
|
129
|
+
return '' if value.empty?
|
|
130
|
+
|
|
131
|
+
return value if value.include?('.')
|
|
132
|
+
|
|
133
|
+
"#{sanitize_dns_label(value)}.#{domain}"
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
def sanitize_dns_label(value)
|
|
137
|
+
value.to_s.downcase.gsub(/[^a-z0-9-]/, '-')
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def build_dnsmasq_conf(domain, interface, server_ip, records, ttl)
|
|
141
|
+
lines = []
|
|
142
|
+
lines << '# Managed by messhy'
|
|
143
|
+
lines << 'domain-needed'
|
|
144
|
+
lines << 'bogus-priv'
|
|
145
|
+
lines << "local=/#{domain}/"
|
|
146
|
+
lines << "domain=#{domain}"
|
|
147
|
+
lines << 'expand-hosts'
|
|
148
|
+
lines << 'cache-size=1000'
|
|
149
|
+
lines << "local-ttl=#{ttl}"
|
|
150
|
+
lines << "interface=#{interface}"
|
|
151
|
+
lines << 'bind-interfaces'
|
|
152
|
+
lines << 'listen-address=127.0.0.1'
|
|
153
|
+
lines << "listen-address=#{server_ip}"
|
|
154
|
+
lines << ''
|
|
155
|
+
|
|
156
|
+
records.sort.each do |hostname, ips|
|
|
157
|
+
Array(ips).each do |ip|
|
|
158
|
+
lines << "address=/#{hostname}/#{ip}"
|
|
159
|
+
end
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
lines.join("\n") + "\n"
|
|
163
|
+
end
|
|
164
|
+
end
|
|
165
|
+
end
|
|
@@ -26,11 +26,15 @@ module Messhy
|
|
|
26
26
|
puts
|
|
27
27
|
end
|
|
28
28
|
|
|
29
|
+
show_dns_status if config.dns_enabled?
|
|
30
|
+
|
|
29
31
|
show_latency_matrix
|
|
30
32
|
end
|
|
31
33
|
|
|
32
34
|
def show_node_status(node_name)
|
|
33
35
|
node_config = config.node_config(node_name)
|
|
36
|
+
label = node_config['label']
|
|
37
|
+
label_display = label.to_s.strip.empty? ? '' : " (#{label})"
|
|
34
38
|
|
|
35
39
|
begin
|
|
36
40
|
status = @ssh_executor.get_wireguard_status(node_name)
|
|
@@ -39,7 +43,7 @@ module Messhy
|
|
|
39
43
|
peers = status.scan(/peer: (.+?)$/).flatten
|
|
40
44
|
|
|
41
45
|
if peers.any?
|
|
42
|
-
puts "✓ #{node_name} (#{node_config['private_ip']}) - connected to #{peers.size} peers"
|
|
46
|
+
puts "✓ #{node_name} (#{node_config['private_ip']})#{label_display} - connected to #{peers.size} peers"
|
|
43
47
|
|
|
44
48
|
# Show basic peer info
|
|
45
49
|
status.split('peer:').drop(1).each do |peer_block|
|
|
@@ -50,10 +54,10 @@ module Messhy
|
|
|
50
54
|
puts " └─ Peer: #{endpoint} - #{stats[:received]} rx, #{stats[:sent]} tx"
|
|
51
55
|
end
|
|
52
56
|
else
|
|
53
|
-
puts "✗ #{node_name} (#{node_config['private_ip']}) - 0 peers (DOWN)"
|
|
57
|
+
puts "✗ #{node_name} (#{node_config['private_ip']})#{label_display} - 0 peers (DOWN)"
|
|
54
58
|
end
|
|
55
59
|
rescue StandardError => e
|
|
56
|
-
puts "✗ #{node_name} (#{node_config['private_ip']}) - Error: #{e.message}"
|
|
60
|
+
puts "✗ #{node_name} (#{node_config['private_ip']})#{label_display} - Error: #{e.message}"
|
|
57
61
|
end
|
|
58
62
|
end
|
|
59
63
|
|
|
@@ -157,6 +161,41 @@ module Messhy
|
|
|
157
161
|
end
|
|
158
162
|
end
|
|
159
163
|
|
|
164
|
+
def show_dns_status
|
|
165
|
+
puts '==> Mesh DNS Status'
|
|
166
|
+
puts "Domain: #{config.dns_domain}"
|
|
167
|
+
puts "Servers: #{config.dns_server_nodes.join(', ')}"
|
|
168
|
+
puts
|
|
169
|
+
|
|
170
|
+
config.dns_server_nodes.each do |node_name|
|
|
171
|
+
node_config = config.node_config(node_name)
|
|
172
|
+
next unless node_config
|
|
173
|
+
|
|
174
|
+
label = node_config['label']
|
|
175
|
+
label_display = label.to_s.strip.empty? ? '' : " (#{label})"
|
|
176
|
+
|
|
177
|
+
begin
|
|
178
|
+
@ssh_executor.execute_on_node(node_name) do
|
|
179
|
+
service = capture(:systemctl, 'is-active', 'dnsmasq', raise_on_non_zero_exit: false).strip
|
|
180
|
+
messhy_records = capture(:bash, '-c',
|
|
181
|
+
"sudo awk 'BEGIN{c=0} /^address=\\//{c++} END{print c}' " \
|
|
182
|
+
"/etc/dnsmasq.d/messhy.conf 2>/dev/null || true").strip
|
|
183
|
+
ap_records = capture(:bash, '-c',
|
|
184
|
+
"sudo awk 'BEGIN{c=0} /^address=\\//{c++} END{print c}' " \
|
|
185
|
+
"/etc/dnsmasq.d/active_postgres.conf 2>/dev/null || true").strip
|
|
186
|
+
|
|
187
|
+
status_icon = service == 'active' ? '✓' : '✗'
|
|
188
|
+
puts "#{status_icon} #{node_name} (#{node_config['private_ip']})#{label_display} - dnsmasq #{service}"
|
|
189
|
+
puts " └─ records: messhy=#{messhy_records.to_i} active_postgres=#{ap_records.to_i}"
|
|
190
|
+
end
|
|
191
|
+
rescue StandardError => e
|
|
192
|
+
puts "✗ #{node_name} (#{node_config['private_ip']})#{label_display} - DNS check failed: #{e.message}"
|
|
193
|
+
end
|
|
194
|
+
end
|
|
195
|
+
|
|
196
|
+
puts
|
|
197
|
+
end
|
|
198
|
+
|
|
160
199
|
private
|
|
161
200
|
|
|
162
201
|
def show_latency_matrix
|
data/lib/messhy/installer.rb
CHANGED
|
@@ -57,6 +57,11 @@ module Messhy
|
|
|
57
57
|
puts "\n==> Verifying mesh connectivity..."
|
|
58
58
|
verify_mesh(skip: skip)
|
|
59
59
|
|
|
60
|
+
if config.dns_enabled?
|
|
61
|
+
puts "\n==> Setting up mesh DNS..."
|
|
62
|
+
DnsManager.new(config, ssh_executor: ssh_executor, dry_run: dry_run, skip: skip).setup
|
|
63
|
+
end
|
|
64
|
+
|
|
60
65
|
puts "\n✓ WireGuard mesh setup complete!"
|
|
61
66
|
end
|
|
62
67
|
|
data/lib/messhy/version.rb
CHANGED
data/lib/messhy.rb
CHANGED
data/lib/tasks/messhy.rake
CHANGED
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: messhy
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.6.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- BoringCache
|
|
@@ -122,6 +122,7 @@ files:
|
|
|
122
122
|
- lib/messhy.rb
|
|
123
123
|
- lib/messhy/cli.rb
|
|
124
124
|
- lib/messhy/configuration.rb
|
|
125
|
+
- lib/messhy/dns_manager.rb
|
|
125
126
|
- lib/messhy/generators/messhy/install_generator.rb
|
|
126
127
|
- lib/messhy/health_checker.rb
|
|
127
128
|
- lib/messhy/host_trust_manager.rb
|
|
@@ -156,7 +157,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
|
156
157
|
- !ruby/object:Gem::Version
|
|
157
158
|
version: '0'
|
|
158
159
|
requirements: []
|
|
159
|
-
rubygems_version: 3.
|
|
160
|
+
rubygems_version: 3.6.9
|
|
160
161
|
specification_version: 4
|
|
161
162
|
summary: WireGuard VPN mesh for Ruby & Rails apps
|
|
162
163
|
test_files: []
|