discourse_sd 0.0.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/bin/discourse_sd +3 -0
- data/lib/discourse_sd.rb +86 -0
- data/lib/discourse_sd/version.rb +3 -0
- data/lib/discourse_sd_cli.rb +25 -0
- metadata +89 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 3fc3cfdab012516746db93ef82db8e640eeab501
|
4
|
+
data.tar.gz: 3d66a320135732d196b38dd2d698909cd5f89466
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 8f42790d9530178a2c1d6cc5ecf529b8b59fedc9640f9353dac03a611552050baec082d4ccf952841a58ea01667f878d621e74403955b43660aeb57de261d702
|
7
|
+
data.tar.gz: c4f2e4c4074c3430e8223033427886050ea91e9ff2ca9c505ede895b6bc82f3583d5f4a0a47606c212fd728e99ab046e0110f88295b914b17289ace0452656f2
|
data/bin/discourse_sd
ADDED
data/lib/discourse_sd.rb
ADDED
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'resolv'
|
2
|
+
require 'dns-sd'
|
3
|
+
|
4
|
+
require_relative 'discourse_sd/version'
|
5
|
+
|
6
|
+
class DiscourseSD
|
7
|
+
attr_reader :zone
|
8
|
+
|
9
|
+
# Create an instance of DiscourseSD to lookup services in the zone
|
10
|
+
# determined from the environment.
|
11
|
+
#
|
12
|
+
# @return [DiscourseSD] the DiscourseSD instance
|
13
|
+
def self.create_from_env
|
14
|
+
if sd_dns = Resolv::DNS.new.getresources("powerdns._domain._tcp", Resolv::DNS::Resource::IN::SRV).first
|
15
|
+
parts = sd_dns.target.to_s.split('.')
|
16
|
+
new(parts[parts.rindex('sd')..-1].join('.'))
|
17
|
+
else
|
18
|
+
raise RuntimeError, "No PowerDNS servers were found!"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
# Create an instance of DiscourseSD to lookup services in the given zone.
|
23
|
+
#
|
24
|
+
# @param zone [String] The zone in which all services should be found.
|
25
|
+
def initialize(zone)
|
26
|
+
@zone = zone
|
27
|
+
end
|
28
|
+
|
29
|
+
# Looks up all the services relevant to a Discourse app, and returns
|
30
|
+
# a hash with their IPv6 addresses and ports using the same key names
|
31
|
+
# that are used in the Discourse config.
|
32
|
+
#
|
33
|
+
# @param prefix [String] The name of the Discourse app cluster.
|
34
|
+
#
|
35
|
+
# @return [Hash] IP addresses and ports for services.
|
36
|
+
def service_instances(prefix)
|
37
|
+
config = {}
|
38
|
+
sd = DNSSD.new(@zone)
|
39
|
+
|
40
|
+
redises = redis_service_instances(sd, prefix)
|
41
|
+
pgbouncers = pgbouncer_service_instances(sd, prefix)
|
42
|
+
|
43
|
+
Resolv::DNS.open do |dns|
|
44
|
+
redis_master = redises.first
|
45
|
+
redis_slave = redises.size > 1 ? redises.last : nil
|
46
|
+
|
47
|
+
if redis_master
|
48
|
+
config[:redis_host] = aaaa_record(dns, redis_master.hostname).to_s
|
49
|
+
config[:redis_port] = redis_master.port
|
50
|
+
end
|
51
|
+
if redis_slave
|
52
|
+
config[:redis_slave_host] = aaaa_record(dns, redis_slave.hostname).to_s
|
53
|
+
config[:redis_slave_port] = redis_slave.port
|
54
|
+
end
|
55
|
+
|
56
|
+
db_master = pgbouncers.first
|
57
|
+
db_replica = pgbouncers.size > 1 ? pgbouncers.last : nil
|
58
|
+
|
59
|
+
if db_master
|
60
|
+
config[:db_host] = aaaa_record(dns, db_master.hostname).to_s
|
61
|
+
config[:db_port] = db_master.port
|
62
|
+
end
|
63
|
+
if db_replica
|
64
|
+
config[:db_replica_host] = aaaa_record(dns, db_replica.hostname).to_s
|
65
|
+
config[:db_replica_port] = db_replica.port
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
config
|
70
|
+
end
|
71
|
+
|
72
|
+
private
|
73
|
+
|
74
|
+
def redis_service_instances(sd, prefix)
|
75
|
+
sd.service_instance(prefix, 'redis', :TCP).targets
|
76
|
+
end
|
77
|
+
|
78
|
+
def pgbouncer_service_instances(sd, prefix)
|
79
|
+
sd.service_instance(prefix, 'pgbouncer', :TCP).targets
|
80
|
+
end
|
81
|
+
|
82
|
+
def aaaa_record(dns, name)
|
83
|
+
dns.getresources(name, Resolv::DNS::Resource::IN::AAAA).first&.address
|
84
|
+
end
|
85
|
+
|
86
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'discourse_sd'
|
2
|
+
require 'json'
|
3
|
+
|
4
|
+
def usage
|
5
|
+
puts "discourse_sd v#{DiscourseSD::VERSION}"
|
6
|
+
puts ''
|
7
|
+
puts 'usage:', ''
|
8
|
+
puts ' discourse_sd rails-config <name>'
|
9
|
+
puts ' Outputs a JSON hash of a rails configuration for the app with the given name'
|
10
|
+
puts ''
|
11
|
+
end
|
12
|
+
|
13
|
+
if ARGV.size == 0
|
14
|
+
usage
|
15
|
+
else
|
16
|
+
sd = DiscourseSD.create_from_env
|
17
|
+
|
18
|
+
case ARGV[0]
|
19
|
+
when 'rails-config'
|
20
|
+
usage && exit unless ARGV.size == 2
|
21
|
+
puts sd.service_instances(ARGV[1]).to_json
|
22
|
+
else
|
23
|
+
usage
|
24
|
+
end
|
25
|
+
end
|
metadata
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: discourse_sd
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.7
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Neil Lalonde
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2019-03-19 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dns-sd
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - ">="
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '0'
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - ">="
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '0'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: yard
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - ">="
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.6'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.6'
|
55
|
+
description: For internal Discourse use
|
56
|
+
email: neil.lalonde@discourse.org
|
57
|
+
executables:
|
58
|
+
- discourse_sd
|
59
|
+
extensions: []
|
60
|
+
extra_rdoc_files: []
|
61
|
+
files:
|
62
|
+
- bin/discourse_sd
|
63
|
+
- lib/discourse_sd.rb
|
64
|
+
- lib/discourse_sd/version.rb
|
65
|
+
- lib/discourse_sd_cli.rb
|
66
|
+
homepage:
|
67
|
+
licenses: []
|
68
|
+
metadata: {}
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options: []
|
71
|
+
require_paths:
|
72
|
+
- lib
|
73
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
74
|
+
requirements:
|
75
|
+
- - ">="
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: 2.3.0
|
78
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - ">="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '0'
|
83
|
+
requirements: []
|
84
|
+
rubyforge_project:
|
85
|
+
rubygems_version: 2.5.2.1
|
86
|
+
signing_key:
|
87
|
+
specification_version: 4
|
88
|
+
summary: Utilities for using DNS-SD in our hosting
|
89
|
+
test_files: []
|