0
# NETCONF Operations
1
2
Complete implementation of NETCONF standard operations (RFC 6241) for configuration management, datastore operations, and session control. Operations are accessible through Manager instances and support both synchronous and asynchronous execution modes.
3
4
## Capabilities
5
6
### Configuration Retrieval
7
8
Operations for retrieving configuration and operational data from NETCONF datastores.
9
10
```python { .api }
11
def get_config(source, filter=None, **kwargs):
12
"""
13
Retrieve configuration from specified datastore.
14
15
Parameters:
16
- source: str, datastore name ('running', 'candidate', 'startup')
17
- filter: tuple or str, filter specification (subtree or xpath)
18
19
Returns:
20
RPCReply: Configuration data response
21
"""
22
23
def get(filter=None, **kwargs):
24
"""
25
Retrieve configuration and state data.
26
27
Parameters:
28
- filter: tuple or str, filter specification (subtree or xpath)
29
30
Returns:
31
RPCReply: Combined configuration and operational data
32
"""
33
34
def get_schema(identifier, version=None, format=None):
35
"""
36
Retrieve YANG schema from server.
37
38
Parameters:
39
- identifier: str, schema identifier
40
- version: str, schema version (optional)
41
- format: str, schema format (yang, yin, rng, rnc)
42
43
Returns:
44
RPCReply: Schema content
45
"""
46
```
47
48
### Configuration Editing
49
50
Operations for modifying device configuration through NETCONF datastores.
51
52
```python { .api }
53
def edit_config(target, config, default_operation=None,
54
test_option=None, error_option=None):
55
"""
56
Edit configuration in target datastore.
57
58
Parameters:
59
- target: str, target datastore ('running', 'candidate', 'startup')
60
- config: str or Element, configuration data
61
- default_operation: str, default operation ('merge', 'replace', 'none')
62
- test_option: str, test option ('test-then-set', 'set', 'test-only')
63
- error_option: str, error handling ('stop-on-error', 'continue-on-error', 'rollback-on-error')
64
65
Returns:
66
RPCReply: Edit operation result
67
"""
68
69
def copy_config(source, target):
70
"""
71
Copy configuration between datastores.
72
73
Parameters:
74
- source: str, source datastore or configuration
75
- target: str, target datastore
76
77
Returns:
78
RPCReply: Copy operation result
79
"""
80
81
def delete_config(target):
82
"""
83
Delete configuration datastore.
84
85
Parameters:
86
- target: str, target datastore (not 'running')
87
88
Returns:
89
RPCReply: Delete operation result
90
"""
91
```
92
93
### Transaction Management
94
95
Operations for managing configuration transactions and validation.
96
97
```python { .api }
98
def validate(source):
99
"""
100
Validate configuration datastore.
101
102
Parameters:
103
- source: str, datastore to validate ('candidate', 'running', 'startup')
104
105
Returns:
106
RPCReply: Validation result
107
"""
108
109
def commit(confirmed=False, timeout=None, persist=None,
110
persist_id=None):
111
"""
112
Commit candidate configuration to running datastore.
113
114
Parameters:
115
- confirmed: bool, confirmed commit
116
- timeout: int, confirm timeout in seconds
117
- persist: str, persist ID for confirmed commit
118
- persist_id: str, existing persist ID to confirm
119
120
Returns:
121
RPCReply: Commit operation result
122
"""
123
124
def discard_changes():
125
"""
126
Discard changes in candidate datastore.
127
128
Returns:
129
RPCReply: Discard operation result
130
"""
131
132
def cancel_commit(persist_id=None):
133
"""
134
Cancel confirmed commit.
135
136
Parameters:
137
- persist_id: str, persist ID to cancel (optional)
138
139
Returns:
140
RPCReply: Cancel operation result
141
"""
142
```
143
144
### Datastore Locking
145
146
Operations for exclusive access control to configuration datastores.
147
148
```python { .api }
149
def lock(target):
150
"""
151
Lock datastore for exclusive access.
152
153
Parameters:
154
- target: str, datastore to lock ('running', 'candidate', 'startup')
155
156
Returns:
157
RPCReply: Lock operation result
158
"""
159
160
def unlock(target):
161
"""
162
Unlock previously locked datastore.
163
164
Parameters:
165
- target: str, datastore to unlock
166
167
Returns:
168
RPCReply: Unlock operation result
169
"""
170
```
171
172
### Session Management
173
174
Operations for NETCONF session lifecycle management.
175
176
```python { .api }
177
def close_session():
178
"""
179
Close current NETCONF session gracefully.
180
181
Returns:
182
RPCReply: Session close result
183
"""
184
185
def kill_session(session_id):
186
"""
187
Forcefully terminate another NETCONF session.
188
189
Parameters:
190
- session_id: str, session ID to terminate
191
192
Returns:
193
RPCReply: Kill session result
194
"""
195
```
196
197
### Notification Subscription
198
199
Operations for subscribing to NETCONF event notifications.
200
201
```python { .api }
202
def create_subscription(filter=None, start_time=None,
203
stop_time=None):
204
"""
205
Create notification subscription.
206
207
Parameters:
208
- filter: str or tuple, notification filter
209
- start_time: str, subscription start time (ISO 8601)
210
- stop_time: str, subscription stop time (ISO 8601)
211
212
Returns:
213
RPCReply: Subscription creation result
214
"""
215
```
216
217
### Generic RPC Operations
218
219
Direct RPC execution for custom or vendor-specific operations.
220
221
```python { .api }
222
def dispatch(rpc_command, source=None, filter=None):
223
"""
224
Execute arbitrary RPC command.
225
226
Parameters:
227
- rpc_command: str or Element, RPC command
228
- source: str, source datastore (for data operations)
229
- filter: str or tuple, data filter
230
231
Returns:
232
RPCReply: RPC execution result
233
"""
234
235
def rpc(op):
236
"""
237
Execute generic RPC operation.
238
239
Parameters:
240
- op: Element, RPC operation element
241
242
Returns:
243
RPCReply: RPC response
244
"""
245
```
246
247
### Device Control Operations
248
249
Additional operations for device management and control.
250
251
```python { .api }
252
def poweroff_machine():
253
"""
254
Power off the device.
255
256
Returns:
257
RPCReply: Poweroff operation result
258
"""
259
260
def reboot_machine():
261
"""
262
Reboot the device.
263
264
Returns:
265
RPCReply: Reboot operation result
266
"""
267
```
268
269
## Core Operation Classes
270
271
```python { .api }
272
class RPC:
273
"""Base class for NETCONF RPC operations."""
274
275
def request(self, *args, **kwargs):
276
"""Execute RPC request with parameters."""
277
278
class RPCReply:
279
"""Represents NETCONF RPC reply with result data."""
280
281
@property
282
def ok(self):
283
"""bool: Whether operation succeeded."""
284
285
@property
286
def data(self):
287
"""Element: Reply data content."""
288
289
@property
290
def data_xml(self):
291
"""str: Reply data as XML string."""
292
293
@property
294
def errors(self):
295
"""list: List of RPC errors."""
296
297
class RPCError(Exception):
298
"""Exception for NETCONF RPC errors."""
299
300
@property
301
def type(self):
302
"""str: Error type."""
303
304
@property
305
def tag(self):
306
"""str: Error tag."""
307
308
@property
309
def severity(self):
310
"""str: Error severity."""
311
312
@property
313
def message(self):
314
"""str: Error message."""
315
316
class RaiseMode:
317
"""Constants for RPC error raising behavior."""
318
NONE = 0 # Never raise exceptions
319
ERRORS = 1 # Raise for errors only
320
ALL = 2 # Raise for errors and warnings (default)
321
```
322
323
## Lock Context Manager
324
325
```python { .api }
326
class LockContext:
327
"""Context manager for datastore locking."""
328
329
def __init__(self, session, device_handler, target):
330
"""
331
Initialize lock context.
332
333
Parameters:
334
- session: transport session
335
- device_handler: device handler
336
- target: str, datastore to lock
337
"""
338
339
def __enter__(self):
340
"""Acquire datastore lock."""
341
342
def __exit__(self, *args):
343
"""Release datastore lock."""
344
```
345
346
## Usage Examples
347
348
### Basic Configuration Operations
349
350
```python
351
from ncclient import manager
352
353
with manager.connect_ssh(host='device.example.com',
354
username='admin', password='admin') as m:
355
356
# Get running configuration
357
config = m.get_config(source='running')
358
print(config.data_xml)
359
360
# Edit configuration
361
new_config = '''
362
<config>
363
<interface xmlns="urn:example:interface">
364
<name>eth0</name>
365
<description>Updated interface</description>
366
</interface>
367
</config>
368
'''
369
370
result = m.edit_config(target='candidate', config=new_config)
371
if result.ok:
372
# Validate and commit
373
m.validate(source='candidate')
374
m.commit()
375
print("Configuration updated successfully")
376
```
377
378
### Using Datastore Locking
379
380
```python
381
from ncclient import manager
382
383
with manager.connect_ssh(host='device.example.com',
384
username='admin', password='admin') as m:
385
386
# Use lock context manager
387
with m.locked('candidate'):
388
# Exclusive access to candidate datastore
389
config = '''
390
<config>
391
<system xmlns="urn:example:system">
392
<hostname>new-hostname</hostname>
393
</system>
394
</config>
395
'''
396
397
m.edit_config(target='candidate', config=config)
398
m.validate(source='candidate')
399
m.commit()
400
# Lock automatically released
401
```
402
403
### Filtering Data
404
405
```python
406
from ncclient import manager
407
408
with manager.connect_ssh(host='device.example.com',
409
username='admin', password='admin') as m:
410
411
# Subtree filter
412
interface_filter = '''
413
<interfaces xmlns="urn:ietf:params:xml:ns:yang:ietf-interfaces">
414
<interface>
415
<name/>
416
<type/>
417
<admin-status/>
418
</interface>
419
</interfaces>
420
'''
421
422
# Get filtered configuration
423
result = m.get_config(source='running',
424
filter=('subtree', interface_filter))
425
426
# XPath filter
427
xpath_filter = "/interfaces/interface[name='eth0']"
428
result = m.get_config(source='running',
429
filter=('xpath', xpath_filter))
430
```
431
432
### Error Handling
433
434
```python
435
from ncclient import manager
436
from ncclient.operations import RPCError, RaiseMode
437
438
with manager.connect_ssh(host='device.example.com',
439
username='admin', password='admin') as m:
440
441
# Configure error handling
442
m.raise_mode = RaiseMode.ERRORS
443
444
try:
445
result = m.edit_config(target='running', config=invalid_config)
446
except RPCError as e:
447
print(f"RPC Error: {e.message}")
448
print(f"Error type: {e.type}")
449
print(f"Error tag: {e.tag}")
450
```