Revision ebf2bbc6

b/ncclient/__init__.py
26 26

  
27 27
__version__ = "0.05"
28 28

  
29
class NCClientError(Exception): pass
30

  
b/ncclient/content.py
16 16

  
17 17
from xml.etree import cElementTree as ET
18 18

  
19
from ncclient import NCClientError
20

  
21
class ContentError(NCClientError): pass
19 22

  
20 23
### Namespace-related ###
21 24

  
......
124 127

  
125 128
iselement = ET.iselement
126 129

  
127
def isdom(x): return True # TODO
130
# def isdom(x): return True # TODO
128 131

  
129
def root_ensured(rep, tag):
132
def ensured(rep, req_tag, req_attrs=None):
130 133
    if isinstance(rep, basestring):
131 134
        rep = ET.XML(rep)
132
    err = False
133
    if ((iselement(rep) and (rep.tag not in (tag, qualify(tag))) or (isdom(x)))): 
134
        raise ArgumentError("Expected root element [%s] not found" % tag)
135
    else:
136
        return rep
135
    if iselement(rep) and (rep.tag not in (req_tag, qualify(req_tag): 
136
        raise ContentError("Required root element [%s] not found" % req_tag)
137
    if req_attrs is not None:
138
        pass # TODO
139
    return rep
b/ncclient/operations/__init__.py
16 16

  
17 17
from ncclient import NCClientError
18 18

  
19
class OperationError(NCClientError):
20
    pass
21

  
22
class MissingCapabilityError(OperationError):
23
    pass
24 19

  
20
from rpc import RPC, RPCError
21
from errors import MissingCapabilityError
25 22
from retrieve import Get, GetConfig
26 23
from edit import EditConfig, CopyConfig, DeleteConfig, Validate, Commit, DiscardChanges
27 24
from session import CloseSession, KillSession
......
30 27

  
31 28

  
32 29
__all__ = [
33
    'OperationError',
34
    'MissingCapabilityError',
30
    'RPC',
31
    'RPCError',
35 32
    'Get',
36 33
    'GetConfig',
37 34
    'EditConfig',
b/ncclient/operations/edit.py
12 12
# See the License for the specific language governing permissions and
13 13
# limitations under the License.
14 14

  
15
from ncclient.content import iselement
15
from ncclient import content
16 16

  
17 17
from rpc import RPC
18 18

  
19 19
import util
20 20

  
21

  
22 21
"Operations related to configuration editing"
23 22

  
24

  
25 23
class EditConfig(RPC):
26 24
    
27 25
    # tested: no
......
38 36
            'tag': 'target',
39 37
            'subtree': util.store_or_url(target, target_url, self._assert)
40 38
            })
41
        subtree.append(config)
39
        subtree.append(content.root_ensured(config, 'config'))
42 40
        if default_operation is not None:
43 41
            subtree.append({
44 42
                'tag': 'default-operation',
......
115 113
                'subtree': util.store_or_url(source, source_url, self._assert)
116 114
            })
117 115
        else:
118
            spec['subtree'].append(config)
116
            spec['subtree'].append(content.root_ensured(config, 'config'))
119 117
        return self._request(spec)
120 118

  
121 119

  
......
169 167
    DEPENDS = [':candidate']
170 168
    
171 169
    SPEC = {'tag': 'discard-changes'}
170

  
b/ncclient/operations/errors.py
1
from ncclient import NCClientError
2

  
3
class OperationError(NCClientError):
4
    pass
5

  
6
class MissingCapabilityError(NCClientError):
7
    pass
8

  
b/ncclient/operations/lock.py
14 14

  
15 15
'Locking-related NETCONF operations'
16 16

  
17
from ncclient.rpc import RPC
17
from rpc import RPC
18 18

  
19 19
class Lock(RPC):
20 20
    
21 21
    # tested: no
22
    # combed: yes
22 23
    
23 24
    SPEC = {
24 25
        'tag': 'lock',
......
37 38
class Unlock(RPC):
38 39
    
39 40
    # tested: no
41
    # combed: yes
40 42
    
41 43
    SPEC = {
42 44
        'tag': 'unlock',
......
55 57
class LockContext:
56 58
    
57 59
    # tested: no
60
    # combed: yes
58 61
    
59 62
    def __init__(self, session, target):
60 63
        self.session = session
b/ncclient/operations/retrieve.py
12 12
# See the License for the specific language governing permissions and
13 13
# limitations under the License.
14 14

  
15
from ncclient.rpc import RPC, RPCReply
15
from rpc import RPC, RPCReply
16 16

  
17 17
from ncclient import content
18 18

  
19 19
import util
20 20

  
21
# NOTES
22
# - consider class for helping define <filter> for Get/GetConfig??
23

  
24 21
class GetReply(RPCReply):
25 22
    
26 23
    'Adds data attribute'
......
60 57
    def request(self, filter=None):
61 58
        spec = Get.SPEC.copy()
62 59
        if filter is not None:
63
            spec['subtree'].append(content.rootchecked(filter. 'filter', 'type'))
60
            spec['subtree'].append(util.build_filter(filter)))
64 61
        return self._request(spec)
65 62

  
66 63
class GetConfig(RPC):
......
87 84
            'subtree': util.store_or_url(source, source_url)
88 85
            })
89 86
        if filter is not None:
90
            spec['subtree'].append(content.rootchecked(filter, 'filter', 'type'))
87
            spec['subtree'].append(util.build_filter(filter))
91 88
        return self._request(spec)
92 89

  
b/ncclient/operations/session.py
14 14

  
15 15
'Session-related NETCONF operations'
16 16

  
17
from ncclient.rpc import RPC
17
from rpc import RPC
18 18

  
19 19
class CloseSession(RPC):
20 20
    # tested: no
......
22 22
    
23 23
    SPEC = { 'tag': 'close-session' }
24 24
    
25
    def _delivery_hook(self):
26
        if self.reply.ok:
27
            self.session.expect_close()
25
    def _delivery_hook(self)
28 26
        self.session.close()
29 27

  
30 28

  
31 29
class KillSession(RPC):
32 30
    # tested: no
31
    # combed: yes
33 32
    
34 33
    SPEC = {
35 34
        'tag': 'kill-session',
......
45 44
            'text': session_id
46 45
        })
47 46
        return self._request(spec)
47

  
b/ncclient/operations/util.py
16 16

  
17 17
from ncclient import OperationError
18 18
from ncclient.content import qualify as _
19
from ncclient.content import ensure_root
19
from ncclient.content import root_ensured
20 20

  
21
from ncclient.errors import MissingCapabilityError, ArgumentError
21
from errors import MissingCapabilityError
22 22

  
23 23
def one_of(*args):
24 24
    'Verifies that only one of the arguments is not None'
......
31 31
                return
32 32
    raise OperationError('Insufficient parameters')
33 33

  
34
def store_or_url(store, url, capcheck_func=None):
34
def store_or_url(store, url, capcheck=None):
35 35
    one_of(store, url)
36 36
    node = {}
37 37
    if store is not None:
38 38
        node['tag'] = store
39 39
    else:
40
        if capcheck_func is not None:
41
            capcheck_func(':url') # hmm.. schema check? deem overkill for now
40
        if capcheck is not None:
41
            capcheck(':url') # hmm.. schema check? deem overkill for now
42 42
        node['tag'] = 'url'
43 43
        node['text'] = url
44 44
    return node
45 45

  
46
def build_filter(spec, capcheck=None):
47
    type = None
48
    if isinstance(spec, tuple):
49
        type, criteria = tuple
50
        rep = {
51
            'tag': 'filter',
52
            'attributes': {'type': type},
53
            'subtree': criteria
54
       }
55
    else:
56
        rep = root_ensure(spec, 'filter', 'type')
57
        try:
58
            type = rep['type']
59
        except KeyError:
60
            type = ele[qualify('type'))
61
    if type == 'xpath' and capcheck_func is not None:
62
        capcheck_func(':xpath')
63
    return rep
64

  
b/ncclient/transport/errors.py
14 14

  
15 15
"TODO: docstrings"
16 16

  
17
from ncclient import NCClientError
18

  
19
class TransportError(NCClientError):
20
    pass
17
from ncclient.errors import TransportError
21 18

  
22 19
class AuthenticationError(TransportError):
23 20
    pass

Also available in: Unified diff