Statistics
| Branch: | Tag: | Revision:

root / ncclient / operations / reply.py @ b4e9d4c2

History | View | Annotate | Download (4 kB)

1 5858a82c Shikhar Bhushan
# Copyright 2009 Shikhar Bhushan
2 5858a82c Shikhar Bhushan
#
3 5858a82c Shikhar Bhushan
# Licensed under the Apache License, Version 2.0 (the "License");
4 5858a82c Shikhar Bhushan
# you may not use this file except in compliance with the License.
5 5858a82c Shikhar Bhushan
# You may obtain a copy of the License at
6 5858a82c Shikhar Bhushan
#
7 5858a82c Shikhar Bhushan
#    http://www.apache.org/licenses/LICENSE-2.0
8 5858a82c Shikhar Bhushan
#
9 5858a82c Shikhar Bhushan
# Unless required by applicable law or agreed to in writing, software
10 5858a82c Shikhar Bhushan
# distributed under the License is distributed on an "AS IS" BASIS,
11 5858a82c Shikhar Bhushan
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 5858a82c Shikhar Bhushan
# See the License for the specific language governing permissions and
13 5858a82c Shikhar Bhushan
# limitations under the License.
14 5858a82c Shikhar Bhushan
15 3e022b7b Shikhar Bhushan
from xml.etree import cElementTree as ET
16 5858a82c Shikhar Bhushan
17 3e022b7b Shikhar Bhushan
from ncclient.content import multiqualify as _
18 3e022b7b Shikhar Bhushan
from ncclient.content import unqualify as __
19 5858a82c Shikhar Bhushan
20 41e2ed46 Shikhar Bhushan
import logging
21 41e2ed46 Shikhar Bhushan
logger = logging.getLogger('ncclient.operations.reply')
22 41e2ed46 Shikhar Bhushan
23 5858a82c Shikhar Bhushan
class RPCReply:
24 5858a82c Shikhar Bhushan
    
25 3e022b7b Shikhar Bhushan
    def __init__(self, raw):
26 41e2ed46 Shikhar Bhushan
        self._raw = raw
27 3e022b7b Shikhar Bhushan
        self._parsed = False
28 3e022b7b Shikhar Bhushan
        self._errors = []
29 5858a82c Shikhar Bhushan
    
30 3e022b7b Shikhar Bhushan
    def __repr__(self):
31 5858a82c Shikhar Bhushan
        return self._raw
32 5858a82c Shikhar Bhushan
    
33 5858a82c Shikhar Bhushan
    def parse(self):
34 541247ba Shikhar Bhushan
        if self._parsed: return
35 41e2ed46 Shikhar Bhushan
        root = ET.fromstring(self._raw) # <rpc-reply> element
36 3e022b7b Shikhar Bhushan
        
37 40a92771 Shikhar Bhushan
        if __(root.tag) != 'rpc-reply':
38 40a92771 Shikhar Bhushan
            raise ValueError('Root element is not RPC reply')
39 1fca349b Shikhar Bhushan
        
40 3e022b7b Shikhar Bhushan
        # per rfc 4741 an <ok/> tag is sent when there are no errors or warnings
41 3e022b7b Shikhar Bhushan
        oktags = _('ok')
42 3e022b7b Shikhar Bhushan
        for oktag in oktags:
43 3e022b7b Shikhar Bhushan
            if root.find(oktag) is not None:
44 541247ba Shikhar Bhushan
                logger.debug('parsed [%s]' % oktag)
45 41e2ed46 Shikhar Bhushan
                self._parsed = True
46 3e022b7b Shikhar Bhushan
                return
47 3e022b7b Shikhar Bhushan
        
48 3e022b7b Shikhar Bhushan
        # create RPCError objects from <rpc-error> elements
49 3e022b7b Shikhar Bhushan
        errtags = _('rpc-error')
50 3e022b7b Shikhar Bhushan
        for errtag in errtags:
51 3e022b7b Shikhar Bhushan
            for err in root.getiterator(errtag): # a particular <rpc-error>
52 541247ba Shikhar Bhushan
                logger.debug('parsed [%s]' % errtag)
53 3e022b7b Shikhar Bhushan
                d = {}
54 3e022b7b Shikhar Bhushan
                for err_detail in err.getchildren(): # <error-type> etc..
55 40a92771 Shikhar Bhushan
                    tag = __(err_detail.tag)
56 b4e9d4c2 Shikhar Bhushan
                    d[tag] = (err_detail.text.strip() if tag != 'error-info'
57 40a92771 Shikhar Bhushan
                              else ET.tostring(err_detail, 'utf-8'))
58 3e022b7b Shikhar Bhushan
                self._errors.append(RPCError(d))
59 3e022b7b Shikhar Bhushan
            if self._errors:
60 3e022b7b Shikhar Bhushan
                break
61 b4e9d4c2 Shikhar Bhushan
        
62 41e2ed46 Shikhar Bhushan
        self._parsed = True
63 5858a82c Shikhar Bhushan
    
64 5858a82c Shikhar Bhushan
    @property
65 5858a82c Shikhar Bhushan
    def raw(self):
66 5858a82c Shikhar Bhushan
        return self._raw
67 5858a82c Shikhar Bhushan
    
68 5858a82c Shikhar Bhushan
    @property
69 5858a82c Shikhar Bhushan
    def ok(self):
70 41e2ed46 Shikhar Bhushan
        if not self._parsed: self.parse()
71 b4e9d4c2 Shikhar Bhushan
        return not self._errors # empty list => false
72 5858a82c Shikhar Bhushan
    
73 5858a82c Shikhar Bhushan
    @property
74 5858a82c Shikhar Bhushan
    def errors(self):
75 3e022b7b Shikhar Bhushan
        'List of RPCError objects. Will be empty if no <rpc-error> elements in reply.'
76 41e2ed46 Shikhar Bhushan
        if not self._parsed: self.parse()
77 3e022b7b Shikhar Bhushan
        return self._errors
78 5858a82c Shikhar Bhushan
79 5858a82c Shikhar Bhushan
80 5858a82c Shikhar Bhushan
class RPCError(Exception): # raise it if you like
81 5858a82c Shikhar Bhushan
    
82 3e022b7b Shikhar Bhushan
    def __init__(self, err_dict):
83 5858a82c Shikhar Bhushan
        self._dict = err_dict
84 3e022b7b Shikhar Bhushan
        if self.message is not None:
85 3e022b7b Shikhar Bhushan
            Exception.__init__(self, self.message)
86 3e022b7b Shikhar Bhushan
        else:
87 3e022b7b Shikhar Bhushan
            Exception.__init__(self)
88 5858a82c Shikhar Bhushan
    
89 5858a82c Shikhar Bhushan
    @property
90 5858a82c Shikhar Bhushan
    def raw(self):
91 3e022b7b Shikhar Bhushan
        return self._element.tostring()
92 5858a82c Shikhar Bhushan
    
93 5858a82c Shikhar Bhushan
    @property
94 5858a82c Shikhar Bhushan
    def type(self):
95 3e022b7b Shikhar Bhushan
        return self.get('error-type', None)
96 5858a82c Shikhar Bhushan
    
97 5858a82c Shikhar Bhushan
    @property
98 5858a82c Shikhar Bhushan
    def severity(self):
99 3e022b7b Shikhar Bhushan
        return self.get('error-severity', None)
100 5858a82c Shikhar Bhushan
    
101 5858a82c Shikhar Bhushan
    @property
102 5858a82c Shikhar Bhushan
    def tag(self):
103 3e022b7b Shikhar Bhushan
        return self.get('error-tag', None)
104 5858a82c Shikhar Bhushan
    
105 5858a82c Shikhar Bhushan
    @property
106 5858a82c Shikhar Bhushan
    def path(self):
107 3e022b7b Shikhar Bhushan
        return self.get('error-path', None)
108 5858a82c Shikhar Bhushan
    
109 5858a82c Shikhar Bhushan
    @property
110 5858a82c Shikhar Bhushan
    def message(self):
111 3e022b7b Shikhar Bhushan
        return self.get('error-message', None)
112 5858a82c Shikhar Bhushan
    
113 5858a82c Shikhar Bhushan
    @property
114 5858a82c Shikhar Bhushan
    def info(self):
115 3e022b7b Shikhar Bhushan
        return self.get('error-info', None)
116 5858a82c Shikhar Bhushan
117 3e022b7b Shikhar Bhushan
    ## dictionary interface
118 5858a82c Shikhar Bhushan
    
119 3e022b7b Shikhar Bhushan
    __getitem__ = lambda self, key: self._dict.__getitem__(key)
120 5858a82c Shikhar Bhushan
    
121 3e022b7b Shikhar Bhushan
    __iter__ = lambda self: self._dict.__iter__()
122 5858a82c Shikhar Bhushan
    
123 3e022b7b Shikhar Bhushan
    __contains__ = lambda self, key: self._dict.__contains__(key)
124 5858a82c Shikhar Bhushan
    
125 3e022b7b Shikhar Bhushan
    keys = lambda self: self._dict.keys()
126 3e022b7b Shikhar Bhushan
    
127 3e022b7b Shikhar Bhushan
    get = lambda self, key, default: self._dict.get(key, default)
128 3e022b7b Shikhar Bhushan
        
129 3e022b7b Shikhar Bhushan
    iteritems = lambda self: self._dict.iteritems()
130 3e022b7b Shikhar Bhushan
    
131 3e022b7b Shikhar Bhushan
    iterkeys = lambda self: self._dict.iterkeys()
132 3e022b7b Shikhar Bhushan
    
133 3e022b7b Shikhar Bhushan
    itervalues = lambda self: self._dict.itervalues()
134 3e022b7b Shikhar Bhushan
    
135 3e022b7b Shikhar Bhushan
    values = lambda self: self._dict.values()
136 3e022b7b Shikhar Bhushan
    
137 3e022b7b Shikhar Bhushan
    items = lambda self: self._dict.items()
138 5858a82c Shikhar Bhushan
    
139 541247ba Shikhar Bhushan
    __repr__ = lambda self: repr(self._dict)