murakumo 0.1.0 → 0.1.1
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.
- data/README +6 -5
- data/etc/murakumo.server +2 -0
- data/etc/murakumo.yml.sample +4 -2
- data/lib/cli/mrkmctl.rb +14 -3
- data/lib/cli/mrkmctl_options.rb +15 -5
- data/lib/cli/murakumo_options.rb +19 -5
- data/lib/misc/murakumo_const.rb +3 -2
- data/lib/srv/murakumo_cloud.rb +28 -12
- data/lib/srv/murakumo_health_checker_context.rb +32 -0
- data/lib/srv/murakumo_server.rb +1 -6
- metadata +9 -9
data/README
CHANGED
@@ -12,14 +12,15 @@ https://bitbucket.org/winebarrel/murakumo
|
|
12
12
|
|
13
13
|
* RubyDNS
|
14
14
|
* SQLite
|
15
|
-
* MessagePack
|
16
15
|
|
17
16
|
== Install
|
18
17
|
|
19
|
-
gem install murakumo
|
20
|
-
cp /usr/local/lib/ruby/gems/1.8/gems/murakumo-*/etc/murakumo.server /etc/init.d/murakumo
|
21
|
-
chmod 755 /etc/init.d/murakumo
|
22
|
-
/etc/init.d/murakumo
|
18
|
+
shell> gem install murakumo
|
19
|
+
shell> cp /usr/local/lib/ruby/gems/1.8/gems/murakumo-*/etc/murakumo.server /etc/init.d/murakumo
|
20
|
+
shell> chmod 755 /etc/init.d/murakumo
|
21
|
+
shell> /etc/init.d/murakumo configure
|
22
|
+
shell> /etc/init.d/murakumo start
|
23
|
+
shell> dig @127.0.0.1 <any_hostname>
|
23
24
|
|
24
25
|
== Example
|
25
26
|
=== display of a list of a record
|
data/etc/murakumo.server
CHANGED
data/etc/murakumo.yml.sample
CHANGED
@@ -8,6 +8,8 @@ log-level: info
|
|
8
8
|
resolver: 8.8.8.8
|
9
9
|
max-ip-num: 8
|
10
10
|
|
11
|
+
#initial-nodes: 10.11.12.14, 10.11.12.15
|
12
|
+
|
11
13
|
# Ip address, hostname, ttl
|
12
14
|
host: 10.11.12.13, my-host, 60
|
13
15
|
|
@@ -20,14 +22,14 @@ health-check:
|
|
20
22
|
foo:
|
21
23
|
interval: 5
|
22
24
|
timeout: 5
|
23
|
-
healthy:
|
25
|
+
healthy: 2
|
24
26
|
unhealthy: 2
|
25
27
|
script: |
|
26
28
|
tcp_check 80
|
27
29
|
bar:
|
28
30
|
interval: 5
|
29
31
|
timeout: 5
|
30
|
-
healthy:
|
32
|
+
healthy: 2
|
31
33
|
unhealthy: 2
|
32
34
|
script: |
|
33
35
|
http_get '/index.html'
|
data/lib/cli/mrkmctl.rb
CHANGED
@@ -26,12 +26,23 @@ begin
|
|
26
26
|
|
27
27
|
puts <<-EOF
|
28
28
|
IP address TTL Priority Activity Hostname
|
29
|
-
--------------- ------
|
29
|
+
--------------- ------ --------- -------- ----------
|
30
30
|
EOF
|
31
31
|
records.each do |r|
|
32
|
-
|
32
|
+
priority = case r[3]
|
33
|
+
when Murakumo::ORIGIN
|
34
|
+
'Origin'
|
35
|
+
when Murakumo::MASTER
|
36
|
+
'Master'
|
37
|
+
when Murakumo::SECONDARY
|
38
|
+
'Secondary'
|
39
|
+
else
|
40
|
+
'Backup'
|
41
|
+
end
|
42
|
+
|
43
|
+
r[3] = priority
|
33
44
|
r[4] = (r[4] == Murakumo::ACTIVE ? 'Active' : 'Inactive')
|
34
|
-
puts '%-15s %6d %-
|
45
|
+
puts '%-15s %6d %-9s %-8s %s' % r.values_at(0, 2, 3, 4, 1)
|
35
46
|
end
|
36
47
|
|
37
48
|
# レコードの追加・更新
|
data/lib/cli/mrkmctl_options.rb
CHANGED
@@ -9,11 +9,12 @@ def mrkmctl_parse_args
|
|
9
9
|
desc 'displays a list of a record'
|
10
10
|
option :list, '-L', '--list [NAME]'
|
11
11
|
|
12
|
-
desc 'adds or updates a record: <hostname>[,<TTL>[,{master|backup}]]'
|
12
|
+
desc 'adds or updates a record: <hostname>[,<TTL>[,{master|secondary|backup}]]'
|
13
13
|
option :add, '-A', '--add RECORD', :type => Array, :multiple => true do |value|
|
14
14
|
(1 <= value.length and value.length <= 3) or invalid_argument
|
15
15
|
|
16
|
-
|
16
|
+
value = value.map {|i| i.strip }
|
17
|
+
hostname, ttl, priority = value
|
17
18
|
|
18
19
|
# hostname
|
19
20
|
/\A[0-9a-z\.\-]+\Z/i =~ hostname or invalid_argument
|
@@ -23,8 +24,8 @@ def mrkmctl_parse_args
|
|
23
24
|
invalid_argument
|
24
25
|
end
|
25
26
|
|
26
|
-
#
|
27
|
-
|
27
|
+
# Priority
|
28
|
+
priority.nil? or /\A(master|secondary|backup)\Z/i =~ priority or invalid_argument
|
28
29
|
end
|
29
30
|
|
30
31
|
desc 'deletes a record'
|
@@ -75,10 +76,19 @@ def mrkmctl_parse_args
|
|
75
76
|
r = r.map {|i| i ? i.to_s.strip : i }
|
76
77
|
[nil, 60, 'master'].each_with_index {|v, i| r[i] ||= v }
|
77
78
|
|
79
|
+
priority = case r[2].to_s
|
80
|
+
when /master/i
|
81
|
+
Murakumo::MASTER
|
82
|
+
when /secondary/i
|
83
|
+
Murakumo::SECONDARY
|
84
|
+
else
|
85
|
+
Murakumo::BACKUP
|
86
|
+
end
|
87
|
+
|
78
88
|
[
|
79
89
|
r[0], # name
|
80
90
|
r[1].to_i, # TTL
|
81
|
-
|
91
|
+
priority,
|
82
92
|
]
|
83
93
|
end
|
84
94
|
end
|
data/lib/cli/murakumo_options.rb
CHANGED
@@ -22,6 +22,7 @@ def murakumo_parse_args
|
|
22
22
|
|
23
23
|
desc 'initial node list of gossip protocols'
|
24
24
|
option :initial_nodes, '-i', '--initial-nodes IP_LIST', :type => Array, :default => [] do |value|
|
25
|
+
value = value.map {|i| i.strip }
|
25
26
|
value.all? {|i| /\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z/ =~ i } or invalid_argument
|
26
27
|
end
|
27
28
|
|
@@ -29,6 +30,7 @@ def murakumo_parse_args
|
|
29
30
|
option :host, '-H', '--host RECORD', :type => Array, :required => true do |value|
|
30
31
|
(1 <= value.length and value.length <= 3) or invalid_argument
|
31
32
|
|
33
|
+
value = value.map {|i| i.strip }
|
32
34
|
ip_addr, hostname, ttl = value
|
33
35
|
|
34
36
|
# ip address
|
@@ -43,11 +45,12 @@ def murakumo_parse_args
|
|
43
45
|
end
|
44
46
|
end # :host
|
45
47
|
|
46
|
-
desc 'resource record of an alias: <hostname>[,<TTL>[,{master|backup}]]'
|
48
|
+
desc 'resource record of an alias: <hostname>[,<TTL>[,{master|secondary|backup}]]'
|
47
49
|
option :aliases, '-A', '--alias RECORD', :type => Array, :multiple => true do |value|
|
48
50
|
(1 <= value.length and value.length <= 3) or invalid_argument
|
49
51
|
|
50
|
-
|
52
|
+
value = value.map {|i| i.strip }
|
53
|
+
hostname, ttl, priority = value
|
51
54
|
|
52
55
|
# hostname
|
53
56
|
/\A[0-9a-z\.\-]+\Z/ =~ hostname or invalid_argument
|
@@ -57,12 +60,14 @@ def murakumo_parse_args
|
|
57
60
|
invalid_argument
|
58
61
|
end
|
59
62
|
|
60
|
-
#
|
61
|
-
|
63
|
+
# Priority
|
64
|
+
priority.nil? or /\A(master|secondary|backup)\Z/i =~ priority or invalid_argument
|
62
65
|
end # :aliases
|
63
66
|
|
64
67
|
desc 'ip address of a default resolver'
|
65
68
|
option :resolver, '-r', '--resolver IP_LIST', :type => Array do |value|
|
69
|
+
value = value.map {|i| i.strip }
|
70
|
+
|
66
71
|
unless value.all? {|i| /\A\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\Z/ =~ i }
|
67
72
|
invalid_argument
|
68
73
|
end
|
@@ -135,10 +140,19 @@ def murakumo_parse_args
|
|
135
140
|
r = r.map {|i| i.to_s.strip }
|
136
141
|
[nil, 60, 'master'].each_with_index {|v, i| r[i] ||= v }
|
137
142
|
|
143
|
+
priority = case r[2].to_s
|
144
|
+
when /master/i
|
145
|
+
Murakumo::MASTER
|
146
|
+
when /secondary/i
|
147
|
+
Murakumo::SECONDARY
|
148
|
+
else
|
149
|
+
Murakumo::BACKUP
|
150
|
+
end
|
151
|
+
|
138
152
|
[
|
139
153
|
r[0], # name
|
140
154
|
r[1].to_i, # TTL
|
141
|
-
|
155
|
+
priority,
|
142
156
|
]
|
143
157
|
end
|
144
158
|
|
data/lib/misc/murakumo_const.rb
CHANGED
data/lib/srv/murakumo_cloud.rb
CHANGED
@@ -353,23 +353,26 @@ module Murakumo
|
|
353
353
|
|
354
354
|
if @address_records.length == 1
|
355
355
|
# レコードが一件ならそれを返す
|
356
|
-
|
357
|
-
|
358
|
-
# 優先度の高いレコードを検索
|
359
|
-
records = @address_records.select {|i| i['priority'] == MASTER }
|
356
|
+
return @address_records.map {|i| i.values_at('ip_address', 'ttl') }
|
357
|
+
end
|
360
358
|
|
361
|
-
|
362
|
-
|
363
|
-
records = @address_records.select {|i| i['priority'] == BACKUP }
|
364
|
-
end
|
359
|
+
# 優先度の高いレコードを検索
|
360
|
+
records = shuffle_records(@address_records.select {|i| i['priority'] == MASTER })
|
365
361
|
|
366
|
-
|
367
|
-
|
368
|
-
|
362
|
+
# 次に優先度の高いレコードを検索
|
363
|
+
records.concat(shuffle_records(@address_records.select {|i| i['priority'] == SECONDARY }))
|
364
|
+
|
365
|
+
# レコードが見つからなかった場合はバックアップを選択
|
366
|
+
if records.empty?
|
367
|
+
records = shuffle_records(@address_records.select {|i| i['priority'] == BACKUP })
|
369
368
|
end
|
370
369
|
|
370
|
+
# それでもレコードが見つからなかった場合はオリジンを選択
|
371
|
+
# ※このパスは通らない
|
372
|
+
records = @address_records if records.empty?
|
373
|
+
|
371
374
|
# IPアドレス、TTLを返す
|
372
|
-
|
375
|
+
records.map {|i| i.values_at('ip_address', 'ttl') }
|
373
376
|
ensure
|
374
377
|
# エラー検出のため、一応クリア
|
375
378
|
@address_records = nil
|
@@ -415,6 +418,19 @@ module Murakumo
|
|
415
418
|
|
416
419
|
private
|
417
420
|
|
421
|
+
# 乱数でレコードをシャッフルする
|
422
|
+
def shuffle_records(records)
|
423
|
+
# レコードが一件の時はそのまま返す
|
424
|
+
return records if records.length == 1
|
425
|
+
|
426
|
+
# 先頭のAレコードを決定
|
427
|
+
max_ip_num = [records.length, @options[:max_ip_num]].min
|
428
|
+
first_index = rand(records.length)
|
429
|
+
|
430
|
+
# Aレコードを返す
|
431
|
+
(records + records).slice(first_index, max_ip_num)
|
432
|
+
end
|
433
|
+
|
418
434
|
# リソースレコードのデータベース作成
|
419
435
|
# もう少し並列処理に強いストレージに変えたいが…
|
420
436
|
def create_database
|
@@ -28,6 +28,38 @@ module Murakumo
|
|
28
28
|
return false
|
29
29
|
end
|
30
30
|
|
31
|
+
# MySQLのドライバがあれば、MySQLチェッカーを定義
|
32
|
+
has_mysql = false
|
33
|
+
|
34
|
+
begin
|
35
|
+
require 'mysql'
|
36
|
+
has_mysql = true
|
37
|
+
rescue LoadError
|
38
|
+
begin
|
39
|
+
require 'mysql2'
|
40
|
+
has_mysql = true
|
41
|
+
rescue LoadError
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
if has_mysql
|
46
|
+
def mysql_check(user, passwd = nil, port_sock = 3306, host = '127.0.0.1', db = nil)
|
47
|
+
port = nil
|
48
|
+
sock = nil
|
49
|
+
|
50
|
+
if port_sock.kind_of?(Integer)
|
51
|
+
port = port_sock
|
52
|
+
else
|
53
|
+
sock = port_sock
|
54
|
+
end
|
55
|
+
|
56
|
+
my = Mysql.new(host, user, passwd, db, port, sock)
|
57
|
+
!!(my.respond_to?(:ping) ? my.ping : my.stat)
|
58
|
+
rescue
|
59
|
+
false
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
31
63
|
end # HealthCheckerContext
|
32
64
|
|
33
65
|
end # Murakumo
|
data/lib/srv/murakumo_server.rb
CHANGED
@@ -66,12 +66,7 @@ module Murakumo
|
|
66
66
|
match(@@cloud.method(:address_exist?), :A) do |transaction|
|
67
67
|
records = @@cloud.lookup_addresses(transaction.name)
|
68
68
|
|
69
|
-
|
70
|
-
max_ip_num = [records.length, @@options[:max_ip_num]].min
|
71
|
-
first_index = rand(max_ip_num);
|
72
|
-
|
73
|
-
# Aレコードを返す
|
74
|
-
(records + records).slice(first_index, max_ip_num).each do |r|
|
69
|
+
records.each do |r|
|
75
70
|
address, ttl = r
|
76
71
|
transaction.respond!(address, :ttl => ttl)
|
77
72
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: murakumo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- winebarrel
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-11-
|
18
|
+
date: 2011-11-17 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rubydns
|
@@ -39,7 +39,7 @@ dependencies:
|
|
39
39
|
requirement: &id002 !ruby/object:Gem::Requirement
|
40
40
|
none: false
|
41
41
|
requirements:
|
42
|
-
- -
|
42
|
+
- - ">="
|
43
43
|
- !ruby/object:Gem::Version
|
44
44
|
hash: 17
|
45
45
|
segments:
|
@@ -55,14 +55,14 @@ dependencies:
|
|
55
55
|
requirement: &id003 !ruby/object:Gem::Requirement
|
56
56
|
none: false
|
57
57
|
requirements:
|
58
|
-
- -
|
58
|
+
- - ">="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
hash:
|
60
|
+
hash: 21
|
61
61
|
segments:
|
62
62
|
- 0
|
63
|
+
- 2
|
63
64
|
- 1
|
64
|
-
|
65
|
-
version: 0.1.9
|
65
|
+
version: 0.2.1
|
66
66
|
type: :runtime
|
67
67
|
version_requirements: *id003
|
68
68
|
- !ruby/object:Gem::Dependency
|