mtik_directory_2_address_list 1.0.2 → 1.0.3
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/bin/mtik_directory_2_address_list +57 -38
- data/lib/mtik_directory_2_address_list.rb +1 -1
- data/lib/mtik_directory_2_address_list/directory.rb +24 -18
- data/lib/mtik_directory_2_address_list/mikrotik.rb +3 -3
- data/lib/mtik_directory_2_address_list/version.rb +1 -1
- data/mtik_directory_2_address_list.gemspec +1 -1
- metadata +3 -3
@@ -3,42 +3,59 @@ require 'optparse'
|
|
3
3
|
require 'syslog'
|
4
4
|
require 'mtik_directory_2_address_list'
|
5
5
|
|
6
|
-
class Args
|
7
|
-
|
8
|
-
|
6
|
+
class Args
|
7
|
+
Error = Class.new(StandardError)
|
8
|
+
|
9
|
+
attr_reader :verbose, :prefix, :retry_timeout
|
9
10
|
|
10
11
|
def initialize
|
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
|
-
|
12
|
+
@verbose = STDOUT.tty?
|
13
|
+
@prefix = 'md2al_'
|
14
|
+
@retry_timeout = 15 # seconds
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.parse
|
18
|
+
self.new.tap { |args| args.parse }
|
19
|
+
end
|
20
|
+
|
21
|
+
def parse
|
22
|
+
opts = OptionParser.new
|
23
|
+
opts.banner = 'Usage: <host> <username> <password> <dir> [options]'
|
24
|
+
|
25
|
+
opts.separator ''
|
26
|
+
opts.separator 'Options:'
|
27
|
+
opts.on('-p', '--prefix PREFIX', 'Mikrotik address-list prefix',
|
28
|
+
"(default: #{@prefix})") { |s| @prefix = s }
|
29
|
+
opts.on('-v', '--[no-]verbose', 'Print debug messages to stdout',
|
30
|
+
'(default: true if stdout is a TTY)') { |v| @verbose = v }
|
31
|
+
opts.on('--retry-timeout SECONDS', Integer, 'Wait before restarting after an error',
|
32
|
+
"(default: #{@retry_timeout})") { |i| @retry_timeout = i }
|
33
|
+
|
34
|
+
opts.separator ''
|
35
|
+
opts.separator 'Symbolic links in <dir>, named like an IP address, will be sent to the'
|
36
|
+
opts.separator 'Mikrotik device at <host>. The address-list name will be formed by the'
|
37
|
+
opts.separator 'PREFIX + whatever the link points to.'
|
38
|
+
opts.separator ''
|
39
|
+
opts.separator 'For example, the following symbolic link: 1.2.3.4 -> 15mbps'
|
40
|
+
opts.separator 'With --prefix set to "down_speed_", will add the IP 1.2.3.4,'
|
41
|
+
opts.separator 'to the address-list named down_speed_15mbps.'
|
42
|
+
opts.separator ''
|
43
|
+
|
44
|
+
opts.parse!
|
45
|
+
ARGV.size == 4 || raise(Error, "need 4 arguments, but #{ARGV.size} provided")
|
46
|
+
|
47
|
+
rescue Error, OptionParser::ParseError => err
|
48
|
+
STDERR << opts << 'Error: ' << err << "\n"
|
40
49
|
exit(2)
|
41
50
|
end
|
51
|
+
|
52
|
+
def directory
|
53
|
+
ARGV[3]
|
54
|
+
end
|
55
|
+
|
56
|
+
def mikrotik
|
57
|
+
Hash[[:host, :user, :pass].zip(ARGV[0, 3])]
|
58
|
+
end
|
42
59
|
end
|
43
60
|
|
44
61
|
class Main
|
@@ -48,17 +65,19 @@ class Main
|
|
48
65
|
end
|
49
66
|
|
50
67
|
def args
|
51
|
-
@args ||= Args.
|
68
|
+
@args ||= Args.parse.tap do |args|
|
52
69
|
Syslog.open($PROGRAM_NAME, Syslog::LOG_PID, Syslog::LOG_DAEMON)
|
53
|
-
args.
|
70
|
+
args.verbose && MtikDirectory2AddressList::Log.output(&method(:info))
|
54
71
|
end
|
55
72
|
end
|
56
73
|
|
57
74
|
def sync
|
58
|
-
MtikDirectory2AddressList.sync(args.
|
75
|
+
MtikDirectory2AddressList.sync(args.directory, args.mikrotik, args.prefix)
|
59
76
|
rescue => err
|
60
|
-
err("Error: #{err}
|
61
|
-
|
77
|
+
err("Error: #{err}")
|
78
|
+
err.backtrace.each { |line| err(" #{line}") }
|
79
|
+
sleep(args.retry_timeout)
|
80
|
+
retry
|
62
81
|
end
|
63
82
|
|
64
83
|
# Send +message+ to syslog and STDERR.
|
@@ -73,7 +92,7 @@ class Main
|
|
73
92
|
# @param [String] message
|
74
93
|
# @return [void]
|
75
94
|
def info(message)
|
76
|
-
STDOUT << message << "\n"
|
95
|
+
STDOUT << message << "\n"
|
77
96
|
end
|
78
97
|
end
|
79
98
|
|
@@ -12,7 +12,7 @@ module MtikDirectory2AddressList
|
|
12
12
|
# @param [String] src The directory where to look for symbolic links
|
13
13
|
# @param [Hash] dst The object passed to the +mtik+ gem (keys: +host+, +user+, +pass+)
|
14
14
|
# @param [String] prefix The prefix an address list name must have for it to be used
|
15
|
-
# @return [
|
15
|
+
# @return [void]
|
16
16
|
def sync(src, dst, prefix = "dir_")
|
17
17
|
Log.info { "Synchronizing [#{src}] with router at [#{dst[:host]}]" }
|
18
18
|
mtik = Mikrotik.new(dst.dup.merge(prefix:prefix))
|
@@ -2,9 +2,15 @@
|
|
2
2
|
|
3
3
|
module MtikDirectory2AddressList
|
4
4
|
class Directory
|
5
|
+
Error = Class.new(StandardError)
|
6
|
+
|
7
|
+
# The {#list} method will not enumerate symbolic links that do not match this regular expression.
|
8
|
+
# Other methods may raise Error.
|
9
|
+
IP_RE = %r{ \A \d{1,3} \. \d{1,3} \. \d{1,3} \. \d{1,3} \z }x
|
10
|
+
|
5
11
|
# Manage a directory of symbolic links.
|
6
12
|
#
|
7
|
-
# The IP address is the name of
|
13
|
+
# The IP address is the name of the symbolic link.
|
8
14
|
# The address list name is what the symbolic link points to.
|
9
15
|
#
|
10
16
|
# @param [Hash] params
|
@@ -13,23 +19,21 @@ module MtikDirectory2AddressList
|
|
13
19
|
@path = params[:path]
|
14
20
|
end
|
15
21
|
|
16
|
-
# Return the address list associated with
|
22
|
+
# Return the address list associated with +ip+.
|
17
23
|
#
|
18
|
-
# @param [String] ip
|
24
|
+
# @param [String] ip
|
19
25
|
#
|
20
|
-
# @return [String] The
|
21
|
-
# @return [nil] When the +ip+ is not found
|
26
|
+
# @return [String] The address list associated with +ip+
|
27
|
+
# @return [nil] When the +ip+ is not found or is not a symbolic link
|
22
28
|
def [](ip)
|
23
|
-
|
24
|
-
|
25
|
-
|
29
|
+
(ip =~ IP_RE) || raise(Error, "Invalid IP [#{ip}]")
|
30
|
+
file = File.join(@path, ip)
|
31
|
+
File.readlink(file)
|
32
|
+
rescue Errno::ENOENT, Errno::EINVAL
|
33
|
+
nil # symlink deleted, not a symlink
|
26
34
|
end
|
27
35
|
|
28
|
-
#
|
29
|
-
# The {#[]} method will read any symbolic link, even if its name does not match this regular expression.
|
30
|
-
IP_RE = %r{ \A \d{1,3} \. \d{1,3} \. \d{1,3} \. \d{1,3} \z }x
|
31
|
-
|
32
|
-
# Enumerates every IP in +@path+.
|
36
|
+
# Enumerate IPs associated with an address list.
|
33
37
|
#
|
34
38
|
# @return [Enumerator] Arrays with: IP, address list
|
35
39
|
def list
|
@@ -40,11 +44,14 @@ module MtikDirectory2AddressList
|
|
40
44
|
end
|
41
45
|
end
|
42
46
|
|
43
|
-
# Yield whenever
|
47
|
+
# Yield whenever an association is modified.
|
44
48
|
#
|
45
|
-
#
|
46
|
-
#
|
49
|
+
# This is based on the mtime of the directory being watched.
|
50
|
+
# If the mtime is not updated when a symbolic link is changed,
|
51
|
+
# the directory must be touched manually.
|
47
52
|
#
|
53
|
+
# @yield Right after being called
|
54
|
+
# @yield After every association update
|
48
55
|
# @return [void]
|
49
56
|
def watch
|
50
57
|
before = nil
|
@@ -54,12 +61,11 @@ module MtikDirectory2AddressList
|
|
54
61
|
end
|
55
62
|
end
|
56
63
|
|
57
|
-
#
|
64
|
+
# Like the instance method {#watch}, but yield a Hash with the associations.
|
58
65
|
#
|
59
66
|
# @param [String] path The directory to watch for modifications
|
60
67
|
#
|
61
68
|
# @yieldparam Hash{String=>String} Map IP addresses to address list names
|
62
|
-
#
|
63
69
|
# @return [void]
|
64
70
|
def self.watch(path)
|
65
71
|
dir = self.new(path:path)
|
@@ -3,9 +3,9 @@ require 'mtik'
|
|
3
3
|
|
4
4
|
module MtikDirectory2AddressList
|
5
5
|
class Mikrotik
|
6
|
-
|
7
|
-
|
8
|
-
|
6
|
+
Error = Class.new(StandardError)
|
7
|
+
RouterError = Class.new(Error)
|
8
|
+
SyncError = Class.new(Error)
|
9
9
|
|
10
10
|
def initialize(params)
|
11
11
|
@prefix = (params[:prefix] || 'md2al_')
|
@@ -8,7 +8,7 @@ Gem::Specification.new do |spec|
|
|
8
8
|
spec.version = MtikDirectory2AddressList::VERSION
|
9
9
|
spec.authors = ['Andre Luiz dos Santos']
|
10
10
|
spec.email = ['andre.netvision.com.br@gmail.com']
|
11
|
-
spec.summary = %q{Synchronize a directory with a Mikrotik address list}
|
11
|
+
spec.summary = %q{Synchronize a directory with a Mikrotik address list.}
|
12
12
|
|
13
13
|
spec.files = `git ls-files -z`.split("\x0")
|
14
14
|
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mtik_directory_2_address_list
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.3
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-01-
|
12
|
+
date: 2015-01-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -151,7 +151,7 @@ rubyforge_project:
|
|
151
151
|
rubygems_version: 1.8.23
|
152
152
|
signing_key:
|
153
153
|
specification_version: 3
|
154
|
-
summary: Synchronize a directory with a Mikrotik address list
|
154
|
+
summary: Synchronize a directory with a Mikrotik address list.
|
155
155
|
test_files:
|
156
156
|
- test/test_directory.rb
|
157
157
|
- test/test_mikrotik.rb
|