hrr_rb_netconf 0.1.1 → 0.2.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/demo/server.rb +2 -3
- data/demo/server_over_ssh.rb +4 -6
- data/demo/server_with_session-oriented-database.rb +4 -6
- data/demo/server_with_sessionless-database.rb +2 -4
- data/lib/hrr_rb_netconf/loggable.rb +42 -0
- data/lib/hrr_rb_netconf/server/capabilities.rb +8 -4
- data/lib/hrr_rb_netconf/server/capability/base_1_0.rb +97 -91
- data/lib/hrr_rb_netconf/server/capability/base_1_1.rb +109 -103
- data/lib/hrr_rb_netconf/server/capability/candidate_1_0.rb +19 -17
- data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_0.rb +4 -2
- data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_1.rb +10 -8
- data/lib/hrr_rb_netconf/server/capability/notification_1_0.rb +62 -62
- data/lib/hrr_rb_netconf/server/capability/rollback_on_error_1_0.rb +3 -1
- data/lib/hrr_rb_netconf/server/capability/startup_1_0.rb +9 -7
- data/lib/hrr_rb_netconf/server/capability/url_1_0.rb +7 -5
- data/lib/hrr_rb_netconf/server/capability/validate_1_0.rb +10 -8
- data/lib/hrr_rb_netconf/server/capability/validate_1_1.rb +11 -9
- data/lib/hrr_rb_netconf/server/capability/writable_running_1_0.rb +4 -2
- data/lib/hrr_rb_netconf/server/capability.rb +16 -27
- data/lib/hrr_rb_netconf/server/datastore/oper_handler.rb +9 -7
- data/lib/hrr_rb_netconf/server/datastore/session.rb +7 -5
- data/lib/hrr_rb_netconf/server/datastore.rb +7 -5
- data/lib/hrr_rb_netconf/server/error/rpc_errorable.rb +8 -5
- data/lib/hrr_rb_netconf/server/model.rb +9 -5
- data/lib/hrr_rb_netconf/server/notification_event.rb +0 -1
- data/lib/hrr_rb_netconf/server/notification_streams.rb +0 -1
- data/lib/hrr_rb_netconf/server/operation.rb +12 -10
- data/lib/hrr_rb_netconf/server/session.rb +39 -37
- data/lib/hrr_rb_netconf/server.rb +24 -22
- data/lib/hrr_rb_netconf/version.rb +1 -1
- data/lib/hrr_rb_netconf.rb +0 -1
- metadata +3 -3
- data/lib/hrr_rb_netconf/logger.rb +0 -56
@@ -2,7 +2,7 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'rexml/document'
|
5
|
-
require 'hrr_rb_netconf/
|
5
|
+
require 'hrr_rb_netconf/loggable'
|
6
6
|
|
7
7
|
module HrrRbNetconf
|
8
8
|
class Server
|
@@ -12,92 +12,96 @@ module HrrRbNetconf
|
|
12
12
|
DEPENDENCIES = []
|
13
13
|
IF_FEATURES = []
|
14
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
|
-
oper_proc('lock'){ |session, datastore, input_e|
|
39
|
-
target = input_e.elements['target'].elements[1].name
|
40
|
-
session.lock target
|
41
|
-
begin
|
42
|
-
datastore.run 'lock', input_e
|
15
|
+
def define_capability
|
16
|
+
oper_proc('get'){ |session, datastore, input_e|
|
17
|
+
datastore.run 'get', input_e
|
18
|
+
}
|
19
|
+
|
20
|
+
oper_proc('get-config'){ |session, datastore, input_e|
|
21
|
+
datastore.run 'get-config', input_e
|
22
|
+
}
|
23
|
+
|
24
|
+
oper_proc('edit-config'){ |session, datastore, input_e|
|
25
|
+
datastore.run 'edit-config', input_e
|
26
|
+
'<ok />'
|
27
|
+
}
|
28
|
+
|
29
|
+
oper_proc('copy-config'){ |session, datastore, input_e|
|
30
|
+
datastore.run 'copy-config', input_e
|
31
|
+
'<ok />'
|
32
|
+
}
|
33
|
+
|
34
|
+
oper_proc('delete-config'){ |session, datastore, input_e|
|
35
|
+
datastore.run 'delete-config', input_e
|
43
36
|
'<ok />'
|
44
|
-
|
37
|
+
}
|
38
|
+
|
39
|
+
oper_proc('lock'){ |session, datastore, input_e|
|
40
|
+
target = input_e.elements['target'].elements[1].name
|
41
|
+
session.lock target
|
42
|
+
begin
|
43
|
+
datastore.run 'lock', input_e
|
44
|
+
'<ok />'
|
45
|
+
rescue
|
46
|
+
session.unlock target
|
47
|
+
raise
|
48
|
+
end
|
49
|
+
}
|
50
|
+
|
51
|
+
oper_proc('unlock'){ |session, datastore, input_e|
|
52
|
+
datastore.run 'unlock', input_e
|
53
|
+
target = input_e.elements['target'].elements[1].name
|
45
54
|
session.unlock target
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
'
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
model 'lock', ['target', 'config-target'], 'choice', 'mandatory' => true
|
89
|
-
model 'lock', ['target', 'config-target', 'running'], 'leaf', 'type' => 'empty'
|
90
|
-
model 'unlock', ['target'], 'container'
|
91
|
-
model 'unlock', ['target', 'config-target'], 'choice', 'mandatory' => true
|
92
|
-
model 'unlock', ['target', 'config-target', 'running'], 'leaf', 'type' => 'empty'
|
93
|
-
model 'close-session', []
|
94
|
-
model 'kill-session', ['session-id'], 'leaf', 'type' => 'integer', 'range' => [1, 2**32-1]
|
55
|
+
'<ok />'
|
56
|
+
}
|
57
|
+
|
58
|
+
oper_proc('close-session'){ |session, datastore, input_e|
|
59
|
+
datastore.run 'close-session', input_e
|
60
|
+
session.close
|
61
|
+
'<ok />'
|
62
|
+
}
|
63
|
+
|
64
|
+
oper_proc('kill-session'){ |session, datastore, input_e|
|
65
|
+
session.close_other Integer(input_e.elements['session-id'].text)
|
66
|
+
'<ok />'
|
67
|
+
}
|
68
|
+
|
69
|
+
model 'get', ['filter'], 'leaf', 'type' => 'anyxml'
|
70
|
+
model 'get-config', ['source'], 'container'
|
71
|
+
model 'get-config', ['source', 'config-source'], 'choice', 'mandatory' => true
|
72
|
+
model 'get-config', ['source', 'config-source', 'running'], 'leaf', 'type' => 'empty'
|
73
|
+
model 'get-config', ['filter'], 'leaf', 'type' => 'anyxml'
|
74
|
+
model 'edit-config', ['target'], 'container'
|
75
|
+
model 'edit-config', ['target', 'config-target'], 'choice', 'mandatory' => true
|
76
|
+
model 'edit-config', ['default-operation'], 'leaf', 'type' => 'enumeration', 'enum' => ['merge', 'replace', 'none'], 'default' => 'merge'
|
77
|
+
model 'edit-config', ['error-option'], 'leaf', 'type' => 'enumeration', 'enum' => ['stop-on-error', 'continue-on-error', 'rollback-on-error'], 'default' => 'stop-on-error'
|
78
|
+
model 'edit-config', ['edit-content'], 'choice', 'mandatory' => true
|
79
|
+
model 'edit-config', ['edit-content', 'config'], 'leaf', 'type' => 'anyxml'
|
80
|
+
model 'copy-config', ['target'], 'container'
|
81
|
+
model 'copy-config', ['target', 'config-target'], 'choice', 'mandatory' => true
|
82
|
+
model 'copy-config', ['source'], 'container'
|
83
|
+
model 'copy-config', ['source', 'config-source'], 'choice', 'mandatory' => true
|
84
|
+
model 'copy-config', ['source', 'config-source', 'running'], 'leaf', 'type' => 'empty'
|
85
|
+
model 'copy-config', ['source', 'config-source', 'config'], 'leaf', 'type' => 'anyxml'
|
86
|
+
model 'delete-config', ['target'], 'container'
|
87
|
+
model 'delete-config', ['target', 'config-target'], 'choice', 'mandatory' => true
|
88
|
+
model 'lock', ['target'], 'container'
|
89
|
+
model 'lock', ['target', 'config-target'], 'choice', 'mandatory' => true
|
90
|
+
model 'lock', ['target', 'config-target', 'running'], 'leaf', 'type' => 'empty'
|
91
|
+
model 'unlock', ['target'], 'container'
|
92
|
+
model 'unlock', ['target', 'config-target'], 'choice', 'mandatory' => true
|
93
|
+
model 'unlock', ['target', 'config-target', 'running'], 'leaf', 'type' => 'empty'
|
94
|
+
model 'close-session', []
|
95
|
+
model 'kill-session', ['session-id'], 'leaf', 'type' => 'integer', 'range' => [1, 2**32-1]
|
96
|
+
end
|
95
97
|
|
96
98
|
class Sender
|
99
|
+
include Loggable
|
100
|
+
|
97
101
|
MAX_CHUNK_SIZE = 2**32 - 1
|
98
102
|
|
99
|
-
def initialize io_w
|
100
|
-
|
103
|
+
def initialize io_w, logger: nil
|
104
|
+
self.logger = logger
|
101
105
|
@io_w = io_w
|
102
106
|
@formatter = REXML::Formatters::Pretty.new(2)
|
103
107
|
@formatter.compact = true
|
@@ -110,7 +114,7 @@ module HrrRbNetconf
|
|
110
114
|
begin
|
111
115
|
@formatter.write(REXML::Document.new(msg, {:ignore_whitespace_nodes => :all}).root, raw_msg)
|
112
116
|
rescue => e
|
113
|
-
|
117
|
+
log_error { "Invalid sending message: #{msg.inspect}: #{e.message}" }
|
114
118
|
raise "Invalid sending message: #{msg.inspect}: #{e.message}"
|
115
119
|
end
|
116
120
|
when REXML::Document
|
@@ -118,10 +122,10 @@ module HrrRbNetconf
|
|
118
122
|
when REXML::Element
|
119
123
|
@formatter.write(msg, raw_msg)
|
120
124
|
else
|
121
|
-
|
125
|
+
log_error { "Unexpected sending message: #{msg.inspect}" }
|
122
126
|
raise ArgumentError, "Unexpected sending message: #{msg.inspect}"
|
123
127
|
end
|
124
|
-
|
128
|
+
log_debug { "Sending message: #{raw_msg.string.inspect}" }
|
125
129
|
raw_msg.rewind
|
126
130
|
encoded_msg = StringIO.new
|
127
131
|
until raw_msg.eof?
|
@@ -130,19 +134,21 @@ module HrrRbNetconf
|
|
130
134
|
encoded_msg.write "\n##{chunk_data.size}\n#{chunk_data}"
|
131
135
|
end
|
132
136
|
encoded_msg.write "\n##\n"
|
133
|
-
|
137
|
+
log_debug { "Sending encoded message: #{encoded_msg.string.inspect}" }
|
134
138
|
begin
|
135
139
|
@io_w.write encoded_msg.string
|
136
140
|
rescue => e
|
137
|
-
|
141
|
+
log_info { "Sender IO closed: #{e.class}: #{e.message}" }
|
138
142
|
raise IOError, "Sender IO closed: #{e.class}: #{e.message}"
|
139
143
|
end
|
140
144
|
end
|
141
145
|
end
|
142
146
|
|
143
147
|
class Receiver
|
144
|
-
|
145
|
-
|
148
|
+
include Loggable
|
149
|
+
|
150
|
+
def initialize io_r, logger: nil
|
151
|
+
self.logger = logger
|
146
152
|
@io_r = io_r
|
147
153
|
end
|
148
154
|
|
@@ -156,11 +162,11 @@ module HrrRbNetconf
|
|
156
162
|
begin
|
157
163
|
buf = @io_r.read(read_len)
|
158
164
|
rescue => e
|
159
|
-
|
165
|
+
log_info { "Receiver IO closed: #{e.class}: #{e.message}" }
|
160
166
|
return nil
|
161
167
|
end
|
162
168
|
if buf.nil?
|
163
|
-
|
169
|
+
log_info { "Receiver IO closed" }
|
164
170
|
return nil
|
165
171
|
end
|
166
172
|
chunked_msg.write buf
|
@@ -170,16 +176,16 @@ module HrrRbNetconf
|
|
170
176
|
state = :before_chunk_size
|
171
177
|
else
|
172
178
|
info = "In beginning_of_msg: expected #{"\n".inspect}, but got #{buf.inspect}: #{chunked_msg.string.inspect}"
|
173
|
-
|
174
|
-
raise Error['malformed-message'].new("rpc", "error")
|
179
|
+
log_info { info }
|
180
|
+
raise Error['malformed-message'].new("rpc", "error", logger: logger)
|
175
181
|
end
|
176
182
|
when :before_chunk_size
|
177
183
|
if buf == "#"
|
178
184
|
state = :in_chunk_size
|
179
185
|
else
|
180
186
|
info = "In before_chunk_size: expected #{"#".inspect}, but got #{buf.inspect}: #{chunked_msg.string.inspect}"
|
181
|
-
|
182
|
-
raise Error['malformed-message'].new("rpc", "error")
|
187
|
+
log_info { info }
|
188
|
+
raise Error['malformed-message'].new("rpc", "error", logger: logger)
|
183
189
|
end
|
184
190
|
when :in_chunk_size
|
185
191
|
if buf =~ /[0-9]/
|
@@ -191,8 +197,8 @@ module HrrRbNetconf
|
|
191
197
|
state = :ending_msg
|
192
198
|
else
|
193
199
|
info = "In in_chunk_size: expected #{"/[0-9]/".inspect}, #{"\n".inspect}, or #{"#".inspect}, but got #{buf.inspect}: #{chunked_msg.string.inspect}"
|
194
|
-
|
195
|
-
raise Error['malformed-message'].new("rpc", "error")
|
200
|
+
log_info { info }
|
201
|
+
raise Error['malformed-message'].new("rpc", "error", logger: logger)
|
196
202
|
end
|
197
203
|
when :in_chunk_data
|
198
204
|
chunk_size = StringIO.new
|
@@ -204,28 +210,28 @@ module HrrRbNetconf
|
|
204
210
|
state = :before_chunk_size
|
205
211
|
else
|
206
212
|
info = "In after_chunk_data: expected #{"\n".inspect}, but got #{buf.inspect}: #{chunked_msg.string.inspect}"
|
207
|
-
|
208
|
-
raise Error['malformed-message'].new("rpc", "error")
|
213
|
+
log_info { info }
|
214
|
+
raise Error['malformed-message'].new("rpc", "error", logger: logger)
|
209
215
|
end
|
210
216
|
when :ending_msg
|
211
217
|
if buf == "\n"
|
212
218
|
state = :end_of_msg
|
213
219
|
else
|
214
220
|
info = "In ending_msg: expected #{"\n".inspect}, but got #{buf.inspect}: #{chunked_msg.string.inspect}"
|
215
|
-
|
216
|
-
raise Error['malformed-message'].new("rpc", "error")
|
221
|
+
log_info { info }
|
222
|
+
raise Error['malformed-message'].new("rpc", "error", logger: logger)
|
217
223
|
end
|
218
224
|
end
|
219
225
|
end
|
220
|
-
|
226
|
+
log_debug { "Received message: #{decoded_msg.string.inspect}" }
|
221
227
|
begin
|
222
228
|
received_msg = REXML::Document.new(decoded_msg.string, {:ignore_whitespace_nodes => :all}).root
|
223
229
|
validate_received_msg received_msg
|
224
230
|
received_msg
|
225
231
|
rescue => e
|
226
232
|
info = "Invalid received message: #{e.message.split("\n").first}: #{decoded_msg.string.inspect}"
|
227
|
-
|
228
|
-
raise Error['malformed-message'].new("rpc", "error")
|
233
|
+
log_info { info }
|
234
|
+
raise Error['malformed-message'].new("rpc", "error", logger: logger)
|
229
235
|
end
|
230
236
|
end
|
231
237
|
|
@@ -9,25 +9,27 @@ module HrrRbNetconf
|
|
9
9
|
DEPENDENCIES = []
|
10
10
|
IF_FEATURES = ['candidate']
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def define_capability
|
13
|
+
oper_proc('commit'){ |session, datastore, input_e|
|
14
|
+
datastore.run 'commit', input_e
|
15
|
+
'<ok />'
|
16
|
+
}
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
oper_proc('discard-changes'){ |session, datastore, input_e|
|
19
|
+
datastore.run 'discard-changes', input_e
|
20
|
+
'<ok />'
|
21
|
+
}
|
21
22
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
23
|
+
model 'get-config', ['source', 'config-source', 'candidate'], 'leaf', 'type' => 'empty'
|
24
|
+
model 'edit-config', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
|
25
|
+
model 'copy-config', ['source', 'config-source', 'candidate'], 'leaf', 'type' => 'empty'
|
26
|
+
model 'copy-config', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
|
27
|
+
model 'validate', ['source', 'config-source', 'candidate'], 'leaf', 'type' => 'empty'
|
28
|
+
model 'lock', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
|
29
|
+
model 'unlock', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
|
30
|
+
model 'commit', []
|
31
|
+
model 'discard-changes', []
|
32
|
+
end
|
31
33
|
end
|
32
34
|
end
|
33
35
|
end
|
@@ -9,8 +9,10 @@ module HrrRbNetconf
|
|
9
9
|
DEPENDENCIES = ['urn:ietf:params:netconf:capability:candidate:1.0']
|
10
10
|
IF_FEATURES = ['candidate', 'confirmed-commit']
|
11
11
|
|
12
|
-
|
13
|
-
|
12
|
+
def define_capability
|
13
|
+
model 'commit', ['confirmed'], 'leaf', 'type' => 'empty'
|
14
|
+
model 'commit', ['confirm-timeout'], 'leaf', 'type' => 'integer', 'range' => [1, 2**32-1], 'default' => '600'
|
15
|
+
end
|
14
16
|
end
|
15
17
|
end
|
16
18
|
end
|
@@ -9,15 +9,17 @@ module HrrRbNetconf
|
|
9
9
|
DEPENDENCIES = ['urn:ietf:params:netconf:capability:candidate:1.0']
|
10
10
|
IF_FEATURES = ['candidate', 'confirmed-commit']
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
12
|
+
def define_capability
|
13
|
+
oper_proc('cancel-commit'){ |session, datastore, input_e|
|
14
|
+
datastore.run 'cancel-commit', input_e
|
15
|
+
'<ok />'
|
16
|
+
}
|
16
17
|
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
18
|
+
model 'commit', ['confirmed'], 'leaf', 'type' => 'empty'
|
19
|
+
model 'commit', ['confirm-timeout'], 'leaf', 'type' => 'integer', 'range' => [1, 2**32-1], 'default' => '600'
|
20
|
+
model 'commit', ['persist'], 'leaf', 'type' => 'string'
|
21
|
+
model 'commit', ['persist-id'], 'leaf', 'type' => 'string'
|
22
|
+
end
|
21
23
|
end
|
22
24
|
end
|
23
25
|
end
|
@@ -2,7 +2,6 @@
|
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
4
|
require 'rexml/document'
|
5
|
-
require 'hrr_rb_netconf/logger'
|
6
5
|
|
7
6
|
module HrrRbNetconf
|
8
7
|
class Server
|
@@ -12,69 +11,70 @@ module HrrRbNetconf
|
|
12
11
|
DEPENDENCIES = []
|
13
12
|
IF_FEATURES = ['notification']
|
14
13
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
end
|
23
|
-
stream = stream_e.text
|
24
|
-
start_time_e = input_e.elements['startTime']
|
25
|
-
start_time = unless start_time_e
|
26
|
-
nil
|
27
|
-
else
|
28
|
-
DateTime.rfc3339(start_time_e.text)
|
29
|
-
end
|
30
|
-
stop_time_e = input_e.elements['stopTime']
|
31
|
-
stop_time = unless stop_time_e
|
32
|
-
nil
|
33
|
-
else
|
34
|
-
DateTime.rfc3339(stop_time_e.text)
|
35
|
-
end
|
36
|
-
if ! session.subscription_creatable? stream
|
37
|
-
logger.error { "Not available stream: #{stream}" }
|
38
|
-
raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'stream'})
|
39
|
-
end
|
40
|
-
if start_time.nil? && stop_time
|
41
|
-
logger.error { "startTime element doesn't exist, but stopTime does" }
|
42
|
-
raise Error['missing-element'].new('protocol', 'error', info: {'bad-element' => 'startTime'})
|
43
|
-
end
|
44
|
-
if start_time && stop_time && (start_time > stop_time)
|
45
|
-
logger.error { "stopTime is earlier than startTime" }
|
46
|
-
raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'stopTime'})
|
47
|
-
end
|
48
|
-
if start_time && (start_time > DateTime.now)
|
49
|
-
logger.error { "startTime is later than current time" }
|
50
|
-
raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'startTime'})
|
51
|
-
end
|
52
|
-
begin
|
53
|
-
events = datastore.run('create-subscription', input_e)
|
54
|
-
rescue Error
|
55
|
-
raise
|
56
|
-
rescue => e
|
57
|
-
logger.error { "Exception in datastore.run('create-subscription', input_e): #{e.message}" }
|
58
|
-
raise Error['operation-failed'].new('application', 'error')
|
59
|
-
end
|
60
|
-
begin
|
61
|
-
if start_time
|
62
|
-
session.notification_replay stream, start_time, stop_time, events
|
14
|
+
def define_capability
|
15
|
+
oper_proc('create-subscription'){ |session, datastore, input_e|
|
16
|
+
stream_e = input_e.elements['stream']
|
17
|
+
unless stream_e
|
18
|
+
log_debug { "create-subscription doesn't have stream, so use NETCONF stream" }
|
19
|
+
stream_e = input_e.add_element('stream')
|
20
|
+
stream_e.text = 'NETCONF'
|
63
21
|
end
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
22
|
+
stream = stream_e.text
|
23
|
+
start_time_e = input_e.elements['startTime']
|
24
|
+
start_time = unless start_time_e
|
25
|
+
nil
|
26
|
+
else
|
27
|
+
DateTime.rfc3339(start_time_e.text)
|
28
|
+
end
|
29
|
+
stop_time_e = input_e.elements['stopTime']
|
30
|
+
stop_time = unless stop_time_e
|
31
|
+
nil
|
32
|
+
else
|
33
|
+
DateTime.rfc3339(stop_time_e.text)
|
34
|
+
end
|
35
|
+
if ! session.subscription_creatable? stream
|
36
|
+
log_error { "Not available stream: #{stream}" }
|
37
|
+
raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'stream'}, logger: logger)
|
38
|
+
end
|
39
|
+
if start_time.nil? && stop_time
|
40
|
+
log_error { "startTime element doesn't exist, but stopTime does" }
|
41
|
+
raise Error['missing-element'].new('protocol', 'error', info: {'bad-element' => 'startTime'}, logger: logger)
|
42
|
+
end
|
43
|
+
if start_time && stop_time && (start_time > stop_time)
|
44
|
+
log_error { "stopTime is earlier than startTime" }
|
45
|
+
raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'stopTime'}, logger: logger)
|
46
|
+
end
|
47
|
+
if start_time && (start_time > DateTime.now)
|
48
|
+
log_error { "startTime is later than current time" }
|
49
|
+
raise Error['bad-element'].new('protocol', 'error', info: {'bad-element' => 'startTime'}, logger: logger)
|
50
|
+
end
|
51
|
+
begin
|
52
|
+
events = datastore.run('create-subscription', input_e)
|
53
|
+
rescue Error
|
54
|
+
raise
|
55
|
+
rescue => e
|
56
|
+
log_error { "Exception in datastore.run('create-subscription', input_e): #{e.message}" }
|
57
|
+
raise Error['operation-failed'].new('application', 'error', logger: logger)
|
58
|
+
end
|
59
|
+
begin
|
60
|
+
if start_time
|
61
|
+
session.notification_replay stream, start_time, stop_time, events
|
62
|
+
end
|
63
|
+
rescue Error
|
64
|
+
raise
|
65
|
+
rescue => e
|
66
|
+
log_error { "Exception in session.notification_replay: #{e.message}" }
|
67
|
+
raise Error['operation-failed'].new('protocol', 'error', logger: logger)
|
68
|
+
end
|
69
|
+
session.create_subscription stream, start_time, stop_time
|
70
|
+
'<ok />'
|
71
|
+
}
|
73
72
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
73
|
+
model 'create-subscription', ['stream'], 'leaf', 'type' => 'string'
|
74
|
+
model 'create-subscription', ['filter'], 'leaf', 'type' => 'anyxml'
|
75
|
+
model 'create-subscription', ['startTime'], 'leaf', 'type' => 'string'
|
76
|
+
model 'create-subscription', ['stopTime'], 'leaf', 'type' => 'string'
|
77
|
+
end
|
78
78
|
end
|
79
79
|
end
|
80
80
|
end
|
@@ -9,7 +9,9 @@ module HrrRbNetconf
|
|
9
9
|
DEPENDENCIES = []
|
10
10
|
IF_FEATURES = ['rollback-on-error']
|
11
11
|
|
12
|
-
|
12
|
+
def define_capability
|
13
|
+
model 'edit-config', ['error-option'], 'leaf', 'type' => 'enumeration', 'enum' => ['stop-on-error', 'continue-on-error', 'rollback-on-error'], 'default' => 'stop-on-error'
|
14
|
+
end
|
13
15
|
end
|
14
16
|
end
|
15
17
|
end
|
@@ -9,13 +9,15 @@ module HrrRbNetconf
|
|
9
9
|
DEPENDENCIES = []
|
10
10
|
IF_FEATURES = ['startup']
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
12
|
+
def define_capability
|
13
|
+
model 'get-config', ['source', 'config-source', 'startup'], 'leaf', 'type' => 'empty'
|
14
|
+
model 'copy-config', ['source', 'config-source', 'startup'], 'leaf', 'type' => 'empty'
|
15
|
+
model 'copy-config', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
|
16
|
+
model 'lock', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
|
17
|
+
model 'unlock', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
|
18
|
+
model 'validate', ['source', 'config-source', 'startup'], 'leaf', 'type' => 'empty'
|
19
|
+
model 'delete-config', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
|
20
|
+
end
|
19
21
|
end
|
20
22
|
end
|
21
23
|
end
|
@@ -12,11 +12,13 @@ module HrrRbNetconf
|
|
12
12
|
DEPENDENCIES = []
|
13
13
|
IF_FEATURES = []
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
def define_capability
|
16
|
+
model 'edit-config', ['edit-content', 'url'], 'leaf', 'type' => 'string', 'validation' => proc { |cap, node| cap.queries['scheme'].any?{|s| s == URI.parse(node.text).scheme} }
|
17
|
+
model 'copy-config', ['target', 'config-target', 'url'], 'leaf', 'type' => 'string'
|
18
|
+
model 'copy-config', ['source', 'config-source', 'url'], 'leaf', 'type' => 'string'
|
19
|
+
model 'delete-config', ['target', 'config-target', 'url'], 'leaf', 'type' => 'string'
|
20
|
+
model 'validate', ['source', 'config-source', 'url'], 'leaf', 'type' => 'string'
|
21
|
+
end
|
20
22
|
end
|
21
23
|
end
|
22
24
|
end
|