blob: 802cbe979ce9f78b55c19cfcc7e7beaf883266b3 [file] [log] [blame]
Khen Nursimulua7b842a2016-12-03 23:28:42 -05001#!/usr/bin/env python
2#
3# Copyright 2016 the original author or authors.
4#
5# Adapted from https://github.com/choppsv1/netconf/error.py
6#
7# Licensed under the Apache License, Version 2.0 (the "License");
8# you may not use this file except in compliance with the License.
9# You may obtain a copy of the License at
10#
11# http://www.apache.org/licenses/LICENSE-2.0
12#
13# Unless required by applicable law or agreed to in writing, software
14# distributed under the License is distributed on an "AS IS" BASIS,
15# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16# See the License for the specific language governing permissions and
17# limitations under the License.
18#
19from netconf.constants import Constants as C
20from lxml import etree
21
22class Error(Exception):
23
24 ### Tag ###
25 IN_USE = "in-use"
26 INVALID_VALUE = "invalid-value"
27 TOO_BIG = "too-big"
28 MISSING_ATTRIBUTE = "missing-attribute"
29 BAD_ATTRIBUTE = "bad-attribute"
30 UNKNOWN_ATTRIBUTE = "unknown-attribute"
31 MISSING_ELEMENT = "missing-element"
32 BAD_ELEMENT = "bad-element"
33 UNKNOWN_ELEMENT = "unknown-element"
34 UNKNOWN_NAMESPACE = "unknown-namespace"
35 ACCESS_DENIED = "access-denied"
36 LOCK_DENIED = "lock-denied"
37 RESOURCE_DENIED = "resource-denied"
38 ROLLBACK_FAILED = "rollback-failed"
39 DATA_EXISTS = "data-exists"
40 DATA_MISSING = "data-missing"
41 OPERATION_NOT_SUPPORTED = "operation-not-supported"
42 OPERATION_FAILED = "operation-failed"
43 MALFORMED_MESSAGE = "malformed-message"
44
45 ### Error-type ###
46 TRANSPORT = 0
47 RPC = 1
48 PROTOCOL = 2
49 APPLICATION = 3
50 ERROR_TYPE_ENUM = {
51 TRANSPORT: "transport",
52 RPC: "rpc",
53 PROTOCOL: "protocol",
54 APPLICATION: "application"
55 }
56
57 ### Severity ###
58 ERROR = "error"
59 WARNING = "warning"
60
61 ### Error-info ###
62 BAD_ATTRIBUTE_INFO = "bad-attribute"
63 BAD_ELEMENT_INFO = "bad-element"
64 SESSION_ID_INFO = "session-id"
65 OK_ELEMENT_INFO = "ok-element"
66 ERR_ELEMENT_INFO = "err-element"
67 NOOP_ELEMENT_INFO = "noop-element"
68
69 ### XML Error tags ###
70 XML_ERROR_TYPE = "error-type"
71 XML_ERROR_TAG = "error-tag"
72 XML_ERROR_SEV = "error-severity"
73
74
75 # def __init__(self, replynode=None, error_type=None, error_tag=None,
76 # error_severity=None, error_tag_app=None, error_path=None,
77 # error_message=None):
78 #
79 # self.replynode = replynode
80 # self.error_type = error_type
81 # self.error_tag = error_tag
82 # self.error_severity = error_severity
83 # self.error_tag_app = error_tag_app
84 # self.error_path = error_path
85 # self.error_message = error_message
86 # self.error_info = []
87
88class ChannelClosed(Error):
89 pass
90
91class FramingError(Error):
92 pass
93
94class SessionError(Error):
95 pass
96
97
98class RPCError(Error):
99 def __init__(self, origmsg, error_type, error_tag, **kwargs):
100 # Create the rpc reply
101 # Append original attributes and namespace
102 self.reply = etree.Element(C.RPC_REPLY,
103 attrib=origmsg.attrib,
104 nsmap=origmsg.nsmap)
105
106 rpcerr = etree.SubElement(self.reply, C.RPC_ERROR)
107
108 if error_type in Error.ERROR_TYPE_ENUM:
109 error_type = Error.ERROR_TYPE_ENUM[error_type]
110 else:
111 error_type = Error.ERROR_TYPE_ENUM[Error.RPC]
112
113 etree.SubElement(rpcerr, Error.XML_ERROR_TYPE).text = str(error_type)
114
115 etree.SubElement(rpcerr, Error.XML_ERROR_TAG).text = error_tag
116
117 if "severity" not in kwargs:
118 etree.SubElement(rpcerr, Error.XML_ERROR_SEV).text = "error"
119
120 # Convert all remaining arguments to xml
121 for key, value in kwargs.items():
122 key = key.replace('_', '-')
123 etree.SubElement(rpcerr, "error-{}".format(key)).text = str(value)
124
125 # super(RPCError, self).__init__(self.get_xml_reply())
126
127 def get_xml_reply(self):
128 return etree.tounicode(self.reply)
129
130
131class BadMsg(RPCError):
132 def __init__(self, origmsg):
133 RPCError.__init__(self,
134 origmsg,
135 Error.RPC,
136 Error.MALFORMED_MESSAGE)
137
138
139class InvalidValue(Error):
140 def __init__(self, origmsg, **kwargs):
141 RPCError.__init__(self,
142 origmsg,
143 Error.RPC,
144 Error.INVALID_VALUE,
145 **kwargs)
146
147
148class MissingElement(RPCError):
149 def __init__(self, origmsg, tag, **kwargs):
150 RPCError.__init__(self,
151 origmsg,
152 Error.RPC,
153 Error.MISSING_ELEMENT,
154 info=tag,
155 **kwargs)
156
157
158class BadElement(RPCError):
159 def __init__(self, origmsg, element, **kwargs):
160 RPCError.__init__(self,
161 origmsg,
162 Error.RPC,
163 Error.BAD_ELEMENT,
164 info=element.tag,
165 **kwargs)
166
167
168class UnknownElement(RPCError):
169 def __init__(self, origmsg, element, **kwargs):
170 RPCError.__init__(self,
171 origmsg,
172 Error.RPC,
173 Error.UNKNOWN_ELEMENT,
174 info=element.tag,
175 **kwargs)
176
177
178class NotImpl(RPCError):
179 def __init__(self, origmsg, **kwargs):
180 RPCError.__init__(self,
181 origmsg,
182 Error.PROTOCOL,
183 Error.OPERATION_NOT_SUPPORTED,
184 **kwargs)
185
186
187class ServerException(RPCError):
188 def __init__(self, origmsg, exception, **kwargs):
189 RPCError.__init__(self,
190 origmsg,
191 Error.PROTOCOL,
192 Error.OPERATION_FAILED,
193 info=str(exception),
194 **kwargs)
195