blob: e15686c1d5f9315920d8b803df822f31589c733e [file] [log] [blame]
# Licensed to the Apache Software Foundation (ASF) under one or more
# contributor license agreements. See the NOTICE file distributed with
# this work for additional information regarding copyright ownership.
# The ASF licenses this file to You under the Apache License, Version 2.0
# (the "License"); you may not use this file except in compliance with
# the License.You may obtain a copy of the License at
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
from libcloud.common.base import XmlResponse
from libcloud.common.base import ConnectionKey
__all__ = ["ZonomiException", "ZonomiResponse", "ZonomiConnection"]
# Endpoint for Zonomi API.
API_HOST = "zonomi.com"
SPECIAL_ERRORS = [
"Not found.",
"ERROR: This zone is already in your zone list.",
"Record not deleted.",
]
class ZonomiException(Exception):
def __init__(self, code, message):
self.code = code
self.message = message
self.args = (code, message)
def __str__(self):
return "%s %s" % (self.code, self.message)
def __repr__(self):
return "ZonomiException %s %s" % (self.code, self.message)
class ZonomiResponse(XmlResponse):
errors = None
objects = None
def __init__(self, response, connection):
self.errors = []
super(ZonomiResponse, self).__init__(response=response, connection=connection)
self.objects, self.errors = self.parse_body_and_errors()
if self.errors:
raise self._make_excp(self.errors[0])
def parse_body_and_errors(self):
error_dict = {}
actions = None
result_counts = None
action_childrens = None
data = []
errors = []
xml_body = super(ZonomiResponse, self).parse_body()
# pylint: disable=no-member
# Error handling
if xml_body.text is not None and xml_body.tag == "error":
error_dict["ERRORCODE"] = self.status
if xml_body.text.startswith("ERROR: No zone found for"):
error_dict["ERRORCODE"] = "404"
error_dict["ERRORMESSAGE"] = "Not found."
else:
error_dict["ERRORMESSAGE"] = xml_body.text
errors.append(error_dict)
# Data handling
childrens = list(xml_body)
if len(childrens) == 3:
result_counts = childrens[1]
actions = childrens[2]
if actions is not None:
actions_childrens = list(actions)
action = actions_childrens[0]
action_childrens = list(action)
if action_childrens is not None:
for child in action_childrens:
if child.tag == "zone" or child.tag == "record":
data.append(child.attrib)
if result_counts is not None and result_counts.attrib.get("deleted") == "1":
data.append("DELETED")
if (
result_counts is not None
and result_counts.attrib.get("deleted") == "0"
and action.get("action") == "DELETE"
):
error_dict["ERRORCODE"] = self.status
error_dict["ERRORMESSAGE"] = "Record not deleted."
errors.append(error_dict)
return (data, errors)
def success(self):
return len(self.errors) == 0
def _make_excp(self, error):
"""
:param error: contains error code and error message
:type error: dict
"""
return ZonomiException(error["ERRORCODE"], error["ERRORMESSAGE"])
class ZonomiConnection(ConnectionKey):
host = API_HOST
responseCls = ZonomiResponse
def add_default_params(self, params):
"""
Adds default parameters to perform a request,
such as api_key.
"""
params["api_key"] = self.key
return params
def add_default_headers(self, headers):
"""
Adds default headers needed to perform a successful
request such as Content-Type, User-Agent.
"""
headers["Content-Type"] = "text/xml;charset=UTF-8"
return headers