1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
|
##
## STUNNEL
##
#
# About stunnel
# --------------------------
#
# The network looks like this:
#
# From the client's perspective:
#
# |------- stunnel client --------------| |---------- stunnel server -----------------------|
# consumer app -> localhost:accept_port -> connect:connect_port -> ??
#
# From the server's perspective:
#
# |------- stunnel client --------------| |---------- stunnel server -----------------------|
# ?? -> *:accept_port -> localhost:connect_port -> service
#
module LeapCli
module Macro
#
# stunnel configuration for the client side.
#
# +node_list+ is a ObjectList of nodes running stunnel servers.
#
# +port+ is the real port of the ultimate service running on the servers
# that the client wants to connect to.
#
# * accept_port is the port on localhost to which local clients
# can connect. it is auto generated serially.
#
# * connect_port is the port on the stunnel server to connect to.
# it is auto generated from the +port+ argument.
#
# generates an entry appropriate to be passed directly to
# create_resources(stunnel::service, hiera('..'), defaults)
#
# local ports are automatically generated, starting at 4000
# and incrementing in sorted order (by node name).
#
def stunnel_client(node_list, port, options={})
@next_stunnel_port ||= 4000
node_list = listify(node_list)
hostnames(node_list) # record the hosts
result = Config::ObjectList.new
node_list.each_node do |node|
if node.name != self.name || options[:include_self]
s_port = stunnel_port(port)
result["#{node.name}_#{port}"] = Config::Object[
'accept_port', @next_stunnel_port,
'connect', node.domain.internal,
'connect_port', s_port,
'original_port', port
]
manager.connections.add(:from => @node.ip_address, :to => node.ip_address, :port => s_port)
@next_stunnel_port += 1
end
end
result
end
#
# generates a stunnel server entry.
#
# +port+ is the real port targeted service.
#
# * `accept_port` is the publicly bound port
# * `connect_port` is the port that the local service is running on.
#
def stunnel_server(port)
{
"accept_port" => stunnel_port(port),
"connect_port" => port
}
end
#
# lists the ips that connect to this node, on particular ports.
#
def stunnel_firewall
manager.connections.select {|connection|
connection['to'] == @node.ip_address
}
end
#
# what it the port of the couchdb we should connect to.
# host will always be localhost.
#
def couchdb_port
if services.include?('couchdb')
couch.port
else
stunnel.clients.couch_client.values.first.accept_port
end
end
private
#
# maps a real port to a stunnel port (used as the connect_port in the client config
# and the accept_port in the server config)
#
def stunnel_port(port)
port = port.to_i
if port < 50000
return port + 10000
else
return port - 10000
end
end
end
end
|