You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@libcloud.apache.org by to...@apache.org on 2021/12/08 13:00:59 UTC
[libcloud] 03/06: Update AWS error response XML parsing code so we also handle situation where response doesn't have a namespace.
This is an automated email from the ASF dual-hosted git repository.
tomaz pushed a commit to branch trunk
in repository https://gitbox.apache.org/repos/asf/libcloud.git
commit 7516dd4cbaa76c8ea93e63bc0c006a12b4fa5ff1
Author: Tomaz Muraus <to...@tomaz.me>
AuthorDate: Wed Dec 8 13:45:36 2021 +0100
Update AWS error response XML parsing code so we also handle situation
where response doesn't have a namespace.
It looks like that in some cases AWS returns error response without a
namespace which previous version of the code didn't handle correctly.
---
libcloud/common/aws.py | 14 +++++++++++---
libcloud/utils/xml.py | 44 +++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 54 insertions(+), 4 deletions(-)
diff --git a/libcloud/common/aws.py b/libcloud/common/aws.py
index 8c415e9..09c0178 100644
--- a/libcloud/common/aws.py
+++ b/libcloud/common/aws.py
@@ -37,6 +37,8 @@ from libcloud.common.base import JsonResponse
from libcloud.common.types import InvalidCredsError, MalformedResponseError
from libcloud.utils.py3 import b, httplib, urlquote
from libcloud.utils.xml import findtext, findall
+from libcloud.utils.xml import findall_ignore_namespace
+from libcloud.utils.xml import findtext_ignore_namespace
__all__ = [
"AWSBaseResponse",
@@ -79,8 +81,12 @@ class AWSBaseResponse(XmlResponse):
:return: ``tuple`` with two elements: (code, message)
:rtype: ``tuple``
"""
- code = findtext(element=element, xpath="Code", namespace=self.namespace)
- message = findtext(element=element, xpath="Message", namespace=self.namespace)
+ code = findtext_ignore_namespace(
+ element=element, xpath="Code", namespace=self.namespace
+ )
+ message = findtext_ignore_namespace(
+ element=element, xpath="Message", namespace=self.namespace
+ )
return code, message
@@ -120,7 +126,9 @@ class AWSGenericResponse(AWSBaseResponse):
)
if self.xpath:
- errs = findall(element=body, xpath=self.xpath, namespace=self.namespace)
+ errs = findall_ignore_namespace(
+ element=body, xpath=self.xpath, namespace=self.namespace
+ )
else:
errs = [body]
diff --git a/libcloud/utils/xml.py b/libcloud/utils/xml.py
index c819d7e..3337565 100644
--- a/libcloud/utils/xml.py
+++ b/libcloud/utils/xml.py
@@ -13,7 +13,14 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-__all__ = ["fixxpath", "findtext", "findattr", "findall"]
+__all__ = [
+ "fixxpath",
+ "findtext",
+ "findattr",
+ "findall",
+ "findall_ignore_namespace",
+ "findtext_ignore_namespace",
+]
def fixxpath(xpath, namespace=None):
@@ -36,9 +43,44 @@ def findtext(element, xpath, namespace=None, no_text_value=""):
return value
+def findtext_ignore_namespace(element, xpath, namespace=None, no_text_value=""):
+ """
+ Special version of findtext() which first tries to find the provided value using the provided
+ namespace and in case no results are found we fallback to the xpath lookup without namespace.
+
+ This is needed because some providers return some responses with namespace and some without.
+ """
+
+ result = findtext(
+ element=element, xpath=xpath, namespace=namespace, no_text_value=no_text_value
+ )
+
+ if not result and namespace:
+ result = findtext(
+ element=element, xpath=xpath, namespace=None, no_text_value=no_text_value
+ )
+
+ return result
+
+
def findattr(element, xpath, namespace=None):
return element.findtext(fixxpath(xpath=xpath, namespace=namespace))
def findall(element, xpath, namespace=None):
return element.findall(fixxpath(xpath=xpath, namespace=namespace))
+
+
+def findall_ignore_namespace(element, xpath, namespace=None):
+ """
+ Special version of findall() which first tries to find the provided value using the provided
+ namespace and in case no results are found we fallback to the xpath lookup without namespace.
+
+ This is needed because some providers return some responses with namespace and some without.
+ """
+ result = findall(element=element, xpath=xpath, namespace=namespace)
+
+ if not result and namespace:
+ result = findall(element=element, xpath=xpath, namespace=None)
+
+ return result