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.
Files changed (34) hide show
  1. checksums.yaml +4 -4
  2. data/demo/server.rb +2 -3
  3. data/demo/server_over_ssh.rb +4 -6
  4. data/demo/server_with_session-oriented-database.rb +4 -6
  5. data/demo/server_with_sessionless-database.rb +2 -4
  6. data/lib/hrr_rb_netconf/loggable.rb +42 -0
  7. data/lib/hrr_rb_netconf/server/capabilities.rb +8 -4
  8. data/lib/hrr_rb_netconf/server/capability/base_1_0.rb +97 -91
  9. data/lib/hrr_rb_netconf/server/capability/base_1_1.rb +109 -103
  10. data/lib/hrr_rb_netconf/server/capability/candidate_1_0.rb +19 -17
  11. data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_0.rb +4 -2
  12. data/lib/hrr_rb_netconf/server/capability/confirmed_commit_1_1.rb +10 -8
  13. data/lib/hrr_rb_netconf/server/capability/notification_1_0.rb +62 -62
  14. data/lib/hrr_rb_netconf/server/capability/rollback_on_error_1_0.rb +3 -1
  15. data/lib/hrr_rb_netconf/server/capability/startup_1_0.rb +9 -7
  16. data/lib/hrr_rb_netconf/server/capability/url_1_0.rb +7 -5
  17. data/lib/hrr_rb_netconf/server/capability/validate_1_0.rb +10 -8
  18. data/lib/hrr_rb_netconf/server/capability/validate_1_1.rb +11 -9
  19. data/lib/hrr_rb_netconf/server/capability/writable_running_1_0.rb +4 -2
  20. data/lib/hrr_rb_netconf/server/capability.rb +16 -27
  21. data/lib/hrr_rb_netconf/server/datastore/oper_handler.rb +9 -7
  22. data/lib/hrr_rb_netconf/server/datastore/session.rb +7 -5
  23. data/lib/hrr_rb_netconf/server/datastore.rb +7 -5
  24. data/lib/hrr_rb_netconf/server/error/rpc_errorable.rb +8 -5
  25. data/lib/hrr_rb_netconf/server/model.rb +9 -5
  26. data/lib/hrr_rb_netconf/server/notification_event.rb +0 -1
  27. data/lib/hrr_rb_netconf/server/notification_streams.rb +0 -1
  28. data/lib/hrr_rb_netconf/server/operation.rb +12 -10
  29. data/lib/hrr_rb_netconf/server/session.rb +39 -37
  30. data/lib/hrr_rb_netconf/server.rb +24 -22
  31. data/lib/hrr_rb_netconf/version.rb +1 -1
  32. data/lib/hrr_rb_netconf.rb +0 -1
  33. metadata +3 -3
  34. 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/logger'
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
- oper_proc('get'){ |session, datastore, input_e|
16
- datastore.run 'get', input_e
17
- }
18
-
19
- oper_proc('get-config'){ |session, datastore, input_e|
20
- datastore.run 'get-config', input_e
21
- }
22
-
23
- oper_proc('edit-config'){ |session, datastore, input_e|
24
- datastore.run 'edit-config', input_e
25
- '<ok />'
26
- }
27
-
28
- oper_proc('copy-config'){ |session, datastore, input_e|
29
- datastore.run 'copy-config', input_e
30
- '<ok />'
31
- }
32
-
33
- oper_proc('delete-config'){ |session, datastore, input_e|
34
- datastore.run 'delete-config', input_e
35
- '<ok />'
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
- rescue
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
- raise
47
- end
48
- }
49
-
50
- oper_proc('unlock'){ |session, datastore, input_e|
51
- datastore.run 'unlock', input_e
52
- target = input_e.elements['target'].elements[1].name
53
- session.unlock target
54
- '<ok />'
55
- }
56
-
57
- oper_proc('close-session'){ |session, datastore, input_e|
58
- datastore.run 'close-session', input_e
59
- session.close
60
- '<ok />'
61
- }
62
-
63
- oper_proc('kill-session'){ |session, datastore, input_e|
64
- session.close_other Integer(input_e.elements['session-id'].text)
65
- '<ok />'
66
- }
67
-
68
- model 'get', ['filter'], 'leaf', 'type' => 'anyxml'
69
- model 'get-config', ['source'], 'container'
70
- model 'get-config', ['source', 'config-source'], 'choice', 'mandatory' => true
71
- model 'get-config', ['source', 'config-source', 'running'], 'leaf', 'type' => 'empty'
72
- model 'get-config', ['filter'], 'leaf', 'type' => 'anyxml'
73
- model 'edit-config', ['target'], 'container'
74
- model 'edit-config', ['target', 'config-target'], 'choice', 'mandatory' => true
75
- model 'edit-config', ['default-operation'], 'leaf', 'type' => 'enumeration', 'enum' => ['merge', 'replace', 'none'], 'default' => 'merge'
76
- model 'edit-config', ['error-option'], 'leaf', 'type' => 'enumeration', 'enum' => ['stop-on-error', 'continue-on-error', 'rollback-on-error'], 'default' => 'stop-on-error'
77
- model 'edit-config', ['edit-content'], 'choice', 'mandatory' => true
78
- model 'edit-config', ['edit-content', 'config'], 'leaf', 'type' => 'anyxml'
79
- model 'copy-config', ['target'], 'container'
80
- model 'copy-config', ['target', 'config-target'], 'choice', 'mandatory' => true
81
- model 'copy-config', ['source'], 'container'
82
- model 'copy-config', ['source', 'config-source'], 'choice', 'mandatory' => true
83
- model 'copy-config', ['source', 'config-source', 'running'], 'leaf', 'type' => 'empty'
84
- model 'copy-config', ['source', 'config-source', 'config'], 'leaf', 'type' => 'anyxml'
85
- model 'delete-config', ['target'], 'container'
86
- model 'delete-config', ['target', 'config-target'], 'choice', 'mandatory' => true
87
- model 'lock', ['target'], 'container'
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
- @logger = Logger.new self.class.name
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
- @logger.error { "Invalid sending message: #{msg.inspect}: #{e.message}" }
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
- @logger.error { "Unexpected sending message: #{msg.inspect}" }
125
+ log_error { "Unexpected sending message: #{msg.inspect}" }
122
126
  raise ArgumentError, "Unexpected sending message: #{msg.inspect}"
123
127
  end
124
- @logger.debug { "Sending message: #{raw_msg.string.inspect}" }
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
- @logger.debug { "Sending encoded message: #{encoded_msg.string.inspect}" }
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
- @logger.info { "Sender IO closed: #{e.class}: #{e.message}" }
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
- def initialize io_r
145
- @logger = Logger.new self.class.name
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
- @logger.info { "Receiver IO closed: #{e.class}: #{e.message}" }
165
+ log_info { "Receiver IO closed: #{e.class}: #{e.message}" }
160
166
  return nil
161
167
  end
162
168
  if buf.nil?
163
- @logger.info { "Receiver IO closed" }
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
- @logger.info { info }
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
- @logger.info { info }
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
- @logger.info { info }
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
- @logger.info { info }
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
- @logger.info { info }
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
- @logger.debug { "Received message: #{decoded_msg.string.inspect}" }
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
- @logger.info { info }
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
- oper_proc('commit'){ |session, datastore, input_e|
13
- datastore.run 'commit', input_e
14
- '<ok />'
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
- oper_proc('discard-changes'){ |session, datastore, input_e|
18
- datastore.run 'discard-changes', input_e
19
- '<ok />'
20
- }
18
+ oper_proc('discard-changes'){ |session, datastore, input_e|
19
+ datastore.run 'discard-changes', input_e
20
+ '<ok />'
21
+ }
21
22
 
22
- model 'get-config', ['source', 'config-source', 'candidate'], 'leaf', 'type' => 'empty'
23
- model 'edit-config', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
24
- model 'copy-config', ['source', 'config-source', 'candidate'], 'leaf', 'type' => 'empty'
25
- model 'copy-config', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
26
- model 'validate', ['source', 'config-source', 'candidate'], 'leaf', 'type' => 'empty'
27
- model 'lock', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
28
- model 'unlock', ['target', 'config-target', 'candidate'], 'leaf', 'type' => 'empty'
29
- model 'commit', []
30
- model 'discard-changes', []
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
- model 'commit', ['confirmed'], 'leaf', 'type' => 'empty'
13
- model 'commit', ['confirm-timeout'], 'leaf', 'type' => 'integer', 'range' => [1, 2**32-1], 'default' => '600'
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
- oper_proc('cancel-commit'){ |session, datastore, input_e|
13
- datastore.run 'cancel-commit', input_e
14
- '<ok />'
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
- model 'commit', ['confirmed'], 'leaf', 'type' => 'empty'
18
- model 'commit', ['confirm-timeout'], 'leaf', 'type' => 'integer', 'range' => [1, 2**32-1], 'default' => '600'
19
- model 'commit', ['persist'], 'leaf', 'type' => 'string'
20
- model 'commit', ['persist-id'], 'leaf', 'type' => 'string'
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
- oper_proc('create-subscription'){ |session, datastore, input_e|
16
- logger = Logger.new HrrRbNetconf::Server::Capability::Notification_1_0
17
- stream_e = input_e.elements['stream']
18
- unless stream_e
19
- logger.debug { "create-subscription doesn't have stream, so use NETCONF stream" }
20
- stream_e = input_e.add_element('stream')
21
- stream_e.text = 'NETCONF'
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
- rescue Error
65
- raise
66
- rescue => e
67
- logger.error { "Exception in session.notification_replay: #{e.message}" }
68
- raise Error['operation-failed'].new('protocol', 'error')
69
- end
70
- session.create_subscription stream, start_time, stop_time
71
- '<ok />'
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
- model 'create-subscription', ['stream'], 'leaf', 'type' => 'string'
75
- model 'create-subscription', ['filter'], 'leaf', 'type' => 'anyxml'
76
- model 'create-subscription', ['startTime'], 'leaf', 'type' => 'string'
77
- model 'create-subscription', ['stopTime'], 'leaf', 'type' => 'string'
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
- model 'edit-config', ['error-option'], 'leaf', 'type' => 'enumeration', 'enum' => ['stop-on-error', 'continue-on-error', 'rollback-on-error'], 'default' => 'stop-on-error'
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
- model 'get-config', ['source', 'config-source', 'startup'], 'leaf', 'type' => 'empty'
13
- model 'copy-config', ['source', 'config-source', 'startup'], 'leaf', 'type' => 'empty'
14
- model 'copy-config', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
15
- model 'lock', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
16
- model 'unlock', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
17
- model 'validate', ['source', 'config-source', 'startup'], 'leaf', 'type' => 'empty'
18
- model 'delete-config', ['target', 'config-target', 'startup'], 'leaf', 'type' => 'empty'
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
- model 'edit-config', ['edit-content', 'url'], 'leaf', 'type' => 'string', 'validation' => proc { |cap, node| cap.queries['scheme'].any?{|s| s == URI.parse(node.text).scheme} }
16
- model 'copy-config', ['target', 'config-target', 'url'], 'leaf', 'type' => 'string'
17
- model 'copy-config', ['source', 'config-source', 'url'], 'leaf', 'type' => 'string'
18
- model 'delete-config', ['target', 'config-target', 'url'], 'leaf', 'type' => 'string'
19
- model 'validate', ['source', 'config-source', 'url'], 'leaf', 'type' => 'string'
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