knot-ruby 0.2.0 → 0.3.0
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.
- checksums.yaml +4 -4
- data/lib/knot/interface.rb +18 -16
- data/lib/knot/protocol.rb +119 -50
- data/lib/knot/version.rb +1 -1
- metadata +3 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 955cc51d2b5bc2c9057fbac7501aa4cd4ddae6a41769a414d9f3dad99da233ec
|
4
|
+
data.tar.gz: 7e63b760071edf2236e09e2148a447d6f3a6ea11ddef129fc98e6160ea43217e
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9c8056ca3f3f7f2b97eb2dbc57047f2d6222a76e2b1d1794a07b016037cb976e6c9d6510e236f26aeb6d9182d98a82ee27f141f5e7bd291ec2d0992847829b6f
|
7
|
+
data.tar.gz: 8f85e0815f1e6bbcc39c357be9ee3d3922201f9fa58aafa576e6d69db1dd8a2d18601d547db2299621fe2bd223745a91987fc6b8a986634e1ec63dd94b8c7811
|
data/lib/knot/interface.rb
CHANGED
@@ -127,37 +127,39 @@ class Knot::Conf
|
|
127
127
|
self.commit
|
128
128
|
end
|
129
129
|
|
130
|
-
def parse_item
|
131
|
-
case
|
130
|
+
def parse_item kv
|
131
|
+
case kv
|
132
132
|
when Hash
|
133
|
-
|
134
|
-
|
135
|
-
|
133
|
+
r = {}
|
134
|
+
kv.each {|k,v| r[k.to_s.to_sym] = v }
|
135
|
+
case r.keys.sort
|
136
|
+
when %i[section], %i[id section], %i[item section], %i[id item section]
|
137
|
+
r
|
136
138
|
else
|
137
|
-
raise ArgumentError, "Invalid Item-format"
|
139
|
+
raise ArgumentError, "Invalid Item-format: #{k}"
|
138
140
|
end
|
139
141
|
|
140
142
|
when Array
|
141
|
-
case
|
142
|
-
when 1 then {section:
|
143
|
-
when 2 then {section:
|
144
|
-
when 3 then {section:
|
145
|
-
else raise ArgumentError, "Invalid Item-format"
|
143
|
+
case kv.length
|
144
|
+
when 1 then {section: kv[0]}
|
145
|
+
when 2 then {section: kv[0], item: kv[1]}
|
146
|
+
when 3 then {section: kv[0], id: kv[1], item: kv[2]}
|
147
|
+
else raise ArgumentError, "Invalid Item-format: #{kv}"
|
146
148
|
end
|
147
149
|
|
148
150
|
when /\A
|
149
|
-
|
150
|
-
|
151
|
-
|
151
|
+
(?<section> [a-z0-9_-]+ )
|
152
|
+
(?: \[ (?<id> [a-z0-9_.-]+) \] )?
|
153
|
+
(?: \. (?<item>[a-z0-9_-]+) )?
|
152
154
|
\z/xi
|
153
155
|
|
154
|
-
|
156
|
+
$~.named_captures.delete_if {|_,v| v.nil? }
|
155
157
|
|
156
158
|
when nil
|
157
159
|
{}
|
158
160
|
|
159
161
|
else
|
160
|
-
raise ArgumentError, "Invalid Item-format"
|
162
|
+
raise ArgumentError, "Invalid Item-format: #{kv}"
|
161
163
|
end
|
162
164
|
end
|
163
165
|
|
data/lib/knot/protocol.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
1
|
require 'iounpack'
|
2
|
-
require '
|
2
|
+
require 'pathname'
|
3
|
+
require 'socket'
|
4
|
+
require 'logger'
|
3
5
|
require_relative 'errors'
|
4
6
|
|
5
7
|
module Knot
|
@@ -53,7 +55,7 @@ module Knot::Protocol::Type
|
|
53
55
|
end
|
54
56
|
|
55
57
|
#class Knot::KnotC
|
56
|
-
# attr_accessor :
|
58
|
+
# attr_accessor :binary
|
57
59
|
#
|
58
60
|
# def initialize path = nil, binary: nil
|
59
61
|
# @path = path
|
@@ -72,44 +74,100 @@ end
|
|
72
74
|
# end
|
73
75
|
#end
|
74
76
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
Name[v] = i
|
77
|
+
class Knot::Protocol::Code
|
78
|
+
include Comparable
|
79
|
+
attr_reader :name, :code, :cname, :description
|
80
|
+
|
81
|
+
def initialize name, code, cname, description
|
82
|
+
raise ArgumentError, "Expecting Symbol for #{self.class.name} instead of: #{name.inspect}" unless Symbol === name
|
83
|
+
raise ArgumentError, "Expecting Integer for #{self.class.name} instead of: #{code.inspect}" unless Integer === code
|
84
|
+
@name, @code, @cname, @description = name, code, cname, description
|
85
|
+
freeze
|
86
|
+
end
|
87
|
+
|
88
|
+
def === x
|
89
|
+
case x
|
90
|
+
when self.class then @id == x.id
|
91
|
+
when Symbol then @name == x
|
92
|
+
when String then @name == x.to_sym
|
93
|
+
when Integer then @code == x
|
94
|
+
else nil
|
95
|
+
end
|
95
96
|
end
|
96
|
-
|
97
|
+
|
98
|
+
def <=>( x) @id <=> x.id end
|
99
|
+
def to_s() @name.to_s end
|
100
|
+
def to_sym() @name end
|
101
|
+
def to_i() @code end
|
102
|
+
end
|
103
|
+
|
104
|
+
module Knot::Protocol::Codes
|
105
|
+
include Enumerable
|
106
|
+
def [] k
|
97
107
|
case k
|
98
108
|
when Symbol
|
99
|
-
Name[k] or raise Knot::Errors::EINVAL, "Unknown
|
109
|
+
self::Name[k] or raise Knot::Errors::EINVAL, "Unknown Codes: #{k}"
|
100
110
|
when Integer
|
101
|
-
|
111
|
+
self::Code[k] or raise Knot::Errors::EINVAL, "Unknown Codes: #{k}"
|
102
112
|
else
|
103
|
-
raise ArgumentError, "Unknown
|
113
|
+
raise ArgumentError, "Unknown Codes-Type: #{k}"
|
104
114
|
end
|
105
115
|
end
|
116
|
+
|
117
|
+
def each &exe
|
118
|
+
block_given? ? self::Codes.each( &exe) : self::Codes.to_enum( :each)
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
module Knot::Protocol::Idx
|
123
|
+
extend Knot::Protocol::Codes
|
124
|
+
|
125
|
+
Codes = [
|
126
|
+
Knot::Protocol::Code.new( :command, 0x10, :CMD, 'Control command name.'),
|
127
|
+
Knot::Protocol::Code.new( :flags, 0x11, :FLAGS, 'Control command flags.'),
|
128
|
+
Knot::Protocol::Code.new( :error, 0x12, :ERROR, 'Error message.'),
|
129
|
+
Knot::Protocol::Code.new( :section, 0x13, :SECTION, 'Configuration section name.'),
|
130
|
+
Knot::Protocol::Code.new( :item, 0x14, :ITEM, 'Configuration item name.'),
|
131
|
+
Knot::Protocol::Code.new( :id, 0x15, :ID, 'Congiguration item identifier.'),
|
132
|
+
Knot::Protocol::Code.new( :zone, 0x16, :ZONE, 'Zone name.'),
|
133
|
+
Knot::Protocol::Code.new( :owner, 0x17, :OWNER, 'Zone record owner'),
|
134
|
+
Knot::Protocol::Code.new( :ttl, 0x18, :TTL, 'Zone record TTL.'),
|
135
|
+
Knot::Protocol::Code.new( :type, 0x19, :TYPE, 'Zone record type name.'),
|
136
|
+
Knot::Protocol::Code.new( :data, 0x1a, :DATA, 'Configuration item/zone record data.'),
|
137
|
+
Knot::Protocol::Code.new( :filter, 0x1b, :FILTER, 'An option or a filter for output data processing.'),
|
138
|
+
]
|
139
|
+
Name = {}
|
140
|
+
Code = {}
|
141
|
+
|
142
|
+
Codes.each do |id|
|
143
|
+
Code[id.to_i] = id
|
144
|
+
Name[id.to_sym] = id
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
module Knot::Protocol::Types
|
149
|
+
extend Knot::Protocol::Codes
|
150
|
+
|
151
|
+
Codes = [
|
152
|
+
Knot::Protocol::Code.new( :end, 0x00, :END, 'Type END.'),
|
153
|
+
Knot::Protocol::Code.new( :data, 0x01, :DATA, 'Type DATA.'),
|
154
|
+
Knot::Protocol::Code.new( :extra, 0x02, :EXTRA, 'Type EXTRA.'),
|
155
|
+
Knot::Protocol::Code.new( :block, 0x03, :BLOCK, 'Type BLOCK.'),
|
156
|
+
]
|
157
|
+
|
158
|
+
Name = {}
|
159
|
+
Code = {}
|
160
|
+
|
161
|
+
Codes.each do |id|
|
162
|
+
Code[id.to_i] = id
|
163
|
+
Name[id.to_sym] = id
|
164
|
+
end
|
106
165
|
end
|
107
166
|
|
108
167
|
class Knot::Protocol
|
109
|
-
attr_reader :sock, :conf, :zones
|
110
|
-
attr_accessor :debug
|
168
|
+
attr_reader :sock, :conf, :zones, :logger
|
111
169
|
|
112
|
-
def initialize path_or_sock = nil
|
170
|
+
def initialize path_or_sock = nil, logger: nil
|
113
171
|
case path_or_sock
|
114
172
|
when String, Pathname
|
115
173
|
@sock = UNIXSocket.new path_or_sock.to_s
|
@@ -118,24 +176,32 @@ class Knot::Protocol
|
|
118
176
|
when nil
|
119
177
|
@sock = UNIXSocket.new '/run/knot/knot.sock'
|
120
178
|
end
|
121
|
-
@
|
179
|
+
@logger = logger || Logger.new(STDERR)
|
122
180
|
@conf = Knot::Conf.new self
|
123
181
|
@zones = Hash.new {|h, zone| h[zone] = Knot::Zone.new zone, self }
|
124
182
|
end
|
125
183
|
|
126
184
|
def snd sock: nil, **data
|
127
185
|
rsock = sock || @sock
|
128
|
-
s = ''
|
129
|
-
sock = StringIO.new s
|
130
|
-
sock.write [1].pack( 'c')
|
186
|
+
#s = ''.b
|
187
|
+
#sock = StringIO.new s
|
188
|
+
#sock.write [1].pack( 'c')
|
131
189
|
data[:flags] ||= ''
|
132
|
-
|
133
|
-
|
134
|
-
|
190
|
+
ds =
|
191
|
+
Idx.
|
192
|
+
select {|n| data[n.to_sym] }.
|
193
|
+
map {|n| v = data[n.to_sym].to_s.b; [n.to_i, v.size, v ] }
|
194
|
+
s = [Types[:data].to_i, ds, Types[:block].to_i].flatten.pack( "c #{'c na*'*ds.length} c").b
|
195
|
+
#Idx.each do |n|
|
196
|
+
# v = data[n.to_sym]&.to_s&.b
|
197
|
+
# sock.write [n.to_i, v.size, v].pack( 'c na*') if v
|
198
|
+
#end
|
199
|
+
#sock.write [3].pack( 'c')
|
200
|
+
#sock.flush
|
201
|
+
if 0 >= @logger.sev_threshold
|
202
|
+
@logger.debug "send data #{data.inspect}"
|
203
|
+
@logger.debug "send raw #{s.inspect}"
|
135
204
|
end
|
136
|
-
sock.write [3].pack( 'c')
|
137
|
-
sock.flush
|
138
|
-
STDERR.puts( {data: data, _: s}.inspect) if @debug
|
139
205
|
rsock.write s
|
140
206
|
rsock.flush
|
141
207
|
end
|
@@ -144,45 +210,48 @@ class Knot::Protocol
|
|
144
210
|
attr_reader :str
|
145
211
|
|
146
212
|
def initialize sock, str = nil
|
147
|
-
@str, @sock = str || '', sock
|
213
|
+
@str, @sock = str || ''.b, sock
|
148
214
|
end
|
149
215
|
|
150
216
|
def unpack pattern
|
151
|
-
IOUnpack.new(pattern).unpack self
|
217
|
+
IOUnpack.new( pattern).unpack self
|
152
218
|
end
|
153
219
|
|
154
220
|
def unpack1 pattern
|
155
|
-
IOUnpack.new(pattern).unpack1 self
|
221
|
+
IOUnpack.new( pattern).unpack1 self
|
156
222
|
end
|
157
223
|
|
158
224
|
def read n
|
159
225
|
s = @sock.read n
|
160
|
-
@str.insert -1, s
|
161
|
-
s
|
226
|
+
@str.insert -1, s unless s.nil?
|
227
|
+
s || ''
|
162
228
|
end
|
163
229
|
end
|
164
230
|
|
165
231
|
def rcv sock: nil
|
166
232
|
ret, r = [], nil
|
167
233
|
sock = sock || @sock
|
168
|
-
sock = RecordIO.new sock if @
|
234
|
+
sock = RecordIO.new sock if 0 >= @logger.sev_threshold
|
169
235
|
loop do
|
170
236
|
t = sock.unpack1 'c'
|
171
237
|
case t
|
172
|
-
when
|
238
|
+
when Knot::Protocol::Types[:end], Knot::Protocol::Types[:block]
|
173
239
|
return ret
|
174
|
-
when
|
240
|
+
when Knot::Protocol::Types[:data], Knot::Protocol::Types[:extra]
|
175
241
|
type = t
|
176
242
|
ret.push( r = {})
|
177
243
|
else
|
178
244
|
raise Knot::Errors::EINVAL, "Missing Type before: #{t}" if ret.empty?
|
179
|
-
i = Idx
|
245
|
+
i = Idx[t] or raise Knot::Errors::EINVAL, "Unknown index: #{t}"
|
180
246
|
l = sock.unpack1 'n'
|
181
|
-
r[i] = sock.read( l)
|
247
|
+
r[i.to_sym] = sock.read( l)
|
182
248
|
end
|
183
249
|
end
|
184
250
|
ensure
|
185
|
-
|
251
|
+
if RecordIO === sock
|
252
|
+
@logger.debug "rcvd raw #{sock.str.inspect}"
|
253
|
+
@logger.debug "rcvd data #{ret.inspect}"
|
254
|
+
end
|
186
255
|
ret
|
187
256
|
end
|
188
257
|
|
data/lib/knot/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knot-ruby
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Denis Knauf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2022-
|
11
|
+
date: 2022-12-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: iounpack
|
@@ -64,8 +64,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
64
64
|
- !ruby/object:Gem::Version
|
65
65
|
version: '0'
|
66
66
|
requirements: []
|
67
|
-
|
68
|
-
rubygems_version: 2.7.6.2
|
67
|
+
rubygems_version: 3.2.5
|
69
68
|
signing_key:
|
70
69
|
specification_version: 4
|
71
70
|
summary: Provides interface to knot-server.
|