Module: LeapCli::Config::Macros
- Included in:
- Object
- Defined in:
- lib/leap_cli/config/macros.rb
Defined Under Namespace
Classes: AssertionFailed, FileMissing
Instance Method Summary collapse
- #assert(assertion) ⇒ Object
-
#authorized_keys ⇒ Object
Creates a hash from the ssh key info in users directory, for use in updating authorized_keys file.
-
#file(filename, options = {}) ⇒ Object
inserts the contents of a file.
-
#file_path(path) ⇒ Object
returns what the file path will be, once the file is rsynced to the server.
-
#fingerprint(filename) ⇒ Object
return a fingerprint for a x509 certificate.
-
#haproxy_servers(node_list, stunnel_clients, non_stunnel_port = nil) ⇒ Object
creates a hash suitable for configuring haproxy.
-
#hex_secret(name, bit_length = 128) ⇒ Object
inserts an hexidecimal secret string, generating it if needed.
-
#hostnames(nodes) ⇒ Object
records the list of hosts that are encountered for this node.
-
#hosts_file(nodes = nil) ⇒ Object
Generates entries needed for updating /etc/hosts on a node (as a hash).
-
#nodes ⇒ Object
the list of all the nodes.
-
#nodes_like_me ⇒ Object
returns a list of nodes that match the same environment.
-
#provider ⇒ Object
grab an environment appropriate provider.
-
#secret(name, length = 32) ⇒ Object
inserts a named secret, generating it if needed.
-
#stunnel_client(node_list, port, options = {}) ⇒ Object
stunnel configuration for the client side.
-
#stunnel_port(port) ⇒ Object
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).
-
#stunnel_server(port) ⇒ Object
generates a stunnel server entry.
-
#try_file(filename) ⇒ Object
like #file, but allow missing files.
Instance Method Details
#assert(assertion) ⇒ Object
397 398 399 400 401 402 403 |
# File 'lib/leap_cli/config/macros.rb', line 397 def assert(assertion) if instance_eval(assertion) true else raise AssertionFailed.new(assertion) end end |
#authorized_keys ⇒ Object
Creates a hash from the ssh key info in users directory, for use in updating authorized_keys file. Additionally, the ‘monitor’ public key is included, which is used by the monitor nodes to run particular commands remotely.
342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 |
# File 'lib/leap_cli/config/macros.rb', line 342 def hash = {} keys = Dir.glob(Path.named_path([:user_ssh, '*'])) keys.sort.each do |keyfile| ssh_type, ssh_key = File.read(keyfile).strip.split(" ") name = File.basename(File.dirname(keyfile)) hash[name] = { "type" => ssh_type, "key" => ssh_key } end ssh_type, ssh_key = File.read(Path.named_path(:monitor_pub_key)).strip.split(" ") hash[Leap::Platform.monitor_username] = { "type" => ssh_type, "key" => ssh_key } hash end |
#file(filename, options = {}) ⇒ Object
inserts the contents of a file
56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 |
# File 'lib/leap_cli/config/macros.rb', line 56 def file(filename, ={}) if filename.is_a? Symbol filename = [filename, @node.name] end filepath = Path.find_file(filename) if filepath if filepath =~ /\.erb$/ ERB.new(File.read(filepath), nil, '%<>').result(binding) else File.read(filepath) end else raise FileMissing.new(Path.named_path(filename), ) "" end end |
#file_path(path) ⇒ Object
returns what the file path will be, once the file is rsynced to the server. an internal list of discovered file paths is saved, in order to rsync these files when needed.
notes:
-
argument ‘path’ is relative to Path.provider/files or Path.provider_base/files
-
the path returned by this method is absolute
-
the path stored for use later by rsync is relative to Path.provider
-
if the path does not exist locally, but exists in provider_base, then the default file from provider_base is copied locally. this is required for rsync to work correctly.
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 119 |
# File 'lib/leap_cli/config/macros.rb', line 94 def file_path(path) if path.is_a? Symbol path = [path, @node.name] end actual_path = Path.find_file(path) if actual_path.nil? Util::log 2, :skipping, "file_path(\"#{path}\") because there is no such file." nil else if actual_path =~ /^#{Regexp.escape(Path.provider_base)}/ # if file is under Path.provider_base, we must copy the default file to # to Path.provider in order for rsync to be able to sync the file. local_provider_path = actual_path.sub(/^#{Regexp.escape(Path.provider_base)}/, Path.provider) FileUtils.mkdir_p File.dirname(local_provider_path), :mode => 0700 FileUtils.install actual_path, local_provider_path, :mode => 0600 Util.log :created, Path.relative_path(local_provider_path) actual_path = local_provider_path end if File.directory?(actual_path) && actual_path !~ /\/$/ actual_path += '/' # ensure directories end with /, important for building rsync command end relative_path = Path.relative_path(actual_path) @node.file_paths << relative_path @node.manager.provider.hiera_sync_destination + '/' + relative_path end end |
#fingerprint(filename) ⇒ Object
return a fingerprint for a x509 certificate
144 145 146 |
# File 'lib/leap_cli/config/macros.rb', line 144 def fingerprint(filename) "SHA256: " + X509.fingerprint("SHA256", Path.named_path(filename)) end |
#haproxy_servers(node_list, stunnel_clients, non_stunnel_port = nil) ⇒ Object
creates a hash suitable for configuring haproxy. the key is the node name of the server we are proxying to.
-
node_list - a hash of nodes for the haproxy servers
-
stunnel_client - contains the mappings to local ports for each server node.
-
non_stunnel_port - in case self is included in node_list, the port to connect to.
1000 weight is used for nodes in the same location. 100 otherwise.
285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 |
# File 'lib/leap_cli/config/macros.rb', line 285 def haproxy_servers(node_list, stunnel_clients, non_stunnel_port=nil) default_weight = 10 local_weight = 100 # record the hosts_file hostnames(node_list) # create a simple map for node name -> local stunnel accept port accept_ports = stunnel_clients.inject({}) do |hsh, stunnel_entry| name = stunnel_entry.first.sub /_[0-9]+$/, '' hsh[name] = stunnel_entry.last['accept_port'] hsh end # if one the nodes in the node list is ourself, then there will not be a stunnel to it, # but we need to include it anyway in the haproxy config. if node_list[self.name] && non_stunnel_port accept_ports[self.name] = non_stunnel_port end # create the first pass of the servers hash servers = node_list.values.inject(Config::ObjectList.new) do |hsh, node| weight = default_weight if self['location'] && node['location'] if self.location['name'] == node.location['name'] weight = local_weight end end hsh[node.name] = Config::Object[ 'backup', false, 'host', 'localhost', 'port', accept_ports[node.name] || 0, 'weight', weight ] hsh end # if there are some local servers, make the others backup if servers.detect{|k,v| v.weight == local_weight} servers.each do |k,server| server['backup'] = server['weight'] == default_weight end end return servers end |
#hex_secret(name, bit_length = 128) ⇒ Object
inserts an hexidecimal secret string, generating it if needed.
bit_length
is the bits in the secret, (ie length of resulting hex string will be bit_length/4)
137 138 139 |
# File 'lib/leap_cli/config/macros.rb', line 137 def hex_secret(name, bit_length=128) @manager.secrets.set(name, Util::Secret.generate_hex(bit_length), @node[:environment]) end |
#hostnames(nodes) ⇒ Object
records the list of hosts that are encountered for this node
155 156 157 158 159 160 161 162 163 164 |
# File 'lib/leap_cli/config/macros.rb', line 155 def hostnames(nodes) @referenced_nodes ||= ObjectList.new if nodes.is_a? Config::Object nodes = ObjectList.new nodes end nodes.each_node do |node| @referenced_nodes[node.name] ||= node end return nodes.values.collect {|node| node.domain.name} end |
#hosts_file(nodes = nil) ⇒ Object
Generates entries needed for updating /etc/hosts on a node (as a hash).
Argument ‘nodes` can be nil or a list of nodes. If nil, only include the IPs of the other nodes this @node as has encountered (plus all mx nodes).
Also, for virtual machines, we use the local address if this @node is in the same location as the node in question.
We include the ssh public key for each host, so that the hash can also be used to generate the /etc/ssh/known_hosts
178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 |
# File 'lib/leap_cli/config/macros.rb', line 178 def hosts_file(nodes=nil) if nodes.nil? if @referenced_nodes && @referenced_nodes.any? nodes = @referenced_nodes nodes = nodes.merge(nodes_like_me[:services => 'mx']) # all nodes always need to communicate with mx nodes. end end return nil unless nodes hosts = {} my_location = @node['location'] ? @node['location']['name'] : nil nodes.each_node do |node| hosts[node.name] = {'ip_address' => node.ip_address, 'domain_internal' => node.domain.internal, 'domain_full' => node.domain.full} node_location = node['location'] ? node['location']['name'] : nil if my_location == node_location if facts = @node.manager.facts[node.name] if facts['ec2_public_ipv4'] hosts[node.name]['ip_address'] = facts['ec2_public_ipv4'] end end end host_pub_key = Util::read_file([:node_ssh_pub_key,node.name]) if host_pub_key hosts[node.name]['host_pub_key'] = host_pub_key end end hosts end |
#nodes ⇒ Object
the list of all the nodes
17 18 19 |
# File 'lib/leap_cli/config/macros.rb', line 17 def nodes global.nodes end |
#nodes_like_me ⇒ Object
returns a list of nodes that match the same environment
if @node.environment is not set, we return other nodes where environment is not set.
34 35 36 |
# File 'lib/leap_cli/config/macros.rb', line 34 def nodes_like_me nodes[:environment => @node.environment] end |
#provider ⇒ Object
grab an environment appropriate provider
24 25 26 |
# File 'lib/leap_cli/config/macros.rb', line 24 def provider global.providers[@node.environment] || global.provider end |
#secret(name, length = 32) ⇒ Object
inserts a named secret, generating it if needed.
manager.export_secrets should be called later to capture any newly generated secrets.
length
is the character length of the generated password.
128 129 130 |
# File 'lib/leap_cli/config/macros.rb', line 128 def secret(name, length=32) @manager.secrets.set(name, Util::Secret.generate(length), @node[:environment]) end |
#stunnel_client(node_list, port, options = {}) ⇒ Object
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.
About ths stunnel puppet names:
-
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.
The network looks like this:
|------ stunnel client ---------------| |--------- stunnel server -----------------------|
consumer app -> localhost:accept_port -> server:connect_port -> server:port -> service app
generates an entry appropriate to be passed directly to create_resources(stunnel::service, hiera(‘..’), defaults)
233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 |
# File 'lib/leap_cli/config/macros.rb', line 233 def stunnel_client(node_list, port, ={}) @next_stunnel_port ||= 4000 hostnames(node_list) # record the hosts node_list.values.inject(Config::ObjectList.new) do |hsh, node| if node.name != self.name || [:include_self] hsh["#{node.name}_#{port}"] = Config::Object[ 'accept_port', @next_stunnel_port, 'connect', node.domain.internal, 'connect_port', stunnel_port(port) ] @next_stunnel_port += 1 end hsh end end |
#stunnel_port(port) ⇒ Object
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)
262 263 264 265 266 267 268 269 |
# File 'lib/leap_cli/config/macros.rb', line 262 def stunnel_port(port) port = port.to_i if port < 50000 return port + 10000 else return port - 10000 end end |
#stunnel_server(port) ⇒ Object
generates a stunnel server entry.
port
is the real port targeted service.
254 255 256 |
# File 'lib/leap_cli/config/macros.rb', line 254 def stunnel_server(port) {"accept" => stunnel_port(port), "connect" => "127.0.0.1:#{port}"} end |
#try_file(filename) ⇒ Object
like #file, but allow missing files
76 77 78 79 80 |
# File 'lib/leap_cli/config/macros.rb', line 76 def try_file(filename) return file(filename) rescue FileMissing return nil end |